Browse Source

Merge branch 'master' into develop

Torkel Ödegaard 8 years ago
parent
commit
9605ab4475
94 changed files with 1790 additions and 13092 deletions
  1. 17 4
      CHANGELOG.md
  2. 11 0
      codecov.yml
  3. 0 7
      conf/defaults.ini
  4. 0 6
      conf/sample.ini
  5. 1 2
      docs/sources/alerting/rules.md
  6. 0 2
      docs/sources/features/datasources/cloudwatch.md
  7. 2 1
      docs/sources/features/datasources/index.md
  8. 1 3
      docs/sources/features/datasources/influxdb.md
  9. 28 3
      docs/sources/features/datasources/mysql.md
  10. 28 1
      docs/sources/features/datasources/postgres.md
  11. 0 5
      docs/sources/http_api/admin.md
  12. 14 2
      docs/sources/http_api/org.md
  13. 7 5
      docs/sources/index.md
  14. 3 3
      docs/sources/installation/debian.md
  15. 66 2
      docs/sources/installation/docker.md
  16. 5 5
      docs/sources/installation/rpm.md
  17. 1 1
      docs/sources/installation/windows.md
  18. 1 1
      docs/sources/plugins/developing/development.md
  19. 2 2
      docs/sources/reference/annotations.md
  20. 1 1
      pkg/api/api.go
  21. 20 6
      pkg/api/datasources.go
  22. 59 0
      pkg/api/dtos/datasource.go
  23. 0 50
      pkg/api/dtos/models.go
  24. 0 2
      pkg/cmd/grafana-server/server.go
  25. 3 1
      pkg/components/renderer/renderer.go
  26. 8 6
      pkg/models/datasource.go
  27. 1 1
      pkg/services/alerting/eval_handler.go
  28. 0 150
      pkg/services/eventpublisher/eventpublisher.go
  29. 21 3
      pkg/services/sqlstore/datasource.go
  30. 83 7
      pkg/services/sqlstore/datasource_test.go
  31. 6 0
      pkg/services/sqlstore/migrations/datasource_mig.go
  32. 0 2
      public/app/core/components/layout_selector/layout_selector.ts
  33. 23 25
      public/app/core/controllers/inspect_ctrl.ts
  34. 4 3
      public/app/core/directives/diff-view.ts
  35. 15 11
      public/app/core/routes/dashboard_loaders.ts
  36. 0 41
      public/app/core/services/analytics.js
  37. 36 0
      public/app/core/services/analytics.ts
  38. 0 33
      public/app/core/services/timer.js
  39. 31 0
      public/app/core/services/timer.ts
  40. 44 0
      public/app/core/specs/store.jest.ts
  41. 0 26
      public/app/core/store.js
  42. 29 0
      public/app/core/store.ts
  43. 0 32
      public/app/core/utils/outline.js
  44. 34 0
      public/app/core/utils/outline.ts
  45. 0 1
      public/app/features/dashboard/dashboard_model.ts
  46. 0 2
      public/app/features/dashboard/impression_store.ts
  47. 0 1
      public/app/features/dashboard/unsavedChangesSrv.js
  48. 0 1
      public/app/features/dashboard/viewStateSrv.js
  49. 3 1
      public/app/features/plugins/ds_edit_ctrl.ts
  50. 7 2
      public/app/features/plugins/plugin_loader.ts
  51. 4 1
      public/app/features/templating/interval_variable.ts
  52. 1 1
      public/app/features/templating/partials/editor.html
  53. 2 2
      public/app/features/templating/specs/template_srv.jest.ts
  54. 74 2
      public/app/features/templating/specs/variable_srv_specs.ts
  55. 1 1
      public/app/plugins/datasource/mysql/datasource.ts
  56. 2 2
      public/app/plugins/datasource/mysql/specs/datasource_specs.ts
  57. 2 2
      public/app/plugins/datasource/postgres/datasource.ts
  58. 20 0
      public/app/plugins/datasource/postgres/specs/datasource_specs.ts
  59. 1052 0
      public/app/plugins/datasource/prometheus/dashboards/grafana_stats.json
  60. 4 7
      public/app/plugins/datasource/prometheus/datasource.ts
  61. 2 1
      public/app/plugins/datasource/prometheus/plugin.json
  62. 1 1
      public/app/plugins/panel/singlestat/module.ts
  63. 5 2
      public/vendor/flot/jquery.flot.js
  64. 5 0
      public/vendor/flot/jquery.flot.selection.js
  65. 0 3
      vendor/github.com/streadway/amqp/.gitignore
  66. 0 13
      vendor/github.com/streadway/amqp/.travis.yml
  67. 0 23
      vendor/github.com/streadway/amqp/LICENSE
  68. 0 76
      vendor/github.com/streadway/amqp/README.md
  69. 0 106
      vendor/github.com/streadway/amqp/allocator.go
  70. 0 90
      vendor/github.com/streadway/amqp/allocator_test.go
  71. 0 44
      vendor/github.com/streadway/amqp/auth.go
  72. 0 159
      vendor/github.com/streadway/amqp/certs.sh
  73. 0 1589
      vendor/github.com/streadway/amqp/channel.go
  74. 0 559
      vendor/github.com/streadway/amqp/client_test.go
  75. 0 764
      vendor/github.com/streadway/amqp/connection.go
  76. 0 118
      vendor/github.com/streadway/amqp/consumers.go
  77. 0 173
      vendor/github.com/streadway/amqp/delivery.go
  78. 0 33
      vendor/github.com/streadway/amqp/delivery_test.go
  79. 0 108
      vendor/github.com/streadway/amqp/doc.go
  80. 0 395
      vendor/github.com/streadway/amqp/examples_test.go
  81. 0 2
      vendor/github.com/streadway/amqp/gen.sh
  82. 0 1772
      vendor/github.com/streadway/amqp/integration_test.go
  83. 0 444
      vendor/github.com/streadway/amqp/read.go
  84. 0 113
      vendor/github.com/streadway/amqp/reconnect_test.go
  85. 0 64
      vendor/github.com/streadway/amqp/return.go
  86. 0 71
      vendor/github.com/streadway/amqp/shared_test.go
  87. 0 537
      vendor/github.com/streadway/amqp/spec/amqp0-9-1.stripped.extended.xml
  88. 0 536
      vendor/github.com/streadway/amqp/spec/gen.go
  89. 0 3306
      vendor/github.com/streadway/amqp/spec091.go
  90. 0 218
      vendor/github.com/streadway/amqp/tls_test.go
  91. 0 382
      vendor/github.com/streadway/amqp/types.go
  92. 0 170
      vendor/github.com/streadway/amqp/uri.go
  93. 0 328
      vendor/github.com/streadway/amqp/uri_test.go
  94. 0 411
      vendor/github.com/streadway/amqp/write.go

+ 17 - 4
CHANGELOG.md

@@ -12,8 +12,21 @@
 ## New Features
 ## New Features
 * **Data Source Proxy**: Add support for whitelisting specified cookies that will be passed through to the data source when proxying data source requests [#5457](https://github.com/grafana/grafana/issues/5457), thanks [@robingustafsson](https://github.com/robingustafsson)
 * **Data Source Proxy**: Add support for whitelisting specified cookies that will be passed through to the data source when proxying data source requests [#5457](https://github.com/grafana/grafana/issues/5457), thanks [@robingustafsson](https://github.com/robingustafsson)
 
 
-## Fixes 
+
+## Tech
+* **RabbitMq**: Remove support for publishing events to RabbitMQ [#9645](https://github.com/grafana/grafana/issues/9645)
+
+## Fixes
 * **Sensu**: Send alert message to sensu output [#9551](https://github.com/grafana/grafana/issues/9551), thx [@cjchand](https://github.com/cjchand)
 * **Sensu**: Send alert message to sensu output [#9551](https://github.com/grafana/grafana/issues/9551), thx [@cjchand](https://github.com/cjchand)
+* **Singlestat**: suppress error when result contains no datapoints [#9636](https://github.com/grafana/grafana/issues/9636), thx [@utkarshcmu](https://github.com/utkarshcmu)
+* **Postgres/MySQL**: Control quoting in SQL-queries when using template variables [#9030](https://github.com/grafana/grafana/issues/9030), thanks [@svenklemm](https://github.com/svenklemm)
+
+# 4.6.0 (2017-10-26)
+
+## Fixes
+* **Alerting**: Viewer can no longer pause alert rules [#9640](https://github.com/grafana/grafana/issues/9640)
+* **Playlist**: Bug where playlist controls was missing [#9639](https://github.com/grafana/grafana/issues/9639)
+* **Firefox**: Creating region annotations now work in firefox [#9638](https://github.com/grafana/grafana/issues/9638)
 
 
 # 4.6.0-beta3 (2017-10-23)
 # 4.6.0-beta3 (2017-10-23)
 
 
@@ -56,11 +69,11 @@
 * **OAuth**: Verify TLS during OAuth callback [#9373](https://github.com/grafana/grafana/issues/9373), thx [@mattbostock](https://github.com/mattbostock)
 * **OAuth**: Verify TLS during OAuth callback [#9373](https://github.com/grafana/grafana/issues/9373), thx [@mattbostock](https://github.com/mattbostock)
 
 
 ## Minor
 ## Minor
-* **SMTP**: Make it possible to set specific EHLO for smtp client. [#9319](https://github.com/grafana/grafana/issues/9319)
-* **Dataproxy**: Allow grafan to renegotiate tls connection [#9250](https://github.com/grafana/grafana/issues/9250)
+* **SMTP**: Make it possible to set specific HELO for smtp client. [#9319](https://github.com/grafana/grafana/issues/9319)
+* **Dataproxy**: Allow grafana to renegotiate tls connection [#9250](https://github.com/grafana/grafana/issues/9250)
 * **HTTP**: set net.Dialer.DualStack to true for all http clients [#9367](https://github.com/grafana/grafana/pull/9367)
 * **HTTP**: set net.Dialer.DualStack to true for all http clients [#9367](https://github.com/grafana/grafana/pull/9367)
 * **Alerting**: Add diff and percent diff as series reducers [#9386](https://github.com/grafana/grafana/pull/9386), thx [@shanhuhai5739](https://github.com/shanhuhai5739)
 * **Alerting**: Add diff and percent diff as series reducers [#9386](https://github.com/grafana/grafana/pull/9386), thx [@shanhuhai5739](https://github.com/shanhuhai5739)
-* **Slack**: Allow images to be uploaded to slack when Token is precent [#7175](https://github.com/grafana/grafana/issues/7175), thx [@xginn8](https://github.com/xginn8)
+* **Slack**: Allow images to be uploaded to slack when Token is present [#7175](https://github.com/grafana/grafana/issues/7175), thx [@xginn8](https://github.com/xginn8)
 * **Opsgenie**: Use their latest API instead of old version [#9399](https://github.com/grafana/grafana/pull/9399), thx [@cglrkn](https://github.com/cglrkn)
 * **Opsgenie**: Use their latest API instead of old version [#9399](https://github.com/grafana/grafana/pull/9399), thx [@cglrkn](https://github.com/cglrkn)
 * **Table**: Add support for displaying the timestamp with milliseconds [#9429](https://github.com/grafana/grafana/pull/9429), thx [@s1061123](https://github.com/s1061123)
 * **Table**: Add support for displaying the timestamp with milliseconds [#9429](https://github.com/grafana/grafana/pull/9429), thx [@s1061123](https://github.com/s1061123)
 * **Hipchat**: Add metrics, message and image to hipchat notifications [#9110](https://github.com/grafana/grafana/issues/9110), thx [@eloo](https://github.com/eloo)
 * **Hipchat**: Add metrics, message and image to hipchat notifications [#9110](https://github.com/grafana/grafana/issues/9110), thx [@eloo](https://github.com/eloo)

+ 11 - 0
codecov.yml

@@ -0,0 +1,11 @@
+coverage:
+  precision: 2
+  round: down
+  range: "50...100"
+
+  status:
+    project: yes
+    patch: yes
+    changes: no
+    
+comment: false

+ 0 - 7
conf/defaults.ini

@@ -381,13 +381,6 @@ facility =
 # Syslog tag. By default, the process' argv[0] is used.
 # Syslog tag. By default, the process' argv[0] is used.
 tag =
 tag =
 
 
-
-#################################### AMQP Event Publisher ################
-[event_publisher]
-enabled = false
-rabbitmq_url = amqp://localhost/
-exchange = grafana_events
-
 #################################### Dashboard JSON files ################
 #################################### Dashboard JSON files ################
 [dashboards.json]
 [dashboards.json]
 enabled = false
 enabled = false

+ 0 - 6
conf/sample.ini

@@ -360,12 +360,6 @@
 ;tag =
 ;tag =
 
 
 
 
-#################################### AMQP Event Publisher ##########################
-[event_publisher]
-;enabled = false
-;rabbitmq_url = amqp://localhost/
-;exchange = grafana_events
-
 ;#################################### Dashboard JSON files ##########################
 ;#################################### Dashboard JSON files ##########################
 [dashboards.json]
 [dashboards.json]
 ;enabled = false
 ;enabled = false

+ 1 - 2
docs/sources/alerting/rules.md

@@ -27,8 +27,7 @@ and the conditions that need to be met for the alert to change state and trigger
 ## Execution
 ## Execution
 
 
 The alert rules are evaluated in the Grafana backend in a scheduler and query execution engine that is part
 The alert rules are evaluated in the Grafana backend in a scheduler and query execution engine that is part
-of core Grafana. Only some data sources are supported right now. They include `Graphite`, `Prometheus`,
-`InfluxDB` and `OpenTSDB`.
+of core Grafana. Only some data sources are supported right now. They include `Graphite`, `Prometheus`, `InfluxDB`, `OpenTSDB`, `MySQL`, `Postgres` and `Cloudwatch`.
 
 
 ### Clustering
 ### Clustering
 
 

+ 0 - 2
docs/sources/features/datasources/cloudwatch.md

@@ -169,5 +169,3 @@ Amazon provides 1 million CloudWatch API requests each month at no additional ch
 it costs $0.01 per 1,000 GetMetricStatistics or ListMetrics requests. For each query Grafana will
 it costs $0.01 per 1,000 GetMetricStatistics or ListMetrics requests. For each query Grafana will
 issue a GetMetricStatistics request and every time you pick a dimension in the query editor
 issue a GetMetricStatistics request and every time you pick a dimension in the query editor
 Grafana will issue a ListMetrics request.
 Grafana will issue a ListMetrics request.
-
-

+ 2 - 1
docs/sources/features/datasources/index.md

@@ -28,8 +28,9 @@ The following datasources are officially supported:
 * [InfluxDB]({{< relref "influxdb.md" >}})
 * [InfluxDB]({{< relref "influxdb.md" >}})
 * [OpenTSDB]({{< relref "opentsdb.md" >}})
 * [OpenTSDB]({{< relref "opentsdb.md" >}})
 * [Prometheus]({{< relref "prometheus.md" >}})
 * [Prometheus]({{< relref "prometheus.md" >}})
+* [MySQL]({{< relref "mysql.md" >}})
+* [Postgres]({{< relref "postgres.md" >}})
 
 
 ## Data source plugins
 ## Data source plugins
 
 
 Since grafana 3.0 you can install data sources as plugins. Checkout [Grafana.net](https://grafana.com/plugins) for more data sources.
 Since grafana 3.0 you can install data sources as plugins. Checkout [Grafana.net](https://grafana.com/plugins) for more data sources.
-

+ 1 - 3
docs/sources/features/datasources/influxdb.md

@@ -173,6 +173,4 @@ SELECT title, description from events WHERE $timeFilter order asc
 
 
 For InfluxDB you need to enter a query like in the above example. You need to have the ```where $timeFilter```
 For InfluxDB you need to enter a query like in the above example. You need to have the ```where $timeFilter```
 part. If you only select one column you will not need to enter anything in the column mapping fields. The
 part. If you only select one column you will not need to enter anything in the column mapping fields. The
-Tags field can be a comma seperated string.
-
-
+Tags field can be a comma separated string.

+ 28 - 3
docs/sources/features/datasources/mysql.md

@@ -142,7 +142,11 @@ SELECT hostname FROM my_host  WHERE region IN($region)
 
 
 ### Using Variables in Queries
 ### Using Variables in Queries
 
 
-Template variables are quoted automatically so if it is a string value do not wrap them in quotes in where clauses. If the variable is a multi-value variable then use the `IN` comparison operator rather than `=` to match against multiple values.
+From Grafana 4.3.0 to 4.6.0, template variables are always quoted automatically so if it is a string value do not wrap them in quotes in where clauses.
+
+From Grafana 4.7.0, template variable values are only quoted when the template variable is a `multi-value`.
+
+If the variable is a multi-value variable then use the `IN` comparison operator rather than `=` to match against multiple values.
 
 
 There are two syntaxes:
 There are two syntaxes:
 
 
@@ -170,7 +174,28 @@ WHERE $__timeFilter(atimestamp) and hostname in([[hostname]])
 ORDER BY atimestamp ASC
 ORDER BY atimestamp ASC
 ```
 ```
 
 
+## Annotations
+
+[Annotations]({{< relref "reference/annotations.md" >}}) allows you to overlay rich event information on top of graphs. You add annotation queries via the Dashboard menu / Annotations view.
+
+An example query:
+
+```sql
+SELECT
+  UNIX_TIMESTAMP(atimestamp) as time_sec,
+  value as text,
+  CONCAT(tag1, ',', tag2) as tags
+FROM my_table
+WHERE $__timeFilter(atimestamp)
+ORDER BY atimestamp ASC
+```
+
+Name | Description
+------------ | -------------
+time_sec | The name of the date/time field.
+text | Event description field.
+tags | Optional field name to use for event tags as a comma separated string.
+
 ## Alerting
 ## Alerting
 
 
-Time series queries should work in alerting conditions. Table formatted queries is not yet supported in alert rule
-conditions.
+Time series queries should work in alerting conditions. Table formatted queries is not yet supported in alert rule conditions.

+ 28 - 1
docs/sources/features/datasources/postgres.md

@@ -154,7 +154,11 @@ SELECT hostname FROM host  WHERE region IN($region)
 
 
 ### Using Variables in Queries
 ### Using Variables in Queries
 
 
-Template variables are quoted automatically so if it is a string value do not wrap them in quotes in where clauses. If the variable is a multi-value variable then use the `IN` comparison operator rather than `=` to match against multiple values.
+From Grafana 4.3.0 to 4.6.0, template variables are always quoted automatically so if it is a string value do not wrap them in quotes in where clauses.
+
+From Grafana 4.7.0, template variable values are only quoted when the template variable is a `multi-value`.
+
+If the variable is a multi-value variable then use the `IN` comparison operator rather than `=` to match against multiple values.
 
 
 There are two syntaxes:
 There are two syntaxes:
 
 
@@ -180,6 +184,29 @@ WHERE $__timeFilter(atimestamp) and hostname in([[hostname]])
 ORDER BY atimestamp ASC
 ORDER BY atimestamp ASC
 ```
 ```
 
 
+## Annotations
+
+[Annotations]({{< relref "reference/annotations.md" >}}) allows you to overlay rich event information on top of graphs. You add annotation queries via the Dashboard menu / Annotations view.
+
+An example query:
+
+```sql
+SELECT
+  extract(epoch from time_date_time) AS time,
+ metric1 as text,
+  concat_ws(', ', metric1::text, metric2::text) as tags
+FROM
+  public.test_data
+WHERE
+  $__timeFilter(time_date_time)
+```
+
+Name | Description
+------------ | -------------
+time | The name of the date/time field.
+text | Event description field.
+tags | Optional field name to use for event tags as a comma separated string.
+
 ## Alerting
 ## Alerting
 
 
 Time series queries should work in alerting conditions. Table formatted queries is not yet supported in alert rule
 Time series queries should work in alerting conditions. Table formatted queries is not yet supported in alert rule

+ 0 - 5
docs/sources/http_api/admin.md

@@ -102,11 +102,6 @@ Content-Type: application/json
     "templates_pattern":"emails/*.html",
     "templates_pattern":"emails/*.html",
     "welcome_email_on_sign_up":"false"
     "welcome_email_on_sign_up":"false"
   },
   },
-  "event_publisher":{
-    "enabled":"false",
-    "exchange":"grafana_events",
-      "rabbitmq_url":"amqp://localhost/"
-  },
   "log":{
   "log":{
     "buffer_len":"10000",
     "buffer_len":"10000",
     "level":"Info",
     "level":"Info",

+ 14 - 2
docs/sources/http_api/org.md

@@ -14,12 +14,12 @@ parent = "http_api"
 
 
 ## Get current Organisation
 ## Get current Organisation
 
 
-`GET /api/org`
+`GET /api/org/`
 
 
 **Example Request**:
 **Example Request**:
 
 
 ```http
 ```http
-GET /api/org HTTP/1.1
+GET /api/org/ HTTP/1.1
 Accept: application/json
 Accept: application/json
 Content-Type: application/json
 Content-Type: application/json
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
@@ -49,6 +49,8 @@ Accept: application/json
 Content-Type: application/json
 Content-Type: application/json
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 ```
 ```
+Note: The api will only work when you pass the admin name and password
+to the request http url, like http://admin:admin@localhost:3000/api/orgs/1
 
 
 **Example Response**:
 **Example Response**:
 
 
@@ -81,6 +83,8 @@ Accept: application/json
 Content-Type: application/json
 Content-Type: application/json
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 ```
 ```
+Note: The api will only work when you pass the admin name and password
+to the request http url, like http://admin:admin@localhost:3000/api/orgs/name/Main%20Org%2E
 
 
 **Example Response**:
 **Example Response**:
 
 
@@ -118,6 +122,9 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
   "name":"New Org."
   "name":"New Org."
 }
 }
 ```
 ```
+Note: The api will work in the following two ways
+1) Need to set GF_USERS_ALLOW_ORG_CREATE=true
+2) Set the config users.allow_org_create to true in ini file
 
 
 **Example Response**:
 **Example Response**:
 
 
@@ -279,6 +286,8 @@ Accept: application/json
 Content-Type: application/json
 Content-Type: application/json
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 ```
 ```
+Note: The api will only work when you pass the admin name and password
+to the request http url, like http://admin:admin@localhost:3000/api/orgs
 
 
 **Example Response**:
 **Example Response**:
 
 
@@ -334,6 +343,9 @@ Accept: application/json
 Content-Type: application/json
 Content-Type: application/json
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
 ```
 ```
+Note: The api will only work when you pass the admin name and password
+to the request http url, like http://admin:admin@localhost:3000/api/orgs/1/users
+
 
 
 **Example Response**:
 **Example Response**:
 
 

+ 7 - 5
docs/sources/index.md

@@ -35,17 +35,19 @@ The back-end web server has a number of configuration options. Go the
 those options.
 those options.
 
 
 
 
-## Getting started
+## Getting Started
 
 
 - [Getting Started]({{< relref "guides/getting_started.md" >}})
 - [Getting Started]({{< relref "guides/getting_started.md" >}})
 - [Basic Concepts]({{< relref "guides/basic_concepts.md" >}})
 - [Basic Concepts]({{< relref "guides/basic_concepts.md" >}})
 - [Screencasts]({{< relref "tutorials/screencasts.md" >}})
 - [Screencasts]({{< relref "tutorials/screencasts.md" >}})
 
 
-## Data sources guides
+## Data Source Guides
 
 
 - [Graphite]({{< relref "features/datasources/graphite.md" >}})
 - [Graphite]({{< relref "features/datasources/graphite.md" >}})
 - [Elasticsearch]({{< relref "features/datasources/elasticsearch.md" >}})
 - [Elasticsearch]({{< relref "features/datasources/elasticsearch.md" >}})
 - [InfluxDB]({{< relref "features/datasources/influxdb.md" >}})
 - [InfluxDB]({{< relref "features/datasources/influxdb.md" >}})
-- [OpenTSDB]({{< relref "features/datasources/opentsdb.md" >}})
-
-
+- [Prometheus]({{< relref "features/datasources/influxdb.md" >}})
+- [OpenTSDB]({{< relref "features/datasources/prometheus.md" >}})
+- [MySQL]({{< relref "features/datasources/mysql.md" >}})
+- [Postgres]({{< relref "features/datasources/postgres.md" >}})
+- [Cloudwatch]({{< relref "features/datasources/cloudwatch.md" >}})

+ 3 - 3
docs/sources/installation/debian.md

@@ -15,7 +15,7 @@ weight = 1
 
 
 Description | Download
 Description | Download
 ------------ | -------------
 ------------ | -------------
-Stable for Debian-based Linux | [grafana_4.5.2_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.5.2_amd64.deb)
+Stable for Debian-based Linux | [grafana_4.6.0_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.6.0_amd64.deb)
 
 
 <!-- Beta for Debian-based Linux | [grafana_4.5.0-beta1_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.5.0-beta1_amd64.deb) -->
 <!-- Beta for Debian-based Linux | [grafana_4.5.0-beta1_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.5.0-beta1_amd64.deb) -->
 
 
@@ -26,9 +26,9 @@ installation.
 
 
 
 
 ```bash
 ```bash
-wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.5.2_amd64.deb
+wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.6.0_amd64.deb
 sudo apt-get install -y adduser libfontconfig
 sudo apt-get install -y adduser libfontconfig
-sudo dpkg -i grafana_4.5.2_amd64.deb
+sudo dpkg -i grafana_4.6.0_amd64.deb
 ```
 ```
 
 
 <!--
 <!--

+ 66 - 2
docs/sources/installation/docker.md

@@ -36,11 +36,75 @@ $ docker run -d -p 3000:3000 \
 ```
 ```
 
 
 In the above example I map the data folder and sets a configuration option via
 In the above example I map the data folder and sets a configuration option via
-an `ENV` instruction.
+an `ENV` instruction. 
+
+See the [docker volumes documentation](https://docs.docker.com/engine/admin/volumes/volumes/) if you want to create a volume to use with the Grafana docker image instead of a bind mount (binding to a directory in the host system).
 
 
 ## Configuration
 ## Configuration
 
 
-The back-end web server has a number of configuration options. Go the
+All options defined in conf/grafana.ini can be overridden using environment
+variables by using the syntax `GF_<SectionName>_<KeyName>`.
+For example:
+
+```bash
+$ docker run \
+  -d \
+  -p 3000:3000 \
+  --name=grafana \
+  -e "GF_SERVER_ROOT_URL=http://grafana.server.name" \
+  -e "GF_SECURITY_ADMIN_PASSWORD=secret" \
+  grafana/grafana
+```
+
+You can use your own grafana.ini file by using environment variable `GF_PATHS_CONFIG`.
+
+The back-end web server has a number of configuration options. Go to the
 [Configuration]({{< relref "configuration.md" >}}) page for details on all
 [Configuration]({{< relref "configuration.md" >}}) page for details on all
 those options.
 those options.
 
 
+## Installing Plugins for Grafana
+
+Pass the plugins you want installed to docker with the `GF_INSTALL_PLUGINS` environment variable as a comma separated list. This will pass each plugin name to `grafana-cli plugins install ${plugin}`.
+
+```bash
+docker run \
+  -d \
+  -p 3000:3000 \
+  --name=grafana \
+  -e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" \
+  grafana/grafana
+```
+
+## Running a Specific Version of Grafana
+
+```bash
+# specify right tag, e.g. 4.5.2 - see Docker Hub for available tags
+$ docker run \
+  -d \
+  -p 3000:3000 \
+  --name grafana \
+  grafana/grafana:4.5.2
+```
+
+## Configuring AWS Credentials for CloudWatch Support
+
+```bash
+$ docker run \
+  -d \
+  -p 3000:3000 \
+  --name=grafana \
+  -e "GF_AWS_PROFILES=default" \
+  -e "GF_AWS_default_ACCESS_KEY_ID=YOUR_ACCESS_KEY" \
+  -e "GF_AWS_default_SECRET_ACCESS_KEY=YOUR_SECRET_KEY" \
+  -e "GF_AWS_default_REGION=us-east-1" \
+  grafana/grafana
+```
+
+You may also specify multiple profiles to `GF_AWS_PROFILES` (e.g.
+`GF_AWS_PROFILES=default another`).
+
+Supported variables:
+
+- `GF_AWS_${profile}_ACCESS_KEY_ID`: AWS access key ID (required).
+- `GF_AWS_${profile}_SECRET_ACCESS_KEY`: AWS secret access  key (required).
+- `GF_AWS_${profile}_REGION`: AWS region (optional).

+ 5 - 5
docs/sources/installation/rpm.md

@@ -15,7 +15,7 @@ weight = 2
 
 
 Description | Download
 Description | Download
 ------------ | -------------
 ------------ | -------------
-Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [4.5.2 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.5.2-1.x86_64.rpm)
+Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [4.6.0 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.0-1.x86_64.rpm)
 
 
 <!-- Latest Beta for CentOS / Fedora / OpenSuse / Redhat Linux | [4.5.0-beta1 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.5.0-beta1.x86_64.rpm) -->
 <!-- Latest Beta for CentOS / Fedora / OpenSuse / Redhat Linux | [4.5.0-beta1 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.5.0-beta1.x86_64.rpm) -->
 
 
@@ -27,7 +27,7 @@ installation.
 You can install Grafana using Yum directly.
 You can install Grafana using Yum directly.
 
 
 ```bash
 ```bash
-$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.5.2-1.x86_64.rpm
+$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.0-1.x86_64.rpm
 ```
 ```
 
 
 Or install manually using `rpm`.
 Or install manually using `rpm`.
@@ -35,15 +35,15 @@ Or install manually using `rpm`.
 #### On CentOS / Fedora / Redhat:
 #### On CentOS / Fedora / Redhat:
 
 
 ```bash
 ```bash
-$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.5.2-1.x86_64.rpm
+$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.0-1.x86_64.rpm
 $ sudo yum install initscripts fontconfig
 $ sudo yum install initscripts fontconfig
-$ sudo rpm -Uvh grafana-4.5.2-1.x86_64.rpm
+$ sudo rpm -Uvh grafana-4.6.0-1.x86_64.rpm
 ```
 ```
 
 
 #### On OpenSuse:
 #### On OpenSuse:
 
 
 ```bash
 ```bash
-$ sudo rpm -i --nodeps grafana-4.5.2-1.x86_64.rpm
+$ sudo rpm -i --nodeps grafana-4.6.0-1.x86_64.rpm
 ```
 ```
 
 
 ## Install via YUM Repository
 ## Install via YUM Repository

+ 1 - 1
docs/sources/installation/windows.md

@@ -13,7 +13,7 @@ weight = 3
 
 
 Description | Download
 Description | Download
 ------------ | -------------
 ------------ | -------------
-Latest stable package for Windows | [grafana.4.5.2.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.5.2.windows-x64.zip)
+Latest stable package for Windows | [grafana.4.6.0.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.0.windows-x64.zip)
 
 
 Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
 Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing
 installation.
 installation.

+ 1 - 1
docs/sources/plugins/developing/development.md

@@ -16,7 +16,7 @@ You can extend Grafana by writing your own plugins and then share then with othe
 
 
 1. [Setup grafana](http://docs.grafana.org/project/building_from_source/)
 1. [Setup grafana](http://docs.grafana.org/project/building_from_source/)
 2. Clone an example plugin into ```/var/lib/grafana/plugins```  or `data/plugins` (relative to grafana git repo if you're running development version from source dir)
 2. Clone an example plugin into ```/var/lib/grafana/plugins```  or `data/plugins` (relative to grafana git repo if you're running development version from source dir)
-3. You one of our example plugins as starting point
+3. Use one of our example plugins as starting point
 
 
 Example plugins
 Example plugins
 
 

+ 2 - 2
docs/sources/reference/annotations.md

@@ -69,5 +69,5 @@ The annotation query options are different for each data source.
 - [Elasticsearch annotation queries]({{< relref "features/datasources/elasticsearch.md#annotations" >}})
 - [Elasticsearch annotation queries]({{< relref "features/datasources/elasticsearch.md#annotations" >}})
 - [InfluxDB annotation queries]({{< relref "features/datasources/influxdb.md#annotations" >}})
 - [InfluxDB annotation queries]({{< relref "features/datasources/influxdb.md#annotations" >}})
 - [Prometheus annotation queries]({{< relref "features/datasources/prometheus.md#annotations" >}})
 - [Prometheus annotation queries]({{< relref "features/datasources/prometheus.md#annotations" >}})
-
-
+- [MySQL annotation queries]({{< relref "features/datasources/mysql.md#annotations" >}})
+- [Postgres annotation queries]({{< relref "features/datasources/postgres.md#annotations" >}})

+ 1 - 1
pkg/api/api.go

@@ -287,7 +287,7 @@ func (hs *HttpServer) registerRoutes() {
 
 
 		apiRoute.Group("/alerts", func(alertsRoute RouteRegister) {
 		apiRoute.Group("/alerts", func(alertsRoute RouteRegister) {
 			alertsRoute.Post("/test", bind(dtos.AlertTestCommand{}), wrap(AlertTest))
 			alertsRoute.Post("/test", bind(dtos.AlertTestCommand{}), wrap(AlertTest))
-			alertsRoute.Post("/:alertId/pause", bind(dtos.PauseAlertCommand{}), wrap(PauseAlert), reqEditorRole)
+			alertsRoute.Post("/:alertId/pause", reqEditorRole, bind(dtos.PauseAlertCommand{}), wrap(PauseAlert))
 			alertsRoute.Get("/:alertId", ValidateOrgAlert, wrap(GetAlert))
 			alertsRoute.Get("/:alertId", ValidateOrgAlert, wrap(GetAlert))
 			alertsRoute.Get("/", wrap(GetAlerts))
 			alertsRoute.Get("/", wrap(GetAlerts))
 			alertsRoute.Get("/states-for-dashboard", wrap(GetAlertStatesForDashboard))
 			alertsRoute.Get("/states-for-dashboard", wrap(GetAlertStatesForDashboard))

+ 20 - 6
pkg/api/datasources.go

@@ -119,7 +119,13 @@ func AddDataSource(c *middleware.Context, cmd m.AddDataSourceCommand) {
 		return
 		return
 	}
 	}
 
 
-	c.JSON(200, util.DynMap{"message": "Datasource added", "id": cmd.Result.Id, "name": cmd.Result.Name})
+	ds := convertModelToDtos(cmd.Result)
+	c.JSON(200, util.DynMap{
+		"message":    "Datasource added",
+		"id":         cmd.Result.Id,
+		"name":       cmd.Result.Name,
+		"datasource": ds,
+	})
 }
 }
 
 
 func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) Response {
 func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) Response {
@@ -133,10 +139,19 @@ func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) Resp
 
 
 	err = bus.Dispatch(&cmd)
 	err = bus.Dispatch(&cmd)
 	if err != nil {
 	if err != nil {
-		return ApiError(500, "Failed to update datasource", err)
+		if err == m.ErrDataSourceUpdatingOldVersion {
+			return ApiError(500, "Failed to update datasource. Reload new version and try again", err)
+		} else {
+			return ApiError(500, "Failed to update datasource", err)
+		}
 	}
 	}
-
-	return Json(200, util.DynMap{"message": "Datasource updated", "id": cmd.Id, "name": cmd.Name})
+	ds := convertModelToDtos(cmd.Result)
+	return Json(200, util.DynMap{
+		"message":    "Datasource updated",
+		"id":         cmd.Id,
+		"name":       cmd.Name,
+		"datasource": ds,
+	})
 }
 }
 
 
 func fillWithSecureJsonData(cmd *m.UpdateDataSourceCommand) error {
 func fillWithSecureJsonData(cmd *m.UpdateDataSourceCommand) error {
@@ -158,8 +173,6 @@ func fillWithSecureJsonData(cmd *m.UpdateDataSourceCommand) error {
 		}
 		}
 	}
 	}
 
 
-	// set version from db
-	cmd.Version = ds.Version
 	return nil
 	return nil
 }
 }
 
 
@@ -228,6 +241,7 @@ func convertModelToDtos(ds *m.DataSource) dtos.DataSource {
 		IsDefault:         ds.IsDefault,
 		IsDefault:         ds.IsDefault,
 		JsonData:          ds.JsonData,
 		JsonData:          ds.JsonData,
 		SecureJsonFields:  map[string]bool{},
 		SecureJsonFields:  map[string]bool{},
+		Version:           ds.Version,
 	}
 	}
 
 
 	for k, v := range ds.SecureJsonData {
 	for k, v := range ds.SecureJsonData {

+ 59 - 0
pkg/api/dtos/datasource.go

@@ -0,0 +1,59 @@
+package dtos
+
+import (
+	"strings"
+
+	"github.com/grafana/grafana/pkg/components/simplejson"
+	m "github.com/grafana/grafana/pkg/models"
+)
+
+type DataSource struct {
+	Id                int64            `json:"id"`
+	OrgId             int64            `json:"orgId"`
+	Name              string           `json:"name"`
+	Type              string           `json:"type"`
+	TypeLogoUrl       string           `json:"typeLogoUrl"`
+	Access            m.DsAccess       `json:"access"`
+	Url               string           `json:"url"`
+	Password          string           `json:"password"`
+	User              string           `json:"user"`
+	Database          string           `json:"database"`
+	BasicAuth         bool             `json:"basicAuth"`
+	BasicAuthUser     string           `json:"basicAuthUser"`
+	BasicAuthPassword string           `json:"basicAuthPassword"`
+	WithCredentials   bool             `json:"withCredentials"`
+	IsDefault         bool             `json:"isDefault"`
+	JsonData          *simplejson.Json `json:"jsonData,omitempty"`
+	SecureJsonFields  map[string]bool  `json:"secureJsonFields"`
+	Version           int              `json:"version"`
+}
+
+type DataSourceListItemDTO struct {
+	Id          int64            `json:"id"`
+	OrgId       int64            `json:"orgId"`
+	Name        string           `json:"name"`
+	Type        string           `json:"type"`
+	TypeLogoUrl string           `json:"typeLogoUrl"`
+	Access      m.DsAccess       `json:"access"`
+	Url         string           `json:"url"`
+	Password    string           `json:"password"`
+	User        string           `json:"user"`
+	Database    string           `json:"database"`
+	BasicAuth   bool             `json:"basicAuth"`
+	IsDefault   bool             `json:"isDefault"`
+	JsonData    *simplejson.Json `json:"jsonData,omitempty"`
+}
+
+type DataSourceList []DataSourceListItemDTO
+
+func (slice DataSourceList) Len() int {
+	return len(slice)
+}
+
+func (slice DataSourceList) Less(i, j int) bool {
+	return strings.ToLower(slice[i].Name) < strings.ToLower(slice[j].Name)
+}
+
+func (slice DataSourceList) Swap(i, j int) {
+	slice[i], slice[j] = slice[j], slice[i]
+}

+ 0 - 50
pkg/api/dtos/models.go

@@ -38,56 +38,6 @@ type CurrentUser struct {
 	HelpFlags1     m.HelpFlags1 `json:"helpFlags1"`
 	HelpFlags1     m.HelpFlags1 `json:"helpFlags1"`
 }
 }
 
 
-type DataSource struct {
-	Id                int64            `json:"id"`
-	OrgId             int64            `json:"orgId"`
-	Name              string           `json:"name"`
-	Type              string           `json:"type"`
-	TypeLogoUrl       string           `json:"typeLogoUrl"`
-	Access            m.DsAccess       `json:"access"`
-	Url               string           `json:"url"`
-	Password          string           `json:"password"`
-	User              string           `json:"user"`
-	Database          string           `json:"database"`
-	BasicAuth         bool             `json:"basicAuth"`
-	BasicAuthUser     string           `json:"basicAuthUser"`
-	BasicAuthPassword string           `json:"basicAuthPassword"`
-	WithCredentials   bool             `json:"withCredentials"`
-	IsDefault         bool             `json:"isDefault"`
-	JsonData          *simplejson.Json `json:"jsonData,omitempty"`
-	SecureJsonFields  map[string]bool  `json:"secureJsonFields"`
-}
-
-type DataSourceListItemDTO struct {
-	Id          int64            `json:"id"`
-	OrgId       int64            `json:"orgId"`
-	Name        string           `json:"name"`
-	Type        string           `json:"type"`
-	TypeLogoUrl string           `json:"typeLogoUrl"`
-	Access      m.DsAccess       `json:"access"`
-	Url         string           `json:"url"`
-	Password    string           `json:"password"`
-	User        string           `json:"user"`
-	Database    string           `json:"database"`
-	BasicAuth   bool             `json:"basicAuth"`
-	IsDefault   bool             `json:"isDefault"`
-	JsonData    *simplejson.Json `json:"jsonData,omitempty"`
-}
-
-type DataSourceList []DataSourceListItemDTO
-
-func (slice DataSourceList) Len() int {
-	return len(slice)
-}
-
-func (slice DataSourceList) Less(i, j int) bool {
-	return strings.ToLower(slice[i].Name) < strings.ToLower(slice[j].Name)
-}
-
-func (slice DataSourceList) Swap(i, j int) {
-	slice[i], slice[j] = slice[j], slice[i]
-}
-
 type MetricRequest struct {
 type MetricRequest struct {
 	From    string             `json:"from"`
 	From    string             `json:"from"`
 	To      string             `json:"to"`
 	To      string             `json:"to"`

+ 0 - 2
pkg/cmd/grafana-server/server.go

@@ -19,7 +19,6 @@ import (
 	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/services/alerting"
 	"github.com/grafana/grafana/pkg/services/alerting"
 	"github.com/grafana/grafana/pkg/services/cleanup"
 	"github.com/grafana/grafana/pkg/services/cleanup"
-	"github.com/grafana/grafana/pkg/services/eventpublisher"
 	"github.com/grafana/grafana/pkg/services/notifications"
 	"github.com/grafana/grafana/pkg/services/notifications"
 	"github.com/grafana/grafana/pkg/services/search"
 	"github.com/grafana/grafana/pkg/services/search"
 	"github.com/grafana/grafana/pkg/setting"
 	"github.com/grafana/grafana/pkg/setting"
@@ -59,7 +58,6 @@ func (g *GrafanaServerImpl) Start() {
 	search.Init()
 	search.Init()
 	login.Init()
 	login.Init()
 	social.NewOAuthService()
 	social.NewOAuthService()
-	eventpublisher.Init()
 	plugins.Init()
 	plugins.Init()
 
 
 	closer, err := tracing.Init(setting.Cfg)
 	closer, err := tracing.Init(setting.Cfg)

+ 3 - 1
pkg/components/renderer/renderer.go

@@ -129,7 +129,9 @@ func RenderToPng(params *RenderOpts) (string, error) {
 
 
 	done := make(chan error)
 	done := make(chan error)
 	go func() {
 	go func() {
-		cmd.Wait()
+		if err := cmd.Wait(); err != nil {
+			rendererLog.Error("failed to render an image", "error", err)
+		}
 		close(done)
 		close(done)
 	}()
 	}()
 
 

+ 8 - 6
pkg/models/datasource.go

@@ -23,10 +23,10 @@ const (
 	DS_ACCESS_PROXY  = "proxy"
 	DS_ACCESS_PROXY  = "proxy"
 )
 )
 
 
-// Typed errors
 var (
 var (
-	ErrDataSourceNotFound   = errors.New("Data source not found")
-	ErrDataSourceNameExists = errors.New("Data source with same name already exists")
+	ErrDataSourceNotFound           = errors.New("Data source not found")
+	ErrDataSourceNameExists         = errors.New("Data source with same name already exists")
+	ErrDataSourceUpdatingOldVersion = errors.New("Trying to update old version of datasource")
 )
 )
 
 
 type DsAccess string
 type DsAccess string
@@ -131,10 +131,12 @@ type UpdateDataSourceCommand struct {
 	IsDefault         bool              `json:"isDefault"`
 	IsDefault         bool              `json:"isDefault"`
 	JsonData          *simplejson.Json  `json:"jsonData"`
 	JsonData          *simplejson.Json  `json:"jsonData"`
 	SecureJsonData    map[string]string `json:"secureJsonData"`
 	SecureJsonData    map[string]string `json:"secureJsonData"`
+	Version           int               `json:"version"`
 
 
-	OrgId   int64 `json:"-"`
-	Id      int64 `json:"-"`
-	Version int   `json:"-"`
+	OrgId int64 `json:"-"`
+	Id    int64 `json:"-"`
+
+	Result *DataSource
 }
 }
 
 
 type DeleteDataSourceByIdCommand struct {
 type DeleteDataSourceByIdCommand struct {

+ 1 - 1
pkg/services/alerting/eval_handler.go

@@ -67,7 +67,7 @@ func (e *DefaultEvalHandler) Eval(context *EvalContext) {
 	metrics.M_Alerting_Execution_Time.Observe(float64(elapsedTime))
 	metrics.M_Alerting_Execution_Time.Observe(float64(elapsedTime))
 }
 }
 
 
-// This should be move into evalContext once its been refactored.
+// This should be move into evalContext once its been refactored. (Carl Bergquist)
 func (handler *DefaultEvalHandler) getNewState(evalContext *EvalContext) models.AlertStateType {
 func (handler *DefaultEvalHandler) getNewState(evalContext *EvalContext) models.AlertStateType {
 	if evalContext.Error != nil {
 	if evalContext.Error != nil {
 		handler.log.Error("Alert Rule Result Error",
 		handler.log.Error("Alert Rule Result Error",

+ 0 - 150
pkg/services/eventpublisher/eventpublisher.go

@@ -1,150 +0,0 @@
-package eventpublisher
-
-import (
-	"encoding/json"
-	"fmt"
-	"log"
-	"time"
-
-	"github.com/grafana/grafana/pkg/bus"
-	"github.com/grafana/grafana/pkg/events"
-	"github.com/grafana/grafana/pkg/setting"
-	"github.com/streadway/amqp"
-)
-
-var (
-	url      string
-	exchange string
-	conn     *amqp.Connection
-	channel  *amqp.Channel
-)
-
-func getConnection() (*amqp.Connection, error) {
-	c, err := amqp.Dial(url)
-	if err != nil {
-		return nil, err
-	}
-	return c, err
-}
-
-func getChannel() (*amqp.Channel, error) {
-	ch, err := conn.Channel()
-	if err != nil {
-		return nil, err
-	}
-
-	err = ch.ExchangeDeclare(
-		exchange, // name
-		"topic",  // type
-		true,     // durable
-		false,    // auto-deleted
-		false,    // internal
-		false,    // no-wait
-		nil,      // arguments
-	)
-	if err != nil {
-		return nil, err
-	}
-	return ch, err
-}
-
-func Init() {
-	sec := setting.Cfg.Section("event_publisher")
-
-	if !sec.Key("enabled").MustBool(false) {
-		return
-	}
-
-	url = sec.Key("rabbitmq_url").String()
-	exchange = sec.Key("exchange").String()
-	bus.AddWildcardListener(eventListener)
-
-	if err := Setup(); err != nil {
-		log.Fatal(4, "Failed to connect to notification queue: %v", err)
-		return
-	}
-}
-
-// Every connection should declare the topology they expect
-func Setup() error {
-	c, err := getConnection()
-	if err != nil {
-		return err
-	}
-	conn = c
-	ch, err := getChannel()
-	if err != nil {
-		return err
-	}
-
-	channel = ch
-
-	// listen for close events so we can reconnect.
-	errChan := channel.NotifyClose(make(chan *amqp.Error))
-	go func() {
-		for e := range errChan {
-			fmt.Println("connection to rabbitmq lost.")
-			fmt.Println(e)
-			fmt.Println("attempting to create new rabbitmq channel.")
-			ch, err := getChannel()
-			if err == nil {
-				channel = ch
-				break
-			}
-
-			//could not create channel, so lets close the connection
-			// and re-create.
-			_ = conn.Close()
-
-			for err != nil {
-				time.Sleep(2 * time.Second)
-				fmt.Println("attempting to reconnect to rabbitmq.")
-				err = Setup()
-			}
-			fmt.Println("Connected to rabbitmq again.")
-		}
-	}()
-
-	return nil
-}
-
-func publish(routingKey string, msgString []byte) {
-	for {
-		err := channel.Publish(
-			exchange,   //exchange
-			routingKey, // routing key
-			false,      // mandatory
-			false,      // immediate
-			amqp.Publishing{
-				ContentType: "application/json",
-				Body:        msgString,
-			},
-		)
-		if err == nil {
-			return
-		}
-		// failures are most likely because the connection was lost.
-		// the connection will be re-established, so just keep
-		// retrying every 2seconds until we successfully publish.
-		time.Sleep(2 * time.Second)
-		fmt.Println("publish failed, retrying.")
-	}
-}
-
-func eventListener(event interface{}) error {
-	wireEvent, err := events.ToOnWriteEvent(event)
-	if err != nil {
-		return err
-	}
-
-	msgString, err := json.Marshal(wireEvent)
-	if err != nil {
-		return err
-	}
-
-	routingKey := fmt.Sprintf("%s.%s", wireEvent.Priority, wireEvent.EventType)
-	// this is run in a greenthread and we expect that publish will keep
-	// retrying until the message gets sent.
-	go publish(routingKey, msgString)
-	return nil
-}

+ 21 - 3
pkg/services/sqlstore/datasource.go

@@ -3,6 +3,8 @@ package sqlstore
 import (
 import (
 	"time"
 	"time"
 
 
+	"github.com/go-xorm/xorm"
+
 	"github.com/grafana/grafana/pkg/bus"
 	"github.com/grafana/grafana/pkg/bus"
 	"github.com/grafana/grafana/pkg/components/securejsondata"
 	"github.com/grafana/grafana/pkg/components/securejsondata"
 	"github.com/grafana/grafana/pkg/metrics"
 	"github.com/grafana/grafana/pkg/metrics"
@@ -69,7 +71,6 @@ func DeleteDataSourceByName(cmd *m.DeleteDataSourceByNameCommand) error {
 }
 }
 
 
 func AddDataSource(cmd *m.AddDataSourceCommand) error {
 func AddDataSource(cmd *m.AddDataSourceCommand) error {
-
 	return inTransaction(func(sess *DBSession) error {
 	return inTransaction(func(sess *DBSession) error {
 		existing := m.DataSource{OrgId: cmd.OrgId, Name: cmd.Name}
 		existing := m.DataSource{OrgId: cmd.OrgId, Name: cmd.Name}
 		has, _ := sess.Get(&existing)
 		has, _ := sess.Get(&existing)
@@ -96,6 +97,7 @@ func AddDataSource(cmd *m.AddDataSourceCommand) error {
 			SecureJsonData:    securejsondata.GetEncryptedJsonData(cmd.SecureJsonData),
 			SecureJsonData:    securejsondata.GetEncryptedJsonData(cmd.SecureJsonData),
 			Created:           time.Now(),
 			Created:           time.Now(),
 			Updated:           time.Now(),
 			Updated:           time.Now(),
+			Version:           1,
 		}
 		}
 
 
 		if _, err := sess.Insert(ds); err != nil {
 		if _, err := sess.Insert(ds); err != nil {
@@ -122,7 +124,6 @@ func updateIsDefaultFlag(ds *m.DataSource, sess *DBSession) error {
 }
 }
 
 
 func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
 func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
-
 	return inTransaction(func(sess *DBSession) error {
 	return inTransaction(func(sess *DBSession) error {
 		ds := &m.DataSource{
 		ds := &m.DataSource{
 			Id:                cmd.Id,
 			Id:                cmd.Id,
@@ -149,12 +150,29 @@ func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
 		sess.UseBool("basic_auth")
 		sess.UseBool("basic_auth")
 		sess.UseBool("with_credentials")
 		sess.UseBool("with_credentials")
 
 
-		_, err := sess.Where("id=? and org_id=?", ds.Id, ds.OrgId).Update(ds)
+		var updateSession *xorm.Session
+		if cmd.Version != 0 {
+			// the reason we allow cmd.version > db.version is make it possible for people to force
+			// updates to datasources using the datasource.yaml file without knowing exactly what version
+			// a datasource have in the db.
+			updateSession = sess.Where("id=? and org_id=? and version < ?", ds.Id, ds.OrgId, ds.Version)
+
+		} else {
+			updateSession = sess.Where("id=? and org_id=?", ds.Id, ds.OrgId)
+		}
+
+		affected, err := updateSession.Update(ds)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
+		if affected == 0 {
+			return m.ErrDataSourceUpdatingOldVersion
+		}
+
 		err = updateIsDefaultFlag(ds, sess)
 		err = updateIsDefaultFlag(ds, sess)
+
+		cmd.Result = ds
 		return err
 		return err
 	})
 	})
 }
 }

+ 83 - 7
pkg/services/sqlstore/datasource_test.go

@@ -37,12 +37,9 @@ type Test struct {
 }
 }
 
 
 func TestDataAccess(t *testing.T) {
 func TestDataAccess(t *testing.T) {
-
 	Convey("Testing DB", t, func() {
 	Convey("Testing DB", t, func() {
 		InitTestDB(t)
 		InitTestDB(t)
-
 		Convey("Can add datasource", func() {
 		Convey("Can add datasource", func() {
-
 			err := AddDataSource(&m.AddDataSourceCommand{
 			err := AddDataSource(&m.AddDataSourceCommand{
 				OrgId:    10,
 				OrgId:    10,
 				Name:     "laban",
 				Name:     "laban",
@@ -67,7 +64,6 @@ func TestDataAccess(t *testing.T) {
 		})
 		})
 
 
 		Convey("Given a datasource", func() {
 		Convey("Given a datasource", func() {
-
 			err := AddDataSource(&m.AddDataSourceCommand{
 			err := AddDataSource(&m.AddDataSourceCommand{
 				OrgId:  10,
 				OrgId:  10,
 				Name:   "nisse",
 				Name:   "nisse",
@@ -83,6 +79,89 @@ func TestDataAccess(t *testing.T) {
 
 
 			ds := query.Result[0]
 			ds := query.Result[0]
 
 
+			Convey(" updated ", func() {
+				cmd := &m.UpdateDataSourceCommand{
+					Id:      ds.Id,
+					OrgId:   10,
+					Name:    "nisse",
+					Type:    m.DS_GRAPHITE,
+					Access:  m.DS_ACCESS_PROXY,
+					Url:     "http://test",
+					Version: ds.Version,
+				}
+
+				Convey("with same version as source", func() {
+					err := UpdateDataSource(cmd)
+					So(err, ShouldBeNil)
+				})
+
+				Convey("when someone else updated between read and update", func() {
+					query := m.GetDataSourcesQuery{OrgId: 10}
+					err = GetDataSources(&query)
+					So(err, ShouldBeNil)
+
+					ds := query.Result[0]
+					intendedUpdate := &m.UpdateDataSourceCommand{
+						Id:      ds.Id,
+						OrgId:   10,
+						Name:    "nisse",
+						Type:    m.DS_GRAPHITE,
+						Access:  m.DS_ACCESS_PROXY,
+						Url:     "http://test",
+						Version: ds.Version,
+					}
+
+					updateFromOtherUser := &m.UpdateDataSourceCommand{
+						Id:      ds.Id,
+						OrgId:   10,
+						Name:    "nisse",
+						Type:    m.DS_GRAPHITE,
+						Access:  m.DS_ACCESS_PROXY,
+						Url:     "http://test",
+						Version: ds.Version,
+					}
+
+					err := UpdateDataSource(updateFromOtherUser)
+					So(err, ShouldBeNil)
+
+					err = UpdateDataSource(intendedUpdate)
+					So(err, ShouldNotBeNil)
+				})
+
+				Convey("updating datasource without version", func() {
+					cmd := &m.UpdateDataSourceCommand{
+						Id:     ds.Id,
+						OrgId:  10,
+						Name:   "nisse",
+						Type:   m.DS_GRAPHITE,
+						Access: m.DS_ACCESS_PROXY,
+						Url:    "http://test",
+					}
+
+					Convey("should not raise errors", func() {
+						err := UpdateDataSource(cmd)
+						So(err, ShouldBeNil)
+					})
+				})
+
+				Convey("updating datasource without higher version", func() {
+					cmd := &m.UpdateDataSourceCommand{
+						Id:      ds.Id,
+						OrgId:   10,
+						Name:    "nisse",
+						Type:    m.DS_GRAPHITE,
+						Access:  m.DS_ACCESS_PROXY,
+						Url:     "http://test",
+						Version: 90000,
+					}
+
+					Convey("should not raise errors", func() {
+						err := UpdateDataSource(cmd)
+						So(err, ShouldBeNil)
+					})
+				})
+			})
+
 			Convey("Can delete datasource by id", func() {
 			Convey("Can delete datasource by id", func() {
 				err := DeleteDataSourceById(&m.DeleteDataSourceByIdCommand{Id: ds.Id, OrgId: ds.OrgId})
 				err := DeleteDataSourceById(&m.DeleteDataSourceByIdCommand{Id: ds.Id, OrgId: ds.OrgId})
 				So(err, ShouldBeNil)
 				So(err, ShouldBeNil)
@@ -106,9 +185,6 @@ func TestDataAccess(t *testing.T) {
 				GetDataSources(&query)
 				GetDataSources(&query)
 				So(len(query.Result), ShouldEqual, 1)
 				So(len(query.Result), ShouldEqual, 1)
 			})
 			})
-
 		})
 		})
-
 	})
 	})
-
 }
 }

+ 6 - 0
pkg/services/sqlstore/migrations/datasource_mig.go

@@ -120,4 +120,10 @@ func addDataSourceMigration(mg *Migrator) {
 		{Name: "json_data", Type: DB_Text, Nullable: true},
 		{Name: "json_data", Type: DB_Text, Nullable: true},
 		{Name: "secure_json_data", Type: DB_Text, Nullable: true},
 		{Name: "secure_json_data", Type: DB_Text, Nullable: true},
 	}))
 	}))
+
+	const setVersionToOneWhereZero = `UPDATE data_source SET version = 1 WHERE version = 0`
+	mg.AddMigration("Update initial version to 1", new(RawSqlMigration).
+		Sqlite(setVersionToOneWhereZero).
+		Postgres(setVersionToOneWhereZero).
+		Mysql(setVersionToOneWhereZero))
 }
 }

+ 0 - 2
public/app/core/components/layout_selector/layout_selector.ts

@@ -1,5 +1,3 @@
-///<reference path="../../../headers/common.d.ts" />
-
 import store from 'app/core/store';
 import store from 'app/core/store';
 import coreModule from 'app/core/core_module';
 import coreModule from 'app/core/core_module';
 
 

+ 23 - 25
public/app/core/controllers/inspect_ctrl.js → public/app/core/controllers/inspect_ctrl.ts

@@ -1,26 +1,13 @@
-define([
-  'angular',
-  'lodash',
-  'jquery',
-  '../core_module',
-],
-function (angular, _, $, coreModule) {
-  'use strict';
+import angular from 'angular';
+import _ from 'lodash';
+import $ from 'jquery';
+import coreModule from '../core_module';
 
 
-  coreModule.default.controller('InspectCtrl', function($scope, $sanitize) {
-    var model = $scope.inspector;
+export class InspectCtrl {
 
 
-    function getParametersFromQueryString(queryString) {
-      var result = [];
-      var parameters = queryString.split("&");
-      for (var i = 0; i < parameters.length; i++) {
-        var keyValue = parameters[i].split("=");
-        if (keyValue[1].length > 0) {
-          result.push({ key: keyValue[0], value: window.unescape(keyValue[1]) });
-        }
-      }
-      return result;
-    }
+  /** @ngInject */
+  constructor($scope, $sanitize) {
+    var model = $scope.inspector;
 
 
     $scope.init = function () {
     $scope.init = function () {
       $scope.editor = { index: 0 };
       $scope.editor = { index: 0 };
@@ -57,7 +44,7 @@ function (angular, _, $, coreModule) {
         $scope.editor.index = 2;
         $scope.editor.index = 2;
 
 
         if (_.isString(model.error.config.data)) {
         if (_.isString(model.error.config.data)) {
-          $scope.request_parameters = getParametersFromQueryString(model.error.config.data);
+          $scope.request_parameters = this.getParametersFromQueryString(model.error.config.data);
         } else  {
         } else  {
           $scope.request_parameters = _.map(model.error.config.data, function(value, key) {
           $scope.request_parameters = _.map(model.error.config.data, function(value, key) {
             return {key: key, value: angular.toJson(value, true)};
             return {key: key, value: angular.toJson(value, true)};
@@ -65,7 +52,18 @@ function (angular, _, $, coreModule) {
         }
         }
       }
       }
     };
     };
+  }
+  getParametersFromQueryString(queryString) {
+    var result = [];
+    var parameters = queryString.split("&");
+    for (var i = 0; i < parameters.length; i++) {
+      var keyValue = parameters[i].split("=");
+      if (keyValue[1].length > 0) {
+        result.push({ key: keyValue[0], value: (<any>window).unescape(keyValue[1]) });
+      }
+    }
+    return result;
+  }
+}
 
 
-  });
-
-});
+coreModule.controller('InspectCtrl', InspectCtrl);

+ 4 - 3
public/app/core/directives/diff-view.ts

@@ -7,14 +7,15 @@ export class DeltaCtrl {
   observer: any;
   observer: any;
 
 
   /** @ngInject */
   /** @ngInject */
-  constructor($rootScope) {
-    const waitForCompile = function(mutations) {
+  constructor(private $rootScope) {
+
+    const waitForCompile = (mutations) => {
       if (mutations.length === 1) {
       if (mutations.length === 1) {
         this.$rootScope.appEvent('json-diff-ready');
         this.$rootScope.appEvent('json-diff-ready');
       }
       }
     };
     };
 
 
-    this.observer = new MutationObserver(waitForCompile.bind(this));
+    this.observer = new MutationObserver(waitForCompile);
 
 
     const observerConfig = {
     const observerConfig = {
       attributes: true,
       attributes: true,

+ 15 - 11
public/app/core/routes/dashboard_loaders.js → public/app/core/routes/dashboard_loaders.ts

@@ -1,10 +1,9 @@
-define([
-  '../core_module',
-],
-function (coreModule) {
-  "use strict";
+import coreModule from '../core_module';
 
 
-  coreModule.default.controller('LoadDashboardCtrl', function($scope, $routeParams, dashboardLoaderSrv, backendSrv, $location) {
+export class LoadDashboardCtrl {
+
+  /** @ngInject */
+  constructor($scope, $routeParams, dashboardLoaderSrv, backendSrv, $location) {
     $scope.appEvent("dashboard-fetch-start");
     $scope.appEvent("dashboard-fetch-start");
 
 
     if (!$routeParams.slug) {
     if (!$routeParams.slug) {
@@ -26,10 +25,13 @@ function (coreModule) {
       }
       }
       $scope.initDashboard(result, $scope);
       $scope.initDashboard(result, $scope);
     });
     });
+  }
+}
 
 
-  });
+export class NewDashboardCtrl {
 
 
-  coreModule.default.controller('NewDashboardCtrl', function($scope) {
+  /** @ngInject */
+  constructor($scope) {
     $scope.initDashboard({
     $scope.initDashboard({
       meta: { canStar: false, canShare: false, isNew: true },
       meta: { canStar: false, canShare: false, isNew: true },
       dashboard: {
       dashboard: {
@@ -38,12 +40,14 @@ function (coreModule) {
           {
           {
             title: 'Dashboard Row',
             title: 'Dashboard Row',
             height: '350px',
             height: '350px',
-            panels:[],
+            panels: [],
             isNew: true,
             isNew: true,
           }
           }
         ]
         ]
       },
       },
     }, $scope);
     }, $scope);
-  });
+  }
+}
 
 
-});
+coreModule.controller('LoadDashboardCtrl', LoadDashboardCtrl);
+coreModule.controller('NewDashboardCtrl', NewDashboardCtrl);

+ 0 - 41
public/app/core/services/analytics.js

@@ -1,41 +0,0 @@
-define([
-  'angular',
-  'jquery',
-  'app/core/core_module',
-  'app/core/config',
-],
-function(angular, $, coreModule, config) {
-  'use strict';
-
-  config = config.default;
-
-  coreModule.default.service('googleAnalyticsSrv', function($rootScope, $location) {
-
-    function gaInit() {
-      $.getScript('https://www.google-analytics.com/analytics.js'); // jQuery shortcut
-      var ga = window.ga = window.ga || function () { (ga.q = ga.q || []).push(arguments); }; ga.l = +new Date;
-      ga('create', config.googleAnalyticsId, 'auto');
-      return ga;
-    }
-
-    this.init = function() {
-
-      $rootScope.$on('$viewContentLoaded', function() {
-        var track =  { page: $location.url() };
-
-        var ga = window.ga || gaInit();
-
-        ga('set', track);
-        ga('send', 'pageview');
-      });
-
-    };
-
-  }).run(function(googleAnalyticsSrv) {
-
-    if (config.googleAnalyticsId) {
-      googleAnalyticsSrv.init();
-    }
-
-  });
-});

+ 36 - 0
public/app/core/services/analytics.ts

@@ -0,0 +1,36 @@
+import $ from 'jquery';
+import coreModule from 'app/core/core_module';
+import config from 'app/core/config';
+
+export class Analytics {
+
+  /** @ngInject */
+  constructor(private $rootScope, private $location) {
+  }
+
+  gaInit() {
+    $.getScript('https://www.google-analytics.com/analytics.js'); // jQuery shortcut
+    var ga = (<any>window).ga = (<any>window).ga || function () { (ga.q = ga.q || []).push(arguments); }; ga.l = +new Date;
+    ga('create', (<any>config).googleAnalyticsId, 'auto');
+    return ga;
+  }
+
+  init() {
+    this.$rootScope.$on('$viewContentLoaded', () => {
+      var track = { page: this.$location.url() };
+      var ga = (<any>window).ga || this.gaInit();
+      ga('set', track);
+      ga('send', 'pageview');
+    });
+  }
+}
+
+/** @ngInject */
+function startAnalytics(googleAnalyticsSrv) {
+  if ((<any>config).googleAnalyticsId) {
+    googleAnalyticsSrv.init();
+  }
+}
+
+coreModule.service('googleAnalyticsSrv', Analytics).run(startAnalytics);
+

+ 0 - 33
public/app/core/services/timer.js

@@ -1,33 +0,0 @@
-define([
-  'angular',
-  'lodash',
-  '../core_module',
-],
-function (angular, _, coreModule) {
-  'use strict';
-
-  coreModule.default.service('timer', function($timeout) {
-    // This service really just tracks a list of $timeout promises to give us a
-    // method for cancelling them all when we need to
-
-    var timers = [];
-
-    this.register = function(promise) {
-      timers.push(promise);
-      return promise;
-    };
-
-    this.cancel = function(promise) {
-      timers = _.without(timers,promise);
-      $timeout.cancel(promise);
-    };
-
-    this.cancelAll = function() {
-      _.each(timers, function(t) {
-        $timeout.cancel(t);
-      });
-      timers = [];
-    };
-  });
-
-});

+ 31 - 0
public/app/core/services/timer.ts

@@ -0,0 +1,31 @@
+import _ from 'lodash';
+import coreModule from 'app/core/core_module';
+
+// This service really just tracks a list of $timeout promises to give us a
+// method for cancelling them all when we need to
+export class Timer {
+  timers = [];
+
+  /** @ngInject */
+  constructor(private $timeout) {
+  }
+
+  register(promise) {
+    this.timers.push(promise);
+    return promise;
+  }
+
+  cancel(promise) {
+    this.timers = _.without(this.timers, promise);
+    this.$timeout.cancel(promise);
+  }
+
+  cancelAll() {
+    _.each(this.timers, function (t) {
+      this.$timeout.cancel(t);
+    });
+    this.timers = [];
+  }
+}
+
+coreModule.service('timer', Timer);

+ 44 - 0
public/app/core/specs/store.jest.ts

@@ -0,0 +1,44 @@
+import store from '../store';
+
+Object.assign(window, {
+  localStorage: {
+    removeItem(key) {
+      delete window.localStorage[key];
+    }
+  }
+});
+
+describe('store', () => {
+
+  it("should store", ()=> {
+    store.set("key1", "123");
+    expect(store.get("key1")).toBe("123");
+  });
+
+  it("get key when undefined", ()=> {
+    expect(store.get("key2")).toBe(undefined);
+  });
+
+  it("check if key exixts", ()=> {
+    store.set("key3", "123");
+    expect(store.exists("key3")).toBe(true);
+  });
+
+  it("get boolean when no key", ()=> {
+    expect(store.getBool("key4", false)).toBe(false);
+  });
+
+  it("get boolean", ()=> {
+    store.set("key5", "true");
+    expect(store.getBool("key5", false)).toBe(true);
+  });
+
+  it("key should be deleted", ()=> {
+    store.set("key6", "123");
+    store.delete("key6");
+    expect(store.exists("key6")).toBe(false);
+  });
+
+});
+
+

+ 0 - 26
public/app/core/store.js

@@ -1,26 +0,0 @@
-define([], function() {
-  'use strict';
-
-  return {
-    get: function(key) {
-      return window.localStorage[key];
-    },
-    set: function(key, value) {
-      window.localStorage[key] = value;
-    },
-    getBool: function(key, def) {
-      if (def !== void 0 && !this.exists(key)) {
-        return def;
-      }
-      return window.localStorage[key] === 'true';
-    },
-    exists: function(key) {
-      return window.localStorage[key] !== void 0;
-    },
-    delete: function(key) {
-      window.localStorage.removeItem(key);
-    }
-
-  };
-
-});

+ 29 - 0
public/app/core/store.ts

@@ -0,0 +1,29 @@
+export class Store {
+
+  get(key) {
+    return window.localStorage[key];
+  }
+
+  set(key, value) {
+    window.localStorage[key] = value;
+  }
+
+  getBool(key, def) {
+    if (def !== void 0 && !this.exists(key)) {
+      return def;
+    }
+    return window.localStorage[key] === 'true';
+  }
+
+  exists(key) {
+    return window.localStorage[key] !== void 0;
+  }
+
+  delete(key) {
+    window.localStorage.removeItem(key);
+  }
+
+}
+
+const store = new Store();
+export default store;

+ 0 - 32
public/app/core/utils/outline.js

@@ -1,32 +0,0 @@
-// outline.js
-// based on http://www.paciellogroup.com/blog/2012/04/how-to-remove-css-outlines-in-an-accessible-manner/
-(function(d) {
-  "use strict";
-
-  var style_element = d.createElement('STYLE'),
-    dom_events = 'addEventListener' in d,
-    add_event_listener = function(type, callback) {
-      // Basic cross-browser event handling
-      if(dom_events){
-        d.addEventListener(type, callback);
-      } else {
-        d.attachEvent('on' + type, callback);
-      }
-    },
-    set_css = function(css_text) {
-      // Handle setting of <style> element contents in IE8
-      !!style_element.styleSheet ? style_element.styleSheet.cssText = css_text : style_element.innerHTML = css_text;
-    };
-
-  d.getElementsByTagName('HEAD')[0].appendChild(style_element);
-
-  // Using mousedown instead of mouseover, so that previously focused elements don't lose focus ring on mouse move
-  add_event_listener('mousedown', function() {
-    set_css(':focus{outline:0 !important}::-moz-focus-inner{border:0;}');
-  });
-
-  add_event_listener('keydown', function() {
-    set_css('');
-  });
-
-})(document);

+ 34 - 0
public/app/core/utils/outline.ts

@@ -0,0 +1,34 @@
+// based on http://www.paciellogroup.com/blog/2012/04/how-to-remove-css-outlines-in-an-accessible-manner/
+function outlineFixer() {
+  let d: any = document;
+
+  var style_element = d.createElement('STYLE');
+  var dom_events = 'addEventListener' in d;
+
+  var add_event_listener = function (type, callback) {
+    // Basic cross-browser event handling
+    if (dom_events) {
+      d.addEventListener(type, callback);
+    } else {
+      d.attachEvent('on' + type, callback);
+    }
+  };
+
+  var set_css = function (css_text) {
+    // Handle setting of <style> element contents in IE8
+    !!style_element.styleSheet ? style_element.styleSheet.cssText = css_text : style_element.innerHTML = css_text;
+  };
+
+  d.getElementsByTagName('HEAD')[0].appendChild(style_element);
+
+  // Using mousedown instead of mouseover, so that previously focused elements don't lose focus ring on mouse move
+  add_event_listener('mousedown', function () {
+    set_css(':focus{outline:0 !important}::-moz-focus-inner{border:0;}');
+  });
+
+  add_event_listener('keydown', function () {
+    set_css('');
+  });
+}
+
+outlineFixer();

+ 0 - 1
public/app/features/dashboard/dashboard_model.ts

@@ -31,7 +31,6 @@ export class DashboardModel {
   revision: number;
   revision: number;
   links: any;
   links: any;
   gnetId: any;
   gnetId: any;
-  editMode: boolean;
   folderId: number;
   folderId: number;
   panels: PanelModel[];
   panels: PanelModel[];
 
 

+ 0 - 2
public/app/features/dashboard/impression_store.ts

@@ -1,5 +1,3 @@
-///<reference path="../../headers/common.d.ts" />
-
 import store from 'app/core/store';
 import store from 'app/core/store';
 import _ from 'lodash';
 import _ from 'lodash';
 import config from 'app/core/config';
 import config from 'app/core/config';

+ 0 - 1
public/app/features/dashboard/unsavedChangesSrv.js

@@ -73,7 +73,6 @@ function(angular, _) {
       dash.time = 0;
       dash.time = 0;
       dash.refresh = 0;
       dash.refresh = 0;
       dash.schemaVersion = 0;
       dash.schemaVersion = 0;
-      dash.editMode = false;
 
 
       // filter row and panels properties that should be ignored
       // filter row and panels properties that should be ignored
       dash.rows = _.filter(dash.rows, function(row) {
       dash.rows = _.filter(dash.rows, function(row) {

+ 0 - 1
public/app/features/dashboard/viewStateSrv.js

@@ -147,7 +147,6 @@ function (angular, _, $, config) {
       ctrl.fullscreen = false;
       ctrl.fullscreen = false;
 
 
       this.dashboard.setViewMode(ctrl.panel, false, false);
       this.dashboard.setViewMode(ctrl.panel, false, false);
-
       this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id});
       this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id});
 
 
       if (!render) { return false;}
       if (!render) { return false;}

+ 3 - 1
public/app/features/plugins/ds_edit_ctrl.ts

@@ -158,13 +158,15 @@ export class DataSourceEditCtrl {
     }
     }
 
 
     if (this.current.id) {
     if (this.current.id) {
-      return this.backendSrv.put('/api/datasources/' + this.current.id, this.current).then(() => {
+      return this.backendSrv.put('/api/datasources/' + this.current.id, this.current).then((result) => {
+        this.current = result.datasource;
         this.updateFrontendSettings().then(() => {
         this.updateFrontendSettings().then(() => {
           this.testDatasource();
           this.testDatasource();
         });
         });
       });
       });
     } else {
     } else {
       return this.backendSrv.post('/api/datasources', this.current).then(result => {
       return this.backendSrv.post('/api/datasources', this.current).then(result => {
+        this.current = result.datasource;
         this.updateFrontendSettings();
         this.updateFrontendSettings();
 
 
         datasourceCreated = true;
         datasourceCreated = true;

+ 7 - 2
public/app/features/plugins/plugin_loader.ts

@@ -64,16 +64,21 @@ exposeToPlugin('lodash', _);
 exposeToPlugin('moment', moment);
 exposeToPlugin('moment', moment);
 exposeToPlugin('jquery', jquery);
 exposeToPlugin('jquery', jquery);
 exposeToPlugin('angular', angular);
 exposeToPlugin('angular', angular);
+exposeToPlugin('d3', d3);
 exposeToPlugin('rxjs/Subject', Subject);
 exposeToPlugin('rxjs/Subject', Subject);
 exposeToPlugin('rxjs/Observable', Observable);
 exposeToPlugin('rxjs/Observable', Observable);
-exposeToPlugin('d3', d3);
+
+// backward compatible path
+exposeToPlugin('vendor/npm/rxjs/Rx', {
+  Subject: Subject,
+  Observable: Observable
+});
 
 
 exposeToPlugin('app/features/dashboard/impression_store', {
 exposeToPlugin('app/features/dashboard/impression_store', {
   impressions: impressions,
   impressions: impressions,
   __esModule: true
   __esModule: true
 });
 });
 
 
-
 exposeToPlugin('app/plugins/sdk', sdk);
 exposeToPlugin('app/plugins/sdk', sdk);
 exposeToPlugin('app/core/utils/datemath', datemath);
 exposeToPlugin('app/core/utils/datemath', datemath);
 exposeToPlugin('app/core/utils/file_export', fileExport);
 exposeToPlugin('app/core/utils/file_export', fileExport);

+ 4 - 1
public/app/features/templating/interval_variable.ts

@@ -5,6 +5,7 @@ import kbn from 'app/core/utils/kbn';
 import {Variable, assignModelProperties, variableTypes} from './variable';
 import {Variable, assignModelProperties, variableTypes} from './variable';
 
 
 export class IntervalVariable implements Variable {
 export class IntervalVariable implements Variable {
+  name: string;
   auto_count: number;
   auto_count: number;
   auto_min: number;
   auto_min: number;
   options: any;
   options: any;
@@ -50,10 +51,12 @@ export class IntervalVariable implements Variable {
 
 
     // add auto option if missing
     // add auto option if missing
     if (this.options.length && this.options[0].text !== 'auto') {
     if (this.options.length && this.options[0].text !== 'auto') {
-      this.options.unshift({ text: 'auto', value: '$__auto_interval' });
+      this.options.unshift({ text: 'auto', value: '$__auto_interval_' + this.name });
     }
     }
 
 
     var res = kbn.calculateInterval(this.timeSrv.timeRange(), this.auto_count, this.auto_min);
     var res = kbn.calculateInterval(this.timeSrv.timeRange(), this.auto_count, this.auto_min);
+    this.templateSrv.setGrafanaVariable('$__auto_interval_' + this.name, res.interval);
+    // for backward compatibility, to be removed eventually
     this.templateSrv.setGrafanaVariable('$__auto_interval', res.interval);
     this.templateSrv.setGrafanaVariable('$__auto_interval', res.interval);
   }
   }
 
 

+ 1 - 1
public/app/features/templating/partials/editor.html

@@ -74,7 +74,7 @@
 			<div class="grafana-info-box col-lg-8">
 			<div class="grafana-info-box col-lg-8">
 				<h5>What does templating do?</h5>
 				<h5>What does templating do?</h5>
 				<p>Templating allows for more interactive and dynamic dashboards. Instead of hard-coding things like server, application
 				<p>Templating allows for more interactive and dynamic dashboards. Instead of hard-coding things like server, application
-				and sensor name in you metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of
+				and sensor name in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of
 				the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
 				the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
 				<br>
 				<br>
 				<br>
 				<br>

+ 2 - 2
public/app/features/templating/specs/template_srv.jest.ts

@@ -254,9 +254,9 @@ describe('templateSrv', function() {
     beforeEach(function() {
     beforeEach(function() {
       initTemplateSrv([
       initTemplateSrv([
         {type: 'query', name: 'server', current: { value: '{asd,asd2}', text: 'All' } },
         {type: 'query', name: 'server', current: { value: '{asd,asd2}', text: 'All' } },
-        {type: 'interval', name: 'period', current: { value: '$__auto_interval', text: 'auto' } }
+        {type: 'interval', name: 'period', current: { value: '$__auto_interval_interval', text: 'auto' } }
       ]);
       ]);
-      _templateSrv.setGrafanaVariable('$__auto_interval', '13m');
+      _templateSrv.setGrafanaVariable('$__auto_interval_interval', '13m');
       _templateSrv.updateTemplateData();
       _templateSrv.updateTemplateData();
     });
     });
 
 

+ 74 - 2
public/app/features/templating/specs/variable_srv_specs.ts

@@ -84,11 +84,19 @@ describe('VariableSrv', function() {
     it('should update options array', function() {
     it('should update options array', function() {
       expect(scenario.variable.options.length).to.be(5);
       expect(scenario.variable.options.length).to.be(5);
       expect(scenario.variable.options[0].text).to.be('auto');
       expect(scenario.variable.options[0].text).to.be('auto');
-      expect(scenario.variable.options[0].value).to.be('$__auto_interval');
+      expect(scenario.variable.options[0].value).to.be('$__auto_interval_test');
     });
     });
 
 
+    it('should set $__auto_interval_test', function() {
+      var call = ctx.templateSrv.setGrafanaVariable.firstCall;
+      expect(call.args[0]).to.be('$__auto_interval_test');
+      expect(call.args[1]).to.be('12h');
+    });
+
+    // updateAutoValue() gets called twice: once directly once via VariableSrv.validateVariableSelectionState()
+    // So use lastCall instead of a specific call number
     it('should set $__auto_interval', function() {
     it('should set $__auto_interval', function() {
-      var call = ctx.templateSrv.setGrafanaVariable.getCall(0);
+      var call = ctx.templateSrv.setGrafanaVariable.lastCall;
       expect(call.args[0]).to.be('$__auto_interval');
       expect(call.args[0]).to.be('$__auto_interval');
       expect(call.args[1]).to.be('12h');
       expect(call.args[1]).to.be('12h');
     });
     });
@@ -395,4 +403,68 @@ describe('VariableSrv', function() {
         expect(scenario.variable.options[1].value).to.be('hop');
         expect(scenario.variable.options[1].value).to.be('hop');
       });
       });
     });
     });
+
+    describe('multiple interval variables with auto', function() {
+      var variable1, variable2;
+
+      beforeEach(function() {
+        var range = {
+          from: moment(new Date()).subtract(7, 'days').toDate(),
+          to: new Date()
+        };
+        ctx.timeSrv.timeRange = sinon.stub().returns(range);
+        ctx.templateSrv.setGrafanaVariable = sinon.spy();
+
+        var variableModel1 = {type: 'interval', query: '1s,2h,5h,1d', name: 'variable1', auto: true, auto_count: 10 };
+        variable1 = ctx.variableSrv.createVariableFromModel(variableModel1);
+        ctx.variableSrv.addVariable(variable1);
+
+        var variableModel2 = {type: 'interval', query: '1s,2h,5h', name: 'variable2', auto: true, auto_count: 1000 };
+        variable2 = ctx.variableSrv.createVariableFromModel(variableModel2);
+        ctx.variableSrv.addVariable(variable2);
+
+        ctx.variableSrv.updateOptions(variable1);
+        ctx.variableSrv.updateOptions(variable2);
+        ctx.$rootScope.$digest();
+      });
+
+      it('should update options array', function() {
+        expect(variable1.options.length).to.be(5);
+        expect(variable1.options[0].text).to.be('auto');
+        expect(variable1.options[0].value).to.be('$__auto_interval_variable1');
+        expect(variable2.options.length).to.be(4);
+        expect(variable2.options[0].text).to.be('auto');
+        expect(variable2.options[0].value).to.be('$__auto_interval_variable2');
+      });
+
+      it('should correctly set $__auto_interval_variableX', function() {
+        var variable1Set, variable2Set, legacySet, unknownSet = false;
+        // updateAutoValue() gets called repeatedly: once directly once via VariableSrv.validateVariableSelectionState()
+        // So check that all calls are valid rather than expect a specific number and/or ordering of calls
+        for (var i = 0; i < ctx.templateSrv.setGrafanaVariable.callCount; i++) {
+          var call = ctx.templateSrv.setGrafanaVariable.getCall(i);
+          switch (call.args[0]) {
+            case '$__auto_interval_variable1':
+              expect(call.args[1]).to.be('12h');
+              variable1Set = true;
+              break;
+            case '$__auto_interval_variable2':
+              expect(call.args[1]).to.be('10m');
+              variable2Set = true;
+              break;
+            case '$__auto_interval':
+              expect(call.args[1]).to.match(/^(12h|10m)$/);
+              legacySet = true;
+              break;
+            default:
+              unknownSet = true;
+              break;
+          }
+        }
+        expect(variable1Set).to.be.equal(true);
+        expect(variable2Set).to.be.equal(true);
+        expect(legacySet).to.be.equal(true);
+        expect(unknownSet).to.be.equal(false);
+      });
+    });
 });
 });

+ 1 - 1
public/app/plugins/datasource/mysql/datasource.ts

@@ -17,7 +17,7 @@ export class MysqlDatasource {
 
 
   interpolateVariable(value) {
   interpolateVariable(value) {
     if (typeof value === 'string') {
     if (typeof value === 'string') {
-      return '\'' + value + '\'';
+      return value;
     }
     }
 
 
     if (typeof value === 'number') {
     if (typeof value === 'number') {

+ 2 - 2
public/app/plugins/datasource/mysql/specs/datasource_specs.ts

@@ -196,8 +196,8 @@ describe('MySQLDatasource', function() {
 
 
   describe('When interpolating variables', () => {
   describe('When interpolating variables', () => {
     describe('and value is a string', () => {
     describe('and value is a string', () => {
-      it('should return a quoted value', () => {
-        expect(ctx.ds.interpolateVariable('abc')).to.eql('\'abc\'');
+      it('should return an unquoted value', () => {
+        expect(ctx.ds.interpolateVariable('abc')).to.eql('abc');
       });
       });
     });
     });
 
 

+ 2 - 2
public/app/plugins/datasource/postgres/datasource.ts

@@ -17,11 +17,11 @@ export class PostgresDatasource {
 
 
   interpolateVariable(value) {
   interpolateVariable(value) {
     if (typeof value === 'string') {
     if (typeof value === 'string') {
-      return '\'' + value + '\'';
+      return value;
     }
     }
 
 
     if (typeof value === 'number') {
     if (typeof value === 'number') {
-      return value.toString();
+      return value;
     }
     }
 
 
     var quotedValues = _.map(value, function(val) {
     var quotedValues = _.map(value, function(val) {

+ 20 - 0
public/app/plugins/datasource/postgres/specs/datasource_specs.ts

@@ -193,4 +193,24 @@ describe('PostgreSQLDatasource', function() {
       expect(results[0].value).to.be('same');
       expect(results[0].value).to.be('same');
     });
     });
   });
   });
+
+  describe('When interpolating variables', () => {
+    describe('and value is a string', () => {
+      it('should return an unquoted value', () => {
+        expect(ctx.ds.interpolateVariable('abc')).to.eql('abc');
+      });
+    });
+
+    describe('and value is a number', () => {
+      it('should return an unquoted value', () => {
+        expect(ctx.ds.interpolateVariable(1000)).to.eql(1000);
+      });
+    });
+
+    describe('and value is an array of strings', () => {
+      it('should return comma separated quoted values', () => {
+        expect(ctx.ds.interpolateVariable(['a', 'b', 'c'])).to.eql('\'a\',\'b\',\'c\'');
+      });
+    });
+  });
 });
 });

+ 1052 - 0
public/app/plugins/datasource/prometheus/dashboards/grafana_stats.json

@@ -0,0 +1,1052 @@
+{
+    "__inputs": [
+      {
+        "name": "DS_PROMETHEUS",
+        "label": "Prometheus",
+        "description": "",
+        "type": "datasource",
+        "pluginId": "prometheus",
+        "pluginName": "Prometheus"
+      }
+    ],
+    "__requires": [
+      {
+        "type": "grafana",
+        "id": "grafana",
+        "name": "Grafana",
+        "version": "4.6.0"
+      },
+      {
+        "type": "panel",
+        "id": "graph",
+        "name": "Graph",
+        "version": ""
+      },
+      {
+        "type": "datasource",
+        "id": "prometheus",
+        "name": "Prometheus",
+        "version": "1.0.0"
+      },
+      {
+        "type": "panel",
+        "id": "singlestat",
+        "name": "Singlestat",
+        "version": ""
+      },
+      {
+        "type": "panel",
+        "id": "table",
+        "name": "Table",
+        "version": ""
+      },
+      {
+        "type": "panel",
+        "id": "text",
+        "name": "Text",
+        "version": ""
+      }
+    ],
+    "revision": "1.0",
+    "version": 2,
+    "title": "Grafana metrics",
+    "tags": [
+        "grafana",
+        "prometheus"
+    ],
+    "description": "Metrics about Grafana",
+    "editable": true,
+    "gnetId": null,
+    "graphTooltip": 0,
+    "hideControls": false,
+    "id": null,
+    "links": [
+      {
+        "icon": "external link",
+        "tags": [],
+        "targetBlank": true,
+        "title": "Available metrics",
+        "type": "link",
+        "url": "/metrics"
+      },
+      {
+        "icon": "external link",
+        "tags": [],
+        "title": "Grafana docs",
+        "type": "link",
+        "url": "http://docs.grafana.org/"
+      },
+      {
+        "icon": "external link",
+        "tags": [],
+        "title": "Prometheus docs",
+        "type": "link",
+        "url": "http://prometheus.io/docs/introduction/overview/"
+      }
+    ],
+    "rows": [
+      {
+        "collapse": false,
+        "height": 164,
+        "panels": [
+          {
+            "cacheTimeout": null,
+            "colorBackground": false,
+            "colorValue": true,
+            "colors": [
+              "rgba(222, 3, 3, 0.9)",
+              "rgb(234, 245, 234)",
+              "rgb(235, 244, 235)"
+            ],
+            "datasource": "${DS_PROMETHEUS}",
+            "decimals": 0,
+            "format": "none",
+            "gauge": {
+              "maxValue": 100,
+              "minValue": 0,
+              "show": false,
+              "thresholdLabels": false,
+              "thresholdMarkers": true
+            },
+            "id": 4,
+            "interval": null,
+            "links": [],
+            "mappingType": 1,
+            "mappingTypes": [
+              {
+                "name": "value to text",
+                "value": 1
+              },
+              {
+                "name": "range to text",
+                "value": 2
+              }
+            ],
+            "maxDataPoints": 100,
+            "nullPointMode": "connected",
+            "nullText": null,
+            "postfix": "",
+            "postfixFontSize": "50%",
+            "prefix": "",
+            "prefixFontSize": "50%",
+            "rangeMaps": [
+              {
+                "from": "null",
+                "text": "N/A",
+                "to": "null"
+              }
+            ],
+            "span": 2,
+            "sparkline": {
+              "fillColor": "rgba(31, 118, 189, 0.18)",
+              "full": false,
+              "lineColor": "rgb(31, 120, 193)",
+              "show": false
+            },
+            "tableColumn": "",
+            "targets": [
+              {
+                "expr": "up{job=\"grafana\"}",
+                "format": "time_series",
+                "instant": true,
+                "intervalFactor": 2,
+                "refId": "A",
+                "step": 60
+              }
+            ],
+            "thresholds": "1, 10000",
+            "title": "Active instances",
+            "type": "singlestat",
+            "valueFontSize": "120%",
+            "valueMaps": [
+              {
+                "op": "=",
+                "text": ":(",
+                "value": "0"
+              }
+            ],
+            "valueName": "avg"
+          },
+          {
+            "cacheTimeout": null,
+            "colorBackground": false,
+            "colorValue": false,
+            "colors": [
+              "rgba(245, 54, 54, 0.9)",
+              "rgba(237, 129, 40, 0.89)",
+              "rgba(50, 172, 45, 0.97)"
+            ],
+            "datasource": "${DS_PROMETHEUS}",
+            "format": "none",
+            "gauge": {
+              "maxValue": 100,
+              "minValue": 0,
+              "show": false,
+              "thresholdLabels": false,
+              "thresholdMarkers": true
+            },
+            "id": 8,
+            "interval": null,
+            "links": [],
+            "mappingType": 1,
+            "mappingTypes": [
+              {
+                "name": "value to text",
+                "value": 1
+              },
+              {
+                "name": "range to text",
+                "value": 2
+              }
+            ],
+            "maxDataPoints": 100,
+            "nullPointMode": "connected",
+            "nullText": null,
+            "postfix": "",
+            "postfixFontSize": "50%",
+            "prefix": "",
+            "prefixFontSize": "50%",
+            "rangeMaps": [
+              {
+                "from": "null",
+                "text": "N/A",
+                "to": "null"
+              }
+            ],
+            "span": 2,
+            "sparkline": {
+              "fillColor": "rgba(31, 118, 189, 0.18)",
+              "full": false,
+              "lineColor": "rgb(31, 120, 193)",
+              "show": false
+            },
+            "tableColumn": "",
+            "targets": [
+              {
+                "expr": "grafana_stat_totals_dashboard",
+                "format": "time_series",
+                "instant": true,
+                "intervalFactor": 2,
+                "refId": "A",
+                "step": 60
+              }
+            ],
+            "thresholds": "",
+            "title": "Dashboard count",
+            "type": "singlestat",
+            "valueFontSize": "120%",
+            "valueMaps": [
+              {
+                "op": "=",
+                "text": "N/A",
+                "value": "null"
+              }
+            ],
+            "valueName": "avg"
+          },
+          {
+            "cacheTimeout": null,
+            "colorBackground": false,
+            "colorValue": false,
+            "colors": [
+              "rgba(245, 54, 54, 0.9)",
+              "rgba(237, 129, 40, 0.89)",
+              "rgba(50, 172, 45, 0.97)"
+            ],
+            "datasource": "${DS_PROMETHEUS}",
+            "format": "none",
+            "gauge": {
+              "maxValue": 100,
+              "minValue": 0,
+              "show": false,
+              "thresholdLabels": false,
+              "thresholdMarkers": true
+            },
+            "id": 9,
+            "interval": null,
+            "links": [],
+            "mappingType": 1,
+            "mappingTypes": [
+              {
+                "name": "value to text",
+                "value": 1
+              },
+              {
+                "name": "range to text",
+                "value": 2
+              }
+            ],
+            "maxDataPoints": 100,
+            "nullPointMode": "connected",
+            "nullText": null,
+            "postfix": "",
+            "postfixFontSize": "50%",
+            "prefix": "",
+            "prefixFontSize": "50%",
+            "rangeMaps": [
+              {
+                "from": "null",
+                "text": "N/A",
+                "to": "null"
+              }
+            ],
+            "span": 2,
+            "sparkline": {
+              "fillColor": "rgba(31, 118, 189, 0.18)",
+              "full": false,
+              "lineColor": "rgb(31, 120, 193)",
+              "show": false
+            },
+            "tableColumn": "",
+            "targets": [
+              {
+                "expr": "grafana_stat_total_users",
+                "format": "time_series",
+                "instant": true,
+                "intervalFactor": 2,
+                "refId": "A",
+                "step": 60
+              }
+            ],
+            "thresholds": "",
+            "title": "User count",
+            "type": "singlestat",
+            "valueFontSize": "120%",
+            "valueMaps": [
+              {
+                "op": "=",
+                "text": "N/A",
+                "value": "null"
+              }
+            ],
+            "valueName": "avg"
+          },
+          {
+            "cacheTimeout": null,
+            "colorBackground": false,
+            "colorValue": false,
+            "colors": [
+              "rgba(245, 54, 54, 0.9)",
+              "rgba(237, 129, 40, 0.89)",
+              "rgba(50, 172, 45, 0.97)"
+            ],
+            "datasource": "${DS_PROMETHEUS}",
+            "format": "none",
+            "gauge": {
+              "maxValue": 100,
+              "minValue": 0,
+              "show": false,
+              "thresholdLabels": false,
+              "thresholdMarkers": true
+            },
+            "id": 10,
+            "interval": null,
+            "links": [],
+            "mappingType": 1,
+            "mappingTypes": [
+              {
+                "name": "value to text",
+                "value": 1
+              },
+              {
+                "name": "range to text",
+                "value": 2
+              }
+            ],
+            "maxDataPoints": 100,
+            "nullPointMode": "connected",
+            "nullText": null,
+            "postfix": "",
+            "postfixFontSize": "50%",
+            "prefix": "",
+            "prefixFontSize": "50%",
+            "rangeMaps": [
+              {
+                "from": "null",
+                "text": "N/A",
+                "to": "null"
+              }
+            ],
+            "span": 2,
+            "sparkline": {
+              "fillColor": "rgba(31, 118, 189, 0.18)",
+              "full": false,
+              "lineColor": "rgb(31, 120, 193)",
+              "show": false
+            },
+            "tableColumn": "",
+            "targets": [
+              {
+                "expr": "grafana_stat_total_playlists",
+                "format": "time_series",
+                "instant": true,
+                "intervalFactor": 2,
+                "refId": "A",
+                "step": 60
+              }
+            ],
+            "thresholds": "",
+            "title": "Playlist count",
+            "type": "singlestat",
+            "valueFontSize": "120%",
+            "valueMaps": [
+              {
+                "op": "=",
+                "text": "N/A",
+                "value": "null"
+              }
+            ],
+            "valueName": "avg"
+          },
+          {
+            "columns": [],
+            "datasource": "${DS_PROMETHEUS}",
+            "fontSize": "100%",
+            "id": 17,
+            "links": [],
+            "pageSize": null,
+            "scroll": false,
+            "showHeader": true,
+            "sort": {
+              "col": 0,
+              "desc": true
+            },
+            "span": 2,
+            "styles": [
+              {
+                "alias": "Time",
+                "dateFormat": "YYYY-MM-DD HH:mm:ss",
+                "link": false,
+                "pattern": "Time",
+                "type": "hidden"
+              },
+              {
+                "alias": "",
+                "colorMode": null,
+                "colors": [
+                  "rgba(245, 54, 54, 0.9)",
+                  "rgba(237, 129, 40, 0.89)",
+                  "rgba(50, 172, 45, 0.97)"
+                ],
+                "decimals": 0,
+                "pattern": "/.*/",
+                "thresholds": [],
+                "type": "number",
+                "unit": "short"
+              }
+            ],
+            "targets": [
+              {
+                "expr": "topk(1, grafana_info)",
+                "format": "time_series",
+                "instant": true,
+                "intervalFactor": 2,
+                "legendFormat": "{{version}}",
+                "refId": "A",
+                "step": 20
+              }
+            ],
+            "title": "Grafana version",
+            "transform": "timeseries_to_rows",
+            "type": "table"
+          },
+          {
+            "content": "<br />\n<br />\n<center>\n<img src=\"public/img/grafana_icon.svg\"  style=\"height: 60px;\">\n<span style=\"color: red;font-size:3rem;line-height: 2rem;\">💖</span>\n<img src=\"public/app/plugins/datasource/prometheus/img/prometheus_logo.svg\" alt=\"Prometheus logo\" style=\"height: 60px;\">\n</center>",
+            "id": 16,
+            "links": [],
+            "mode": "html",
+            "span": 2,
+            "title": "",
+            "transparent": true,
+            "type": "text"
+          }
+        ],
+        "repeat": null,
+        "repeatIteration": null,
+        "repeatRowId": null,
+        "showTitle": false,
+        "title": "Dashboard Row",
+        "titleSize": "h6"
+      },
+      {
+        "collapse": false,
+        "height": 373,
+        "panels": [
+          {
+            "aliasColors": {
+              "400": "#447EBC",
+              "500": "#BF1B00"
+            },
+            "bars": false,
+            "dashLength": 10,
+            "dashes": false,
+            "datasource": "${DS_PROMETHEUS}",
+            "fill": 1,
+            "height": "",
+            "id": 15,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "null as zero",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [
+              {}
+            ],
+            "spaceLength": 10,
+            "span": 5,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "expr": "sum by (statuscode) (irate(http_request_total{job='grafana'}[5m]))",
+                "format": "time_series",
+                "intervalFactor": 3,
+                "legendFormat": "{{statuscode}}",
+                "refId": "B",
+                "step": 15,
+                "target": "dev.grafana.cb-office.alerting.active_alerts"
+              }
+            ],
+            "thresholds": [],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "http status codes",
+            "tooltip": {
+              "shared": true,
+              "sort": 0,
+              "value_type": "individual"
+            },
+            "type": "graph",
+            "xaxis": {
+              "buckets": null,
+              "mode": "time",
+              "name": null,
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              },
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              }
+            ]
+          },
+          {
+            "aliasColors": {
+              "400": "#447EBC",
+              "500": "#BF1B00"
+            },
+            "bars": false,
+            "dashLength": 10,
+            "dashes": false,
+            "datasource": "${DS_PROMETHEUS}",
+            "fill": 1,
+            "height": "",
+            "id": 11,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "null as zero",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [
+              {}
+            ],
+            "spaceLength": 10,
+            "span": 5,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "expr": "sum(irate(grafana_api_response_status_total[5m]))",
+                "format": "time_series",
+                "intervalFactor": 4,
+                "legendFormat": "api",
+                "refId": "A",
+                "step": 20
+              },
+              {
+                "expr": "sum(irate(grafana_proxy_response_status_total[5m]))",
+                "format": "time_series",
+                "intervalFactor": 4,
+                "legendFormat": "proxy",
+                "refId": "B",
+                "step": 20
+              },
+              {
+                "expr": "sum(irate(grafana_page_response_status_total[5m]))",
+                "format": "time_series",
+                "intervalFactor": 4,
+                "legendFormat": "web",
+                "refId": "C",
+                "step": 20
+              }
+            ],
+            "thresholds": [],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Requests by routing group",
+            "tooltip": {
+              "shared": true,
+              "sort": 0,
+              "value_type": "individual"
+            },
+            "type": "graph",
+            "xaxis": {
+              "buckets": null,
+              "mode": "time",
+              "name": null,
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              },
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              }
+            ]
+          },
+          {
+            "columns": [],
+            "datasource": "${DS_PROMETHEUS}",
+            "fontSize": "100%",
+            "height": "",
+            "id": 12,
+            "links": [],
+            "pageSize": null,
+            "scroll": true,
+            "showHeader": true,
+            "sort": {
+              "col": 0,
+              "desc": true
+            },
+            "span": 2,
+            "styles": [
+              {
+                "alias": "Time",
+                "dateFormat": "YYYY-MM-DD HH:mm:ss",
+                "link": false,
+                "pattern": "Time",
+                "type": "hidden"
+              },
+              {
+                "alias": "",
+                "colorMode": null,
+                "colors": [
+                  "rgba(245, 54, 54, 0.9)",
+                  "rgba(237, 129, 40, 0.89)",
+                  "rgba(50, 172, 45, 0.97)"
+                ],
+                "decimals": 0,
+                "pattern": "/.*/",
+                "thresholds": [],
+                "type": "number",
+                "unit": "short"
+              }
+            ],
+            "targets": [
+              {
+                "expr": "sort(topk(8, sum by (handler) (http_request_total{job=\"grafana\"})))",
+                "format": "time_series",
+                "instant": true,
+                "intervalFactor": 10,
+                "legendFormat": "{{handler}}",
+                "refId": "A",
+                "step": 100
+              }
+            ],
+            "title": "Most used handlers",
+            "transform": "timeseries_to_rows",
+            "type": "table"
+          }
+        ],
+        "repeat": null,
+        "repeatIteration": null,
+        "repeatRowId": null,
+        "showTitle": false,
+        "title": "Dashboard Row",
+        "titleSize": "h6"
+      },
+      {
+        "collapse": false,
+        "height": 188,
+        "panels": [
+          {
+            "aliasColors": {
+              "alerting": "#890F02",
+              "ok": "#7EB26D"
+            },
+            "bars": false,
+            "dashLength": 10,
+            "dashes": false,
+            "datasource": "${DS_PROMETHEUS}",
+            "fill": 1,
+            "id": 6,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "null",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [],
+            "spaceLength": 10,
+            "span": 6,
+            "stack": true,
+            "steppedLine": false,
+            "targets": [
+              {
+                "expr": "increase(grafana_alerting_result_total[1m])",
+                "format": "time_series",
+                "intervalFactor": 3,
+                "legendFormat": "{{state}}",
+                "refId": "A",
+                "step": 15
+              }
+            ],
+            "thresholds": [],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Grafana alert results",
+            "tooltip": {
+              "shared": true,
+              "sort": 0,
+              "value_type": "individual"
+            },
+            "type": "graph",
+            "xaxis": {
+              "buckets": null,
+              "mode": "time",
+              "name": null,
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              },
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              }
+            ]
+          },
+          {
+            "aliasColors": {
+              "alerting": "#890F02",
+              "alertname": "#BF1B00",
+              "firing alerts": "#BF1B00",
+              "ok": "#7EB26D"
+            },
+            "bars": false,
+            "dashLength": 10,
+            "dashes": false,
+            "datasource": "${DS_PROMETHEUS}",
+            "fill": 1,
+            "id": 18,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "null",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [
+              {
+                "alias": "Firing alerts",
+                "yaxis": 1
+              }
+            ],
+            "spaceLength": 10,
+            "span": 6,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "expr": " sum (ALERTS)",
+                "format": "time_series",
+                "intervalFactor": 3,
+                "legendFormat": "firing alerts",
+                "refId": "A",
+                "step": 15
+              }
+            ],
+            "thresholds": [],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Prometheus alerts",
+            "tooltip": {
+              "shared": true,
+              "sort": 0,
+              "value_type": "individual"
+            },
+            "type": "graph",
+            "xaxis": {
+              "buckets": null,
+              "mode": "time",
+              "name": null,
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              },
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              }
+            ]
+          }
+        ],
+        "repeat": null,
+        "repeatIteration": null,
+        "repeatRowId": null,
+        "showTitle": false,
+        "title": "Dashboard Row",
+        "titleSize": "h6"
+      },
+      {
+        "collapse": false,
+        "height": 250,
+        "panels": [
+          {
+            "aliasColors": {},
+            "bars": false,
+            "dashLength": 10,
+            "dashes": false,
+            "datasource": "${DS_PROMETHEUS}",
+            "description": "Aggregated over all Grafana nodes.",
+            "fill": 1,
+            "id": 7,
+            "legend": {
+              "avg": false,
+              "current": false,
+              "max": false,
+              "min": false,
+              "show": true,
+              "total": false,
+              "values": false
+            },
+            "lines": true,
+            "linewidth": 2,
+            "links": [],
+            "nullPointMode": "null",
+            "percentage": false,
+            "pointradius": 5,
+            "points": false,
+            "renderer": "flot",
+            "seriesOverrides": [
+              {
+                "alias": "avg gc duration",
+                "yaxis": 2
+              },
+              {
+                "alias": "127.0.0.1:3000",
+                "yaxis": 1
+              },
+              {
+                "alias": "allocated memory",
+                "yaxis": 2
+              },
+              {
+                "alias": "used memory",
+                "yaxis": 2
+              },
+              {
+                "alias": "memory usage",
+                "yaxis": 2
+              }
+            ],
+            "spaceLength": 10,
+            "span": 12,
+            "stack": false,
+            "steppedLine": false,
+            "targets": [
+              {
+                "expr": "sum(go_goroutines{job=\"grafana\"})",
+                "format": "time_series",
+                "hide": false,
+                "intervalFactor": 4,
+                "legendFormat": "go routines",
+                "refId": "A",
+                "step": 8,
+                "target": "select metric",
+                "type": "timeserie"
+              },
+              {
+                "expr": "sum(process_resident_memory_bytes{job=\"grafana\"})",
+                "format": "time_series",
+                "intervalFactor": 4,
+                "legendFormat": "memory usage",
+                "refId": "B",
+                "step": 8
+              }
+            ],
+            "thresholds": [],
+            "timeFrom": null,
+            "timeShift": null,
+            "title": "Grafana performance",
+            "tooltip": {
+              "shared": true,
+              "sort": 0,
+              "value_type": "individual"
+            },
+            "type": "graph",
+            "xaxis": {
+              "buckets": null,
+              "mode": "time",
+              "name": null,
+              "show": true,
+              "values": []
+            },
+            "yaxes": [
+              {
+                "format": "short",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              },
+              {
+                "format": "decbytes",
+                "label": null,
+                "logBase": 1,
+                "max": null,
+                "min": null,
+                "show": true
+              }
+            ]
+          }
+        ],
+        "repeat": null,
+        "repeatIteration": null,
+        "repeatRowId": null,
+        "showTitle": false,
+        "title": "Dashboard Row",
+        "titleSize": "h6"
+      }
+    ],
+    "schemaVersion": 14,
+    "style": "dark",
+    
+    "templating": {
+      "list": []
+    },
+    "time": {
+      "from": "now-6h",
+      "to": "now"
+    },
+    "timepicker": {
+      "refresh_intervals": [
+        "5s",
+        "10s",
+        "30s",
+        "1m",
+        "5m",
+        "15m",
+        "30m",
+        "1h",
+        "2h",
+        "1d"
+      ],
+      "time_options": [
+        "5m",
+        "15m",
+        "1h",
+        "6h",
+        "12h",
+        "24h",
+        "2d",
+        "7d",
+        "30d"
+      ]
+    },
+    "timezone": ""
+  }

+ 4 - 7
public/app/plugins/datasource/prometheus/datasource.ts

@@ -1,5 +1,3 @@
-///<reference path="../../../headers/common.d.ts" />
-
 import _ from 'lodash';
 import _ from 'lodash';
 
 
 import kbn from 'app/core/utils/kbn';
 import kbn from 'app/core/utils/kbn';
@@ -122,7 +120,7 @@ export class PrometheusDatasource {
         } else {
         } else {
           for (let metricData of response.data.data.result) {
           for (let metricData of response.data.data.result) {
             if (response.data.data.resultType === 'matrix') {
             if (response.data.data.resultType === 'matrix') {
-              result.push(self.transformMetricData(metricData, activeTargets[index], start, end));
+              result.push(self.transformMetricData(metricData, activeTargets[index], start, end, queries[index].step));
             } else if (response.data.data.resultType === 'vector') {
             } else if (response.data.data.resultType === 'vector') {
               result.push(self.transformInstantMetricData(metricData, activeTargets[index]));
               result.push(self.transformInstantMetricData(metricData, activeTargets[index]));
             }
             }
@@ -144,7 +142,6 @@ export class PrometheusDatasource {
     var intervalFactor = target.intervalFactor || 1;
     var intervalFactor = target.intervalFactor || 1;
     // Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
     // Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
     var adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
     var adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
-
     var scopedVars = options.scopedVars;
     var scopedVars = options.scopedVars;
     // If the interval was adjusted, make a shallow copy of scopedVars with updated interval vars
     // If the interval was adjusted, make a shallow copy of scopedVars with updated interval vars
     if (interval !== adjustedInterval) {
     if (interval !== adjustedInterval) {
@@ -154,7 +151,7 @@ export class PrometheusDatasource {
         "__interval_ms":  {text: interval * 1000, value: interval * 1000},
         "__interval_ms":  {text: interval * 1000, value: interval * 1000},
       });
       });
     }
     }
-    target.step = query.step = interval;
+    query.step = interval;
 
 
     // Only replace vars in expression after having (possibly) updated interval vars
     // Only replace vars in expression after having (possibly) updated interval vars
     query.expr = this.templateSrv.replace(target.expr, scopedVars, this.interpolateQueryExpr);
     query.expr = this.templateSrv.replace(target.expr, scopedVars, this.interpolateQueryExpr);
@@ -272,13 +269,13 @@ export class PrometheusDatasource {
     });
     });
   }
   }
 
 
-  transformMetricData(md, options, start, end) {
+  transformMetricData(md, options, start, end, step) {
     var dps = [],
     var dps = [],
       metricLabel = null;
       metricLabel = null;
 
 
     metricLabel = this.createMetricLabel(md.metric, options);
     metricLabel = this.createMetricLabel(md.metric, options);
 
 
-    var stepMs = parseInt(options.step) * 1000;
+    var stepMs = step * 1000;
     var baseTimestamp = start * 1000;
     var baseTimestamp = start * 1000;
     for (let value of md.values) {
     for (let value of md.values) {
       var dp_value = parseFloat(value[1]);
       var dp_value = parseFloat(value[1]);

+ 2 - 1
public/app/plugins/datasource/prometheus/plugin.json

@@ -4,7 +4,8 @@
   "id": "prometheus",
   "id": "prometheus",
 
 
   "includes": [
   "includes": [
-    {"type": "dashboard", "name": "Prometheus Stats", "path": "dashboards/prometheus_stats.json"}
+    {"type": "dashboard", "name": "Prometheus Stats", "path": "dashboards/prometheus_stats.json"},
+    {"type": "dashboard", "name": "Grafana Stats", "path": "dashboards/grafana_stats.json"}
   ],
   ],
 
 
   "metrics": true,
   "metrics": true,

+ 1 - 1
public/app/plugins/panel/singlestat/module.ts

@@ -66,7 +66,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     thresholds: '',
     thresholds: '',
     colorBackground: false,
     colorBackground: false,
     colorValue: false,
     colorValue: false,
-    colors: ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
+    colors: ["#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a"],
     sparkline: {
     sparkline: {
       show: false,
       show: false,
       full: false,
       full: false,

+ 5 - 2
public/vendor/flot/jquery.flot.js

@@ -2962,8 +2962,11 @@ Licensed under the MIT license.
         }
         }
 
 
         function onClick(e) {
         function onClick(e) {
-            triggerClickHoverEvent("plotclick", e,
-                                   function (s) { return s["clickable"] != false; });
+          if (plot.isSelecting) {
+            return;
+          }
+
+          triggerClickHoverEvent("plotclick", e, function (s) { return s["clickable"] != false; });
         }
         }
 
 
         // trigger click or hover event (they send the same parameters
         // trigger click or hover event (they send the same parameters

+ 5 - 0
public/vendor/flot/jquery.flot.selection.js

@@ -152,6 +152,10 @@ The plugin allso adds the following methods to the plot object:
                 plot.getPlaceholder().trigger("plotselecting", [ null ]);
                 plot.getPlaceholder().trigger("plotselecting", [ null ]);
             }
             }
 
 
+            setTimeout(function() {
+              plot.isSelecting = false;
+            }, 10);
+
             return false;
             return false;
         }
         }
 
 
@@ -218,6 +222,7 @@ The plugin allso adds the following methods to the plot object:
 
 
             setSelectionPos(selection.second, pos);
             setSelectionPos(selection.second, pos);
             if (selectionIsSane()) {
             if (selectionIsSane()) {
+                plot.isSelecting = true;
                 selection.show = true;
                 selection.show = true;
                 plot.triggerRedrawOverlay();
                 plot.triggerRedrawOverlay();
             }
             }

+ 0 - 3
vendor/github.com/streadway/amqp/.gitignore

@@ -1,3 +0,0 @@
-spec/spec
-examples/simple-consumer/simple-consumer
-examples/simple-producer/simple-producer

+ 0 - 13
vendor/github.com/streadway/amqp/.travis.yml

@@ -1,13 +0,0 @@
-language: go
-
-go:
-  - 1.1
-  - tip
-
-services:
-  - rabbitmq
-
-env:
- - AMQP_URL=amqp://guest:guest@127.0.0.1:5672/ GOMAXPROCS=2
-
-script: go test -tags integration ./...

+ 0 - 23
vendor/github.com/streadway/amqp/LICENSE

@@ -1,23 +0,0 @@
-Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer.
-
-Redistributions in binary form must reproduce the above copyright notice, this
-list of conditions and the following disclaimer in the documentation and/or
-other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 76
vendor/github.com/streadway/amqp/README.md

@@ -1,76 +0,0 @@
-# AMQP
-
-AMQP 0.9.1 client with RabbitMQ extensions in Go.
-
-# Status
-
-*Beta*
-
-[![Build Status](https://secure.travis-ci.org/streadway/amqp.png)](http://travis-ci.org/streadway/amqp)
-
-API changes unlikely and will be discussed on [Github
-issues](https://github.com/streadway/amqp/issues) along with any bugs or
-enhancements.
-
-# Goals
-
-Provide an functional interface that closely represents the AMQP 0.9.1 model
-targeted to RabbitMQ as a server.  This includes the minimum necessary to
-interact the semantics of the protocol.
-
-# Non-goals
-
-Things not intended to be supported.
-
-  * Auto reconnect and re-synchronization of client and server topologies.
-    * Reconnection would require understanding the error paths when the
-      topology cannot be declared on reconnect.  This would require a new set
-      of types and code paths that are best suited at the call-site of this
-      package.  AMQP has a dynamic topology that needs all peers to agree. If
-      this doesn't happen, the behavior is undefined.  Instead of producing a
-      possible interface with undefined behavior, this package is designed to
-      be simple for the caller to implement the necessary connection-time
-      topology declaration so that reconnection is trivial and encapsulated in
-      the caller's application code.
-  * AMQP Protocol negotiation for forward or backward compatibility.
-    * 0.9.1 is stable and widely deployed.  Versions 0.10 and 1.0 are divergent
-      specifications that change the semantics and wire format of the protocol.
-      We will accept patches for other protocol support but have no plans for
-      implementation ourselves.
-  * Anything other than PLAIN and EXTERNAL authentication mechanisms.
-    * Keeping the mechanisms interface modular makes it possible to extend
-      outside of this package.  If other mechanisms prove to be popular, then
-      we would accept patches to include them in this pacakge.
-
-# Usage
-
-See the 'examples' subdirectory for simple producers and consumers executables.
-If you have a use-case in mind which isn't well-represented by the examples,
-please file an issue.
-
-# Documentation
-
-Use [Godoc documentation](http://godoc.org/github.com/streadway/amqp) for
-reference and usage.
-
-[RabbitMQ tutorials in
-Go](https://github.com/rabbitmq/rabbitmq-tutorials/tree/master/go) are also
-available.
-
-# Contributing
-
-Pull requests are very much welcomed.  Create your pull request on a non-master
-branch, make sure a test or example is included that covers your change and
-your commits represent coherent changes that include a reason for the change.
-
-To run the integration tests, make sure you have RabbitMQ running on any host,
-export the environment variable `AMQP_URL=amqp://host/` and run `go test -tags
-integration`.  TravisCI will also run the integration tests.
-
-Thanks to the [community of contributors](https://github.com/streadway/amqp/graphs/contributors).
-
-# License
-
-BSD 2 clause - see LICENSE for more details.
-
-

+ 0 - 106
vendor/github.com/streadway/amqp/allocator.go

@@ -1,106 +0,0 @@
-package amqp
-
-import (
-	"bytes"
-	"fmt"
-	"math/big"
-)
-
-const (
-	free      = 0
-	allocated = 1
-)
-
-// allocator maintains a bitset of allocated numbers.
-type allocator struct {
-	pool *big.Int
-	last int
-	low  int
-	high int
-}
-
-// NewAllocator reserves and frees integers out of a range between low and
-// high.
-//
-// O(N) worst case space used, where N is maximum allocated, divided by
-// sizeof(big.Word)
-func newAllocator(low, high int) *allocator {
-	return &allocator{
-		pool: big.NewInt(0),
-		last: low,
-		low:  low,
-		high: high,
-	}
-}
-
-// String returns a string describing the contents of the allocator like
-// "allocator[low..high] reserved..until"
-//
-// O(N) where N is high-low
-func (a allocator) String() string {
-	b := &bytes.Buffer{}
-	fmt.Fprintf(b, "allocator[%d..%d]", a.low, a.high)
-
-	for low := a.low; low <= a.high; low++ {
-		high := low
-		for a.reserved(high) && high <= a.high {
-			high++
-		}
-
-		if high > low+1 {
-			fmt.Fprintf(b, " %d..%d", low, high-1)
-		} else if high > low {
-			fmt.Fprintf(b, " %d", high-1)
-		}
-
-		low = high
-	}
-	return b.String()
-}
-
-// Next reserves and returns the next available number out of the range between
-// low and high.  If no number is available, false is returned.
-//
-// O(N) worst case runtime where N is allocated, but usually O(1) due to a
-// rolling index into the oldest allocation.
-func (a *allocator) next() (int, bool) {
-	wrapped := a.last
-
-	// Find trailing bit
-	for ; a.last <= a.high; a.last++ {
-		if a.reserve(a.last) {
-			return a.last, true
-		}
-	}
-
-	// Find preceeding free'd pool
-	a.last = a.low
-
-	for ; a.last < wrapped; a.last++ {
-		if a.reserve(a.last) {
-			return a.last, true
-		}
-	}
-
-	return 0, false
-}
-
-// reserve claims the bit if it is not already claimed, returning true if
-// succesfully claimed.
-func (a *allocator) reserve(n int) bool {
-	if a.reserved(n) {
-		return false
-	}
-	a.pool.SetBit(a.pool, n-a.low, allocated)
-	return true
-}
-
-// reserved returns true if the integer has been allocated
-func (a *allocator) reserved(n int) bool {
-	return a.pool.Bit(n-a.low) == allocated
-}
-
-// release frees the use of the number for another allocation
-func (a *allocator) release(n int) {
-	a.pool.SetBit(a.pool, n-a.low, free)
-}

+ 0 - 90
vendor/github.com/streadway/amqp/allocator_test.go

@@ -1,90 +0,0 @@
-package amqp
-
-import (
-	"math/rand"
-	"testing"
-)
-
-func TestAllocatorFirstShouldBeTheLow(t *testing.T) {
-	n, ok := newAllocator(1, 2).next()
-	if !ok {
-		t.Fatalf("expected to allocate between 1 and 2")
-	}
-
-	if want, got := 1, n; want != got {
-		t.Fatalf("expected to first allocation to be 1")
-	}
-}
-
-func TestAllocatorShouldBeBoundByHigh(t *testing.T) {
-	a := newAllocator(1, 2)
-
-	if n, ok := a.next(); n != 1 || !ok {
-		t.Fatalf("expected to allocate between 1 and 2, got %d, %v", n, ok)
-	}
-	if n, ok := a.next(); n != 2 || !ok {
-		t.Fatalf("expected to allocate between 1 and 2, got %d, %v", n, ok)
-	}
-	if _, ok := a.next(); ok {
-		t.Fatalf("expected not to allocate outside of 1 and 2")
-	}
-}
-
-func TestAllocatorStringShouldIncludeAllocatedRanges(t *testing.T) {
-	a := newAllocator(1, 10)
-	a.reserve(1)
-	a.reserve(2)
-	a.reserve(3)
-	a.reserve(5)
-	a.reserve(6)
-	a.reserve(8)
-	a.reserve(10)
-
-	if want, got := "allocator[1..10] 1..3 5..6 8 10", a.String(); want != got {
-		t.Fatalf("expected String of %q, got %q", want, got)
-	}
-}
-
-func TestAllocatorShouldReuseReleased(t *testing.T) {
-	a := newAllocator(1, 2)
-
-	first, _ := a.next()
-	if want, got := 1, first; want != got {
-		t.Fatalf("expected allocation to be %d, got: %d", want, got)
-	}
-
-	second, _ := a.next()
-	if want, got := 2, second; want != got {
-		t.Fatalf("expected allocation to be %d, got: %d", want, got)
-	}
-
-	a.release(first)
-
-	third, _ := a.next()
-	if want, got := first, third; want != got {
-		t.Fatalf("expected third allocation to be %d, got: %d", want, got)
-	}
-
-	_, ok := a.next()
-	if want, got := false, ok; want != got {
-		t.Fatalf("expected fourth allocation to saturate the pool")
-	}
-}
-
-func TestAllocatorReleasesKeepUpWithAllocationsForAllSizes(t *testing.T) {
-	const runs = 5
-	const max = 13
-
-	for lim := 1; lim < 2<<max; lim <<= 1 {
-		a := newAllocator(0, lim)
-
-		for i := 0; i < runs*lim; i++ {
-			if i >= lim { // fills the allocator
-				a.release(int(rand.Int63n(int64(lim))))
-			}
-			if _, ok := a.next(); !ok {
-				t.Fatalf("expected %d runs of random release of size %d not to fail on allocation %d", runs, lim, i)
-			}
-		}
-	}
-}

+ 0 - 44
vendor/github.com/streadway/amqp/auth.go

@@ -1,44 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"fmt"
-)
-
-// Authentication interface provides a means for different SASL authentication
-// mechanisms to be used during connection tuning.
-type Authentication interface {
-	Mechanism() string
-	Response() string
-}
-
-// PlainAuth is a similar to Basic Auth in HTTP.
-type PlainAuth struct {
-	Username string
-	Password string
-}
-
-func (me *PlainAuth) Mechanism() string {
-	return "PLAIN"
-}
-
-func (me *PlainAuth) Response() string {
-	return fmt.Sprintf("\000%s\000%s", me.Username, me.Password)
-}
-
-// Finds the first mechanism preferred by the client that the server supports.
-func pickSASLMechanism(client []Authentication, serverMechanisms []string) (auth Authentication, ok bool) {
-	for _, auth = range client {
-		for _, mech := range serverMechanisms {
-			if auth.Mechanism() == mech {
-				return auth, true
-			}
-		}
-	}
-
-	return
-}

+ 0 - 159
vendor/github.com/streadway/amqp/certs.sh

@@ -1,159 +0,0 @@
-#!/bin/sh
-#
-# Creates the CA, server and client certs to be used by tls_test.go
-# http://www.rabbitmq.com/ssl.html
-#
-# Copy stdout into the const section of tls_test.go or use for RabbitMQ
-#
-root=$PWD/certs
-
-if [ -f $root/ca/serial ]; then
-  echo >&2 "Previous installation found"
-  echo >&2 "Remove $root/ca and rerun to overwrite"
-  exit 1
-fi
-
-mkdir -p $root/ca/private
-mkdir -p $root/ca/certs
-mkdir -p $root/server
-mkdir -p $root/client
-
-cd $root/ca
-
-chmod 700 private
-touch index.txt
-echo 'unique_subject = no' > index.txt.attr
-echo '01' > serial
-echo >openssl.cnf '
-[ ca ]
-default_ca = testca
-
-[ testca ]
-dir = .
-certificate = $dir/cacert.pem
-database = $dir/index.txt
-new_certs_dir = $dir/certs
-private_key = $dir/private/cakey.pem
-serial = $dir/serial
-
-default_crl_days = 7
-default_days = 3650
-default_md = sha1
-
-policy = testca_policy
-x509_extensions = certificate_extensions
-
-[ testca_policy ]
-commonName = supplied
-stateOrProvinceName = optional
-countryName = optional
-emailAddress = optional
-organizationName = optional
-organizationalUnitName = optional
-
-[ certificate_extensions ]
-basicConstraints = CA:false
-
-[ req ]
-default_bits = 2048
-default_keyfile = ./private/cakey.pem
-default_md = sha1
-prompt = yes
-distinguished_name = root_ca_distinguished_name
-x509_extensions = root_ca_extensions
-
-[ root_ca_distinguished_name ]
-commonName = hostname
-
-[ root_ca_extensions ]
-basicConstraints = CA:true
-keyUsage = keyCertSign, cRLSign
-
-[ client_ca_extensions ]
-basicConstraints = CA:false
-keyUsage = digitalSignature
-extendedKeyUsage = 1.3.6.1.5.5.7.3.2
-
-[ server_ca_extensions ]
-basicConstraints = CA:false
-keyUsage = keyEncipherment
-extendedKeyUsage = 1.3.6.1.5.5.7.3.1
-subjectAltName = @alt_names
-
-[ alt_names ]
-IP.1 = 127.0.0.1
-'
-
-openssl req \
-  -x509 \
-  -nodes \
-  -config openssl.cnf \
-  -newkey rsa:2048 \
-  -days 3650 \
-  -subj "/CN=MyTestCA/" \
-  -out cacert.pem \
-  -outform PEM
-
-openssl x509 \
-  -in cacert.pem \
-  -out cacert.cer \
-  -outform DER
-
-openssl genrsa -out $root/server/key.pem 2048
-openssl genrsa -out $root/client/key.pem 2048
-
-openssl req \
-  -new \
-  -nodes \
-  -config openssl.cnf \
-  -subj "/CN=127.0.0.1/O=server/" \
-  -key $root/server/key.pem \
-  -out $root/server/req.pem \
-  -outform PEM
-
-openssl req \
-  -new \
-  -nodes \
-  -config openssl.cnf \
-  -subj "/CN=127.0.0.1/O=client/" \
-  -key $root/client/key.pem \
-  -out $root/client/req.pem \
-  -outform PEM
-
-openssl ca \
-  -config openssl.cnf \
-  -in $root/server/req.pem \
-  -out $root/server/cert.pem \
-  -notext \
-  -batch \
-  -extensions server_ca_extensions
-
-openssl ca \
-  -config openssl.cnf \
-  -in $root/client/req.pem \
-  -out $root/client/cert.pem \
-  -notext \
-  -batch \
-  -extensions client_ca_extensions
-
-cat <<-END
-const caCert = \`
-`cat $root/ca/cacert.pem`
-\`
-
-const serverCert = \`
-`cat $root/server/cert.pem`
-\`
-
-const serverKey = \`
-`cat $root/server/key.pem`
-\`
-
-const clientCert = \`
-`cat $root/client/cert.pem`
-\`
-
-const clientKey = \`
-`cat $root/client/key.pem`
-\`
-END

+ 0 - 1589
vendor/github.com/streadway/amqp/channel.go

@@ -1,1589 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"container/heap"
-	"reflect"
-	"sync"
-)
-
-// 0      1         3             7                  size+7 size+8
-// +------+---------+-------------+  +------------+  +-----------+
-// | type | channel |     size    |  |  payload   |  | frame-end |
-// +------+---------+-------------+  +------------+  +-----------+
-//  octet   short         long         size octets       octet
-const frameHeaderSize = 1 + 2 + 4 + 1
-
-/*
-Channel represents an AMQP channel. Used as a context for valid message
-exchange.  Errors on methods with this Channel as a receiver means this channel
-should be discarded and a new channel established.
-
-*/
-type Channel struct {
-	destructor sync.Once
-	sendM      sync.Mutex // sequence channel frames
-	m          sync.Mutex // struct field mutex
-
-	connection *Connection
-
-	rpc       chan message
-	consumers *consumers
-
-	id uint16
-
-	// true when we will never notify again
-	noNotify bool
-
-	// Channel and Connection exceptions will be broadcast on these listeners.
-	closes []chan *Error
-
-	// Listeners for active=true flow control.  When true is sent to a listener,
-	// publishing should pause until false is sent to listeners.
-	flows []chan bool
-
-	// Listeners for returned publishings for unroutable messages on mandatory
-	// publishings or undeliverable messages on immediate publishings.
-	returns []chan Return
-
-	// Listeners for when the server notifies the client that
-	// a consumer has been cancelled.
-	cancels []chan string
-
-	// Listeners for Acks/Nacks when the channel is in Confirm mode
-	// the value is the sequentially increasing delivery tag
-	// starting at 1 immediately after the Confirm
-	acks  []chan uint64
-	nacks []chan uint64
-
-	// When in confirm mode, track publish counter and order confirms
-	confirms       tagSet
-	publishCounter uint64
-
-	// Selects on any errors from shutdown during RPC
-	errors chan *Error
-
-	// State machine that manages frame order, must only be mutated by the connection
-	recv func(*Channel, frame) error
-
-	// State that manages the send behavior after before and after shutdown, must
-	// only be mutated in shutdown()
-	send func(*Channel, message) error
-
-	// Current state for frame re-assembly, only mutated from recv
-	message messageWithContent
-	header  *headerFrame
-	body    []byte
-}
-
-// Constructs a new channel with the given framing rules
-func newChannel(c *Connection, id uint16) *Channel {
-	return &Channel{
-		connection: c,
-		id:         id,
-		rpc:        make(chan message),
-		consumers:  makeConsumers(),
-		recv:       (*Channel).recvMethod,
-		send:       (*Channel).sendOpen,
-		errors:     make(chan *Error, 1),
-	}
-}
-
-// shutdown is called by Connection after the channel has been removed from the
-// connection registry.
-func (me *Channel) shutdown(e *Error) {
-	me.destructor.Do(func() {
-		me.m.Lock()
-		defer me.m.Unlock()
-
-		// Broadcast abnormal shutdown
-		if e != nil {
-			for _, c := range me.closes {
-				c <- e
-			}
-		}
-
-		me.send = (*Channel).sendClosed
-
-		// Notify RPC if we're selecting
-		if e != nil {
-			me.errors <- e
-		}
-
-		me.consumers.closeAll()
-
-		for _, c := range me.closes {
-			close(c)
-		}
-
-		for _, c := range me.flows {
-			close(c)
-		}
-
-		for _, c := range me.returns {
-			close(c)
-		}
-
-		for _, c := range me.cancels {
-			close(c)
-		}
-
-		// A seen map to keep from double closing the ack and nacks. the other
-		// channels are different types and are not shared
-		seen := make(map[chan uint64]bool)
-
-		for _, c := range me.acks {
-			if !seen[c] {
-				close(c)
-				seen[c] = true
-			}
-		}
-
-		for _, c := range me.nacks {
-			if !seen[c] {
-				close(c)
-				seen[c] = true
-			}
-		}
-
-		me.noNotify = true
-	})
-}
-
-func (me *Channel) open() error {
-	return me.call(&channelOpen{}, &channelOpenOk{})
-}
-
-// Performs a request/response call for when the message is not NoWait and is
-// specified as Synchronous.
-func (me *Channel) call(req message, res ...message) error {
-	if err := me.send(me, req); err != nil {
-		return err
-	}
-
-	if req.wait() {
-		select {
-		case e := <-me.errors:
-			return e
-
-		case msg := <-me.rpc:
-			if msg != nil {
-				for _, try := range res {
-					if reflect.TypeOf(msg) == reflect.TypeOf(try) {
-						// *res = *msg
-						vres := reflect.ValueOf(try).Elem()
-						vmsg := reflect.ValueOf(msg).Elem()
-						vres.Set(vmsg)
-						return nil
-					}
-				}
-				return ErrCommandInvalid
-			} else {
-				// RPC channel has been closed without an error, likely due to a hard
-				// error on the Connection.  This indicates we have already been
-				// shutdown and if were waiting, will have returned from the errors chan.
-				return ErrClosed
-			}
-		}
-	}
-
-	return nil
-}
-
-func (me *Channel) sendClosed(msg message) (err error) {
-	me.sendM.Lock()
-	defer me.sendM.Unlock()
-
-	// After a 'channel.close' is sent or received the only valid response is
-	// channel.close-ok
-	if _, ok := msg.(*channelCloseOk); ok {
-		return me.connection.send(&methodFrame{
-			ChannelId: me.id,
-			Method:    msg,
-		})
-	}
-
-	return ErrClosed
-}
-
-func (me *Channel) sendOpen(msg message) (err error) {
-	me.sendM.Lock()
-	defer me.sendM.Unlock()
-
-	if content, ok := msg.(messageWithContent); ok {
-		props, body := content.getContent()
-		class, _ := content.id()
-		size := me.connection.Config.FrameSize - frameHeaderSize
-
-		if err = me.connection.send(&methodFrame{
-			ChannelId: me.id,
-			Method:    content,
-		}); err != nil {
-			return
-		}
-
-		if err = me.connection.send(&headerFrame{
-			ChannelId:  me.id,
-			ClassId:    class,
-			Size:       uint64(len(body)),
-			Properties: props,
-		}); err != nil {
-			return
-		}
-
-		for i, j := 0, size; i < len(body); i, j = j, j+size {
-			if j > len(body) {
-				j = len(body)
-			}
-
-			if err = me.connection.send(&bodyFrame{
-				ChannelId: me.id,
-				Body:      body[i:j],
-			}); err != nil {
-				return
-			}
-		}
-	} else {
-		err = me.connection.send(&methodFrame{
-			ChannelId: me.id,
-			Method:    msg,
-		})
-	}
-
-	return
-}
-
-// Eventually called via the state machine from the connection's reader
-// goroutine, so assumes serialized access.
-func (me *Channel) dispatch(msg message) {
-	switch m := msg.(type) {
-	case *channelClose:
-		me.connection.closeChannel(me, newError(m.ReplyCode, m.ReplyText))
-		me.send(me, &channelCloseOk{})
-
-	case *channelFlow:
-		for _, c := range me.flows {
-			c <- m.Active
-		}
-		me.send(me, &channelFlowOk{Active: m.Active})
-
-	case *basicCancel:
-		for _, c := range me.cancels {
-			c <- m.ConsumerTag
-		}
-		me.send(me, &basicCancelOk{ConsumerTag: m.ConsumerTag})
-
-	case *basicReturn:
-		ret := newReturn(*m)
-		for _, c := range me.returns {
-			c <- *ret
-		}
-
-	case *basicAck:
-		if m.Multiple {
-			me.confimMultiple(m.DeliveryTag, me.acks)
-		} else {
-			me.confimOne(m.DeliveryTag, me.acks)
-		}
-
-	case *basicNack:
-		if m.Multiple {
-			me.confimMultiple(m.DeliveryTag, me.nacks)
-		} else {
-			me.confimOne(m.DeliveryTag, me.nacks)
-		}
-
-	case *basicDeliver:
-		me.consumers.send(m.ConsumerTag, newDelivery(me, m))
-		// TODO log failed consumer and close channel, this can happen when
-		// deliveries are in flight and a no-wait cancel has happened
-
-	default:
-		me.rpc <- msg
-	}
-}
-
-func (me *Channel) transition(f func(*Channel, frame) error) error {
-	me.recv = f
-	return nil
-}
-
-func (me *Channel) recvMethod(f frame) error {
-	switch frame := f.(type) {
-	case *methodFrame:
-		if msg, ok := frame.Method.(messageWithContent); ok {
-			me.body = make([]byte, 0)
-			me.message = msg
-			return me.transition((*Channel).recvHeader)
-		}
-
-		me.dispatch(frame.Method) // termination state
-		return me.transition((*Channel).recvMethod)
-
-	case *headerFrame:
-		// drop
-		return me.transition((*Channel).recvMethod)
-
-	case *bodyFrame:
-		// drop
-		return me.transition((*Channel).recvMethod)
-
-	default:
-		panic("unexpected frame type")
-	}
-
-	panic("unreachable")
-}
-
-func (me *Channel) recvHeader(f frame) error {
-	switch frame := f.(type) {
-	case *methodFrame:
-		// interrupt content and handle method
-		return me.recvMethod(f)
-
-	case *headerFrame:
-		// start collecting if we expect body frames
-		me.header = frame
-
-		if frame.Size == 0 {
-			me.message.setContent(me.header.Properties, me.body)
-			me.dispatch(me.message) // termination state
-			return me.transition((*Channel).recvMethod)
-		} else {
-			return me.transition((*Channel).recvContent)
-		}
-
-	case *bodyFrame:
-		// drop and reset
-		return me.transition((*Channel).recvMethod)
-
-	default:
-		panic("unexpected frame type")
-	}
-
-	panic("unreachable")
-}
-
-// state after method + header and before the length
-// defined by the header has been reached
-func (me *Channel) recvContent(f frame) error {
-	switch frame := f.(type) {
-	case *methodFrame:
-		// interrupt content and handle method
-		return me.recvMethod(f)
-
-	case *headerFrame:
-		// drop and reset
-		return me.transition((*Channel).recvMethod)
-
-	case *bodyFrame:
-		me.body = append(me.body, frame.Body...)
-
-		if uint64(len(me.body)) >= me.header.Size {
-			me.message.setContent(me.header.Properties, me.body)
-			me.dispatch(me.message) // termination state
-			return me.transition((*Channel).recvMethod)
-		}
-
-		return me.transition((*Channel).recvContent)
-
-	default:
-		panic("unexpected frame type")
-	}
-
-	panic("unreachable")
-}
-
-/*
-Close initiate a clean channel closure by sending a close message with the error
-code set to '200'.
-
-It is safe to call this method multiple times.
-
-*/
-func (me *Channel) Close() error {
-	defer me.connection.closeChannel(me, nil)
-	return me.call(
-		&channelClose{ReplyCode: replySuccess},
-		&channelCloseOk{},
-	)
-}
-
-/*
-NotifyClose registers a listener for when the server sends a channel or
-connection exception in the form of a Connection.Close or Channel.Close method.
-Connection exceptions will be broadcast to all open channels and all channels
-will be closed, where channel exceptions will only be broadcast to listeners to
-this channel.
-
-The chan provided will be closed when the Channel is closed and on a
-graceful close, no error will be sent.
-
-*/
-func (me *Channel) NotifyClose(c chan *Error) chan *Error {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.noNotify {
-		close(c)
-	} else {
-		me.closes = append(me.closes, c)
-	}
-
-	return c
-}
-
-/*
-NotifyFlow registers a listener for basic.flow methods sent by the server.
-When `true` is sent on one of the listener channels, all publishers should
-pause until a `false` is sent.
-
-The server may ask the producer to pause or restart the flow of Publishings
-sent by on a channel. This is a simple flow-control mechanism that a server can
-use to avoid overflowing its queues or otherwise finding itself receiving more
-messages than it can process. Note that this method is not intended for window
-control. It does not affect contents returned by basic.get-ok methods.
-
-When a new channel is opened, it is active (flow is active). Some
-applications assume that channels are inactive until started. To emulate
-this behavior a client MAY open the channel, then pause it.
-
-Publishers should respond to a flow messages as rapidly as possible and the
-server may disconnect over producing channels that do not respect these
-messages.
-
-basic.flow-ok methods will always be returned to the server regardless of
-the number of listeners there are.
-
-To control the flow of deliveries from the server.  Use the Channel.Flow()
-method instead.
-
-Note: RabbitMQ will rather use TCP pushback on the network connection instead
-of sending basic.flow.  This means that if a single channel is producing too
-much on the same connection, all channels using that connection will suffer,
-including acknowledgments from deliveries.  Use different Connections if you
-desire to interleave consumers and producers in the same process to avoid your
-basic.ack messages from getting rate limited with your basic.publish messages.
-
-*/
-func (me *Channel) NotifyFlow(c chan bool) chan bool {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.noNotify {
-		close(c)
-	} else {
-		me.flows = append(me.flows, c)
-	}
-
-	return c
-}
-
-/*
-NotifyReturn registers a listener for basic.return methods.  These can be sent
-from the server when a publish is undeliverable either from the mandatory or
-immediate flags.
-
-A return struct has a copy of the Publishing along with some error
-information about why the publishing failed.
-
-*/
-func (me *Channel) NotifyReturn(c chan Return) chan Return {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.noNotify {
-		close(c)
-	} else {
-		me.returns = append(me.returns, c)
-	}
-
-	return c
-}
-
-/*
-NotifyCancel registers a listener for basic.cancel methods.  These can be sent
-from the server when a queue is deleted or when consuming from a mirrored queue
-where the master has just failed (and was moved to another node)
-
-The subscription tag is returned to the listener.
-
-*/
-func (me *Channel) NotifyCancel(c chan string) chan string {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.noNotify {
-		close(c)
-	} else {
-		me.cancels = append(me.cancels, c)
-	}
-
-	return c
-}
-
-/*
-NotifyConfirm registers a listener chan for reliable publishing to receive
-basic.ack and basic.nack messages.  These messages will be sent by the server
-for every publish after Channel.Confirm has been called.  The value sent on
-these channels is the sequence number of the publishing.  It is up to client of
-this channel to maintain the sequence number of each publishing and handle
-resends on basic.nack.
-
-There will be either at most one Ack or Nack delivered for every Publishing.
-
-Acknowledgments will be received in the order of delivery from the
-NotifyConfirm channels even if the server acknowledges them out of order.
-
-The capacity of the ack and nack channels must be at least as large as the
-number of outstanding publishings.  Not having enough buffered chans will
-create a deadlock if you attempt to perform other operations on the Connection
-or Channel while confirms are in-flight.
-
-It's advisable to wait for all acks or nacks to arrive before calling
-Channel.Close().
-
-*/
-func (me *Channel) NotifyConfirm(ack, nack chan uint64) (chan uint64, chan uint64) {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.noNotify {
-		close(ack)
-		close(nack)
-	} else {
-		me.acks = append(me.acks, ack)
-		me.nacks = append(me.nacks, nack)
-	}
-
-	return ack, nack
-}
-
-// Since the acknowledgments may come out of order, scan the heap
-// until found.  In most cases, only the head will be found.
-func (me *Channel) confimOne(tag uint64, ch []chan uint64) {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.confirms != nil {
-		var unacked []uint64
-
-		for {
-			// We expect once and only once delivery
-			next := heap.Pop(&me.confirms).(uint64)
-
-			if next != tag {
-				unacked = append(unacked, next)
-			} else {
-				for _, c := range ch {
-					c <- tag
-				}
-				break
-			}
-		}
-
-		for _, pending := range unacked {
-			heap.Push(&me.confirms, pending)
-		}
-	}
-}
-
-// Instead of pushing the pending acknowledgments, deliver them as we should ack
-// all up until this tag.
-func (me *Channel) confimMultiple(tag uint64, ch []chan uint64) {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.confirms != nil {
-		for {
-			// We expect once and only once delivery
-			next := heap.Pop(&me.confirms).(uint64)
-
-			for _, c := range ch {
-				c <- next
-			}
-
-			if next == tag {
-				break
-			}
-		}
-	}
-}
-
-/*
-Qos controls how many messages or how many bytes the server will try to keep on
-the network for consumers before receiving delivery acks.  The intent of Qos is
-to make sure the network buffers stay full between the server and client.
-
-With a prefetch count greater than zero, the server will deliver that many
-messages to consumers before acknowledgments are received.  The server ignores
-this option when consumers are started with noAck because no acknowledgments
-are expected or sent.
-
-With a prefetch size greater than zero, the server will try to keep at least
-that many bytes of deliveries flushed to the network before receiving
-acknowledgments from the consumers.  This option is ignored when consumers are
-started with noAck.
-
-When global is true, these Qos settings apply to all existing and future
-consumers on all channels on the same connection.  When false, the Channel.Qos
-settings will apply to all existing and future consumers on this channel.
-RabbitMQ does not implement the global flag.
-
-To get round-robin behavior between consumers consuming from the same queue on
-different connections, set the prefetch count to 1, and the next available
-message on the server will be delivered to the next available consumer.
-
-If your consumer work time is reasonably is consistent and not much greater
-than two times your network round trip time, you will see significant
-throughput improvements starting with a prefetch count of 2 or slightly
-greater as described by benchmarks on RabbitMQ.
-
-http://www.rabbitmq.com/blog/2012/04/25/rabbitmq-performance-measurements-part-2/
-*/
-func (me *Channel) Qos(prefetchCount, prefetchSize int, global bool) error {
-	return me.call(
-		&basicQos{
-			PrefetchCount: uint16(prefetchCount),
-			PrefetchSize:  uint32(prefetchSize),
-			Global:        global,
-		},
-		&basicQosOk{},
-	)
-}
-
-/*
-Cancel stops deliveries to the consumer chan established in Channel.Consume and
-identified by consumer.
-
-Only use this method to cleanly stop receiving deliveries from the server and
-cleanly shut down the consumer chan identified by this tag.  Using this method
-and waiting for remaining messages to flush from the consumer chan will ensure
-all messages received on the network will be delivered to the receiver of your
-consumer chan.
-
-Continue consuming from the chan Delivery provided by Channel.Consume until the
-chan closes.
-
-When noWait is true, do not wait for the server to acknowledge the cancel.
-Only use this when you are certain there are no deliveries requiring
-acknowledgment are in-flight otherwise they will arrive and be dropped in the
-client without an ack and will not be redelivered to other consumers.
-
-*/
-func (me *Channel) Cancel(consumer string, noWait bool) error {
-	req := &basicCancel{
-		ConsumerTag: consumer,
-		NoWait:      noWait,
-	}
-	res := &basicCancelOk{}
-
-	if err := me.call(req, res); err != nil {
-		return err
-	}
-
-	if req.wait() {
-		me.consumers.close(res.ConsumerTag)
-	} else {
-		// Potentially could drop deliveries in flight
-		me.consumers.close(consumer)
-	}
-
-	return nil
-}
-
-/*
-QueueDeclare declares a queue to hold messages and deliver to consumers.
-Declaring creates a queue if it doesn't already exist, or ensures that an
-existing queue matches the same parameters.
-
-Every queue declared gets a default binding to the empty exchange "" which has
-the type "direct" with the routing key matching the queue's name.  With this
-default binding, it is possible to publish messages that route directly to
-this queue by publishing to "" with the routing key of the queue name.
-
-  QueueDeclare("alerts", true, false, false false, false, nil)
-  Publish("", "alerts", false, false, Publishing{Body: []byte("...")})
-
-  Delivery       Exchange  Key       Queue
-  -----------------------------------------------
-  key: alerts -> ""     -> alerts -> alerts
-
-The queue name may be empty, in which the server will generate a unique name
-which will be returned in the Name field of Queue struct.
-
-Durable and Non-Auto-Deleted queues will survive server restarts and remain
-when there are no remaining consumers or bindings.  Persistent publishings will
-be restored in this queue on server restart.  These queues are only able to be
-bound to durable exchanges.
-
-Non-Durable and Auto-Deleted queues will not be redeclared on server restart
-and will be deleted by the server after a short time when the last consumer is
-canceled or the last consumer's channel is closed.  Queues with this lifetime
-can also be deleted normally with QueueDelete.  These durable queues can only
-be bound to non-durable exchanges.
-
-Non-Durable and Non-Auto-Deleted queues will remain declared as long as the
-server is running regardless of how many consumers.  This lifetime is useful
-for temporary topologies that may have long delays between consumer activity.
-These queues can only be bound to non-durable exchanges.
-
-Durable and Auto-Deleted queues will be restored on server restart, but without
-active consumers, will not survive and be removed.  This Lifetime is unlikely
-to be useful.
-
-Exclusive queues are only accessible by the connection that declares them and
-will be deleted when the connection closes.  Channels on other connections
-will receive an error when attempting declare, bind, consume, purge or delete a
-queue with the same name.
-
-When noWait is true, the queue will assume to be declared on the server.  A
-channel exception will arrive if the conditions are met for existing queues
-or attempting to modify an existing queue from a different connection.
-
-When the error return value is not nil, you can assume the queue could not be
-declared with these parameters and the channel will be closed.
-
-*/
-func (me *Channel) QueueDeclare(name string, durable, autoDelete, exclusive, noWait bool, args Table) (Queue, error) {
-	if err := args.Validate(); err != nil {
-		return Queue{}, err
-	}
-
-	req := &queueDeclare{
-		Queue:      name,
-		Passive:    false,
-		Durable:    durable,
-		AutoDelete: autoDelete,
-		Exclusive:  exclusive,
-		NoWait:     noWait,
-		Arguments:  args,
-	}
-	res := &queueDeclareOk{}
-
-	if err := me.call(req, res); err != nil {
-		return Queue{}, err
-	}
-
-	if req.wait() {
-		return Queue{
-			Name:      res.Queue,
-			Messages:  int(res.MessageCount),
-			Consumers: int(res.ConsumerCount),
-		}, nil
-	}
-
-	return Queue{
-		Name: name,
-	}, nil
-
-	panic("unreachable")
-}
-
-/*
-
-QueueDeclarePassive is functionally and parametrically equivalent to
-QueueDeclare, except that it sets the "passive" attribute to true. A passive
-queue is assumed by RabbitMQ to already exist, and attempting to connect to a
-non-existent queue will cause RabbitMQ to throw an exception. This function
-can be used to test for the existence of a queue.
-
-*/
-func (me *Channel) QueueDeclarePassive(name string, durable, autoDelete, exclusive, noWait bool, args Table) (Queue, error) {
-	if err := args.Validate(); err != nil {
-		return Queue{}, err
-	}
-
-	req := &queueDeclare{
-		Queue:      name,
-		Passive:    true,
-		Durable:    durable,
-		AutoDelete: autoDelete,
-		Exclusive:  exclusive,
-		NoWait:     noWait,
-		Arguments:  args,
-	}
-	res := &queueDeclareOk{}
-
-	if err := me.call(req, res); err != nil {
-		return Queue{}, err
-	}
-
-	if req.wait() {
-		return Queue{
-			Name:      res.Queue,
-			Messages:  int(res.MessageCount),
-			Consumers: int(res.ConsumerCount),
-		}, nil
-	}
-
-	return Queue{
-		Name: name,
-	}, nil
-
-	panic("unreachable")
-}
-
-/*
-QueueInspect passively declares a queue by name to inspect the current message
-count, consumer count.
-
-Use this method to check how many unacknowledged messages reside in the queue
-and how many consumers are receiving deliveries and whether a queue by this
-name already exists.
-
-If the queue by this name exists, use Channel.QueueDeclare check if it is
-declared with specific parameters.
-
-If a queue by this name does not exist, an error will be returned and the
-channel will be closed.
-
-*/
-func (me *Channel) QueueInspect(name string) (Queue, error) {
-	req := &queueDeclare{
-		Queue:   name,
-		Passive: true,
-	}
-	res := &queueDeclareOk{}
-
-	err := me.call(req, res)
-
-	state := Queue{
-		Name:      name,
-		Messages:  int(res.MessageCount),
-		Consumers: int(res.ConsumerCount),
-	}
-
-	return state, err
-}
-
-/*
-QueueBind binds an exchange to a queue so that publishings to the exchange will
-be routed to the queue when the publishing routing key matches the binding
-routing key.
-
-  QueueBind("pagers", "alert", "log", false, nil)
-  QueueBind("emails", "info", "log", false, nil)
-
-  Delivery       Exchange  Key       Queue
-  -----------------------------------------------
-  key: alert --> log ----> alert --> pagers
-  key: info ---> log ----> info ---> emails
-  key: debug --> log       (none)    (dropped)
-
-If a binding with the same key and arguments already exists between the
-exchange and queue, the attempt to rebind will be ignored and the existing
-binding will be retained.
-
-In the case that multiple bindings may cause the message to be routed to the
-same queue, the server will only route the publishing once.  This is possible
-with topic exchanges.
-
-  QueueBind("pagers", "alert", "amq.topic", false, nil)
-  QueueBind("emails", "info", "amq.topic", false, nil)
-  QueueBind("emails", "#", "amq.topic", false, nil) // match everything
-
-  Delivery       Exchange        Key       Queue
-  -----------------------------------------------
-  key: alert --> amq.topic ----> alert --> pagers
-  key: info ---> amq.topic ----> # ------> emails
-                           \---> info ---/
-  key: debug --> amq.topic ----> # ------> emails
-
-It is only possible to bind a durable queue to a durable exchange regardless of
-whether the queue or exchange is auto-deleted.  Bindings between durable queues
-and exchanges will also be restored on server restart.
-
-If the binding could not complete, an error will be returned and the channel
-will be closed.
-
-When noWait is true and the queue could not be bound, the channel will be
-closed with an error.
-
-*/
-func (me *Channel) QueueBind(name, key, exchange string, noWait bool, args Table) error {
-	if err := args.Validate(); err != nil {
-		return err
-	}
-
-	return me.call(
-		&queueBind{
-			Queue:      name,
-			Exchange:   exchange,
-			RoutingKey: key,
-			NoWait:     noWait,
-			Arguments:  args,
-		},
-		&queueBindOk{},
-	)
-}
-
-/*
-QueueUnbind removes a binding between an exchange and queue matching the key and
-arguments.
-
-It is possible to send and empty string for the exchange name which means to
-unbind the queue from the default exchange.
-
-*/
-func (me *Channel) QueueUnbind(name, key, exchange string, args Table) error {
-	if err := args.Validate(); err != nil {
-		return err
-	}
-
-	return me.call(
-		&queueUnbind{
-			Queue:      name,
-			Exchange:   exchange,
-			RoutingKey: key,
-			Arguments:  args,
-		},
-		&queueUnbindOk{},
-	)
-}
-
-/*
-QueuePurge removes all messages from the named queue which are not waiting to
-be acknowledged.  Messages that have been delivered but have not yet been
-acknowledged will not be removed.
-
-When successful, returns the number of messages purged.
-
-If noWait is true, do not wait for the server response and the number of
-messages purged will not be meaningful.
-*/
-func (me *Channel) QueuePurge(name string, noWait bool) (int, error) {
-	req := &queuePurge{
-		Queue:  name,
-		NoWait: noWait,
-	}
-	res := &queuePurgeOk{}
-
-	err := me.call(req, res)
-
-	return int(res.MessageCount), err
-}
-
-/*
-QueueDelete removes the queue from the server including all bindings then
-purges the messages based on server configuration, returning the number of
-messages purged.
-
-When ifUnused is true, the queue will not be deleted if there are any
-consumers on the queue.  If there are consumers, an error will be returned and
-the channel will be closed.
-
-When ifEmpty is true, the queue will not be deleted if there are any messages
-remaining on the queue.  If there are messages, an error will be returned and
-the channel will be closed.
-
-When noWait is true, the queue will be deleted without waiting for a response
-from the server.  The purged message count will not be meaningful. If the queue
-could not be deleted, a channel exception will be raised and the channel will
-be closed.
-
-*/
-func (me *Channel) QueueDelete(name string, ifUnused, ifEmpty, noWait bool) (int, error) {
-	req := &queueDelete{
-		Queue:    name,
-		IfUnused: ifUnused,
-		IfEmpty:  ifEmpty,
-		NoWait:   noWait,
-	}
-	res := &queueDeleteOk{}
-
-	err := me.call(req, res)
-
-	return int(res.MessageCount), err
-}
-
-/*
-Consume immediately starts delivering queued messages.
-
-Begin receiving on the returned chan Delivery before any other operation on the
-Connection or Channel.
-
-Continues deliveries to the returned chan Delivery until Channel.Cancel,
-Connection.Close, Channel.Close, or an AMQP exception occurs.  Consumers must
-range over the chan to ensure all deliveries are received.  Unreceived
-deliveries will block all methods on the same connection.
-
-All deliveries in AMQP must be acknowledged.  It is expected of the consumer to
-call Delivery.Ack after it has successfully processed the delivery.  If the
-consumer is cancelled or the channel or connection is closed any unacknowledged
-deliveries will be requeued at the end of the same queue.
-
-The consumer is identified by a string that is unique and scoped for all
-consumers on this channel.  If you wish to eventually cancel the consumer, use
-the same non-empty idenfitier in Channel.Cancel.  An empty string will cause
-the library to generate a unique identity.  The consumer identity will be
-included in every Delivery in the ConsumerTag field
-
-When autoAck (also known as noAck) is true, the server will acknowledge
-deliveries to this consumer prior to writing the delivery to the network.  When
-autoAck is true, the consumer should not call Delivery.Ack.  Automatically
-acknowledging deliveries means that some deliveries may get lost if the
-consumer is unable to process them after the server delivers them.
-
-When exclusive is true, the server will ensure that this is the sole consumer
-from this queue.  When exclusive is false, the server will fairly distribute
-deliveries across multiple consumers.
-
-When noLocal is true, the server will not deliver publishing sent from the same
-connection to this consumer.  It's advisable to use separate connections for
-Channel.Publish and Channel.Consume so not to have TCP pushback on publishing
-affect the ability to consume messages, so this parameter is here mostly for
-completeness.
-
-When noWait is true, do not wait for the server to confirm the request and
-immediately begin deliveries.  If it is not possible to consume, a channel
-exception will be raised and the channel will be closed.
-
-Optional arguments can be provided that have specific semantics for the queue
-or server.
-
-When the channel or connection closes, all delivery chans will also close.
-
-Deliveries on the returned chan will be buffered indefinitely.  To limit memory
-of this buffer, use the Channel.Qos method to limit the amount of
-unacknowledged/buffered deliveries the server will deliver on this Channel.
-
-*/
-func (me *Channel) Consume(queue, consumer string, autoAck, exclusive, noLocal, noWait bool, args Table) (<-chan Delivery, error) {
-	// When we return from me.call, there may be a delivery already for the
-	// consumer that hasn't been added to the consumer hash yet.  Because of
-	// this, we never rely on the server picking a consumer tag for us.
-
-	if err := args.Validate(); err != nil {
-		return nil, err
-	}
-
-	if consumer == "" {
-		consumer = uniqueConsumerTag()
-	}
-
-	req := &basicConsume{
-		Queue:       queue,
-		ConsumerTag: consumer,
-		NoLocal:     noLocal,
-		NoAck:       autoAck,
-		Exclusive:   exclusive,
-		NoWait:      noWait,
-		Arguments:   args,
-	}
-	res := &basicConsumeOk{}
-
-	deliveries := make(chan Delivery)
-
-	me.consumers.add(consumer, deliveries)
-
-	if err := me.call(req, res); err != nil {
-		me.consumers.close(consumer)
-		return nil, err
-	}
-
-	return (<-chan Delivery)(deliveries), nil
-}
-
-/*
-ExchangeDeclare declares an exchange on the server. If the exchange does not
-already exist, the server will create it.  If the exchange exists, the server
-verifies that it is of the provided type, durability and auto-delete flags.
-
-Errors returned from this method will close the channel.
-
-Exchange names starting with "amq." are reserved for pre-declared and
-standardized exchanges. The client MAY declare an exchange starting with
-"amq." if the passive option is set, or the exchange already exists.  Names can
-consists of a non-empty sequence of letters, digits, hyphen, underscore,
-period, or colon.
-
-Each exchange belongs to one of a set of exchange kinds/types implemented by
-the server. The exchange types define the functionality of the exchange - i.e.
-how messages are routed through it. Once an exchange is declared, its type
-cannot be changed.  The common types are "direct", "fanout", "topic" and
-"headers".
-
-Durable and Non-Auto-Deleted exchanges will survive server restarts and remain
-declared when there are no remaining bindings.  This is the best lifetime for
-long-lived exchange configurations like stable routes and default exchanges.
-
-Non-Durable and Auto-Deleted exchanges will be deleted when there are no
-remaining bindings and not restored on server restart.  This lifetime is
-useful for temporary topologies that should not pollute the virtual host on
-failure or after the consumers have completed.
-
-Non-Durable and Non-Auto-deleted exchanges will remain as long as the server is
-running including when there are no remaining bindings.  This is useful for
-temporary topologies that may have long delays between bindings.
-
-Durable and Auto-Deleted exchanges will survive server restarts and will be
-removed before and after server restarts when there are no remaining bindings.
-These exchanges are useful for robust temporary topologies or when you require
-binding durable queues to auto-deleted exchanges.
-
-Note: RabbitMQ declares the default exchange types like 'amq.fanout' as
-durable, so queues that bind to these pre-declared exchanges must also be
-durable.
-
-Exchanges declared as `internal` do not accept accept publishings. Internal
-exchanges are useful for when you wish to implement inter-exchange topologies
-that should not be exposed to users of the broker.
-
-When noWait is true, declare without waiting for a confirmation from the server.
-The channel may be closed as a result of an error.  Add a NotifyClose listener
-to respond to any exceptions.
-
-Optional amqp.Table of arguments that are specific to the server's implementation of
-the exchange can be sent for exchange types that require extra parameters.
-*/
-func (me *Channel) ExchangeDeclare(name, kind string, durable, autoDelete, internal, noWait bool, args Table) error {
-	if err := args.Validate(); err != nil {
-		return err
-	}
-
-	return me.call(
-		&exchangeDeclare{
-			Exchange:   name,
-			Type:       kind,
-			Passive:    false,
-			Durable:    durable,
-			AutoDelete: autoDelete,
-			Internal:   internal,
-			NoWait:     noWait,
-			Arguments:  args,
-		},
-		&exchangeDeclareOk{},
-	)
-}
-
-/*
-
-ExchangeDeclarePassive is functionally and parametrically equivalent to
-ExchangeDeclare, except that it sets the "passive" attribute to true. A passive
-exchange is assumed by RabbitMQ to already exist, and attempting to connect to a
-non-existent exchange will cause RabbitMQ to throw an exception. This function
-can be used to detect the existence of an exchange.
-
-*/
-func (me *Channel) ExchangeDeclarePassive(name, kind string, durable, autoDelete, internal, noWait bool, args Table) error {
-	if err := args.Validate(); err != nil {
-		return err
-	}
-
-	return me.call(
-		&exchangeDeclare{
-			Exchange:   name,
-			Type:       kind,
-			Passive:    true,
-			Durable:    durable,
-			AutoDelete: autoDelete,
-			Internal:   internal,
-			NoWait:     noWait,
-			Arguments:  args,
-		},
-		&exchangeDeclareOk{},
-	)
-}
-
-/*
-ExchangeDelete removes the named exchange from the server. When an exchange is
-deleted all queue bindings on the exchange are also deleted.  If this exchange
-does not exist, the channel will be closed with an error.
-
-When ifUnused is true, the server will only delete the exchange if it has no queue
-bindings.  If the exchange has queue bindings the server does not delete it
-but close the channel with an exception instead.  Set this to true if you are
-not the sole owner of the exchange.
-
-When noWait is true, do not wait for a server confirmation that the exchange has
-been deleted.  Failing to delete the channel could close the channel.  Add a
-NotifyClose listener to respond to these channel exceptions.
-*/
-func (me *Channel) ExchangeDelete(name string, ifUnused, noWait bool) error {
-	return me.call(
-		&exchangeDelete{
-			Exchange: name,
-			IfUnused: ifUnused,
-			NoWait:   noWait,
-		},
-		&exchangeDeleteOk{},
-	)
-}
-
-/*
-ExchangeBind binds an exchange to another exchange to create inter-exchange
-routing topologies on the server.  This can decouple the private topology and
-routing exchanges from exchanges intended solely for publishing endpoints.
-
-Binding two exchanges with identical arguments will not create duplicate
-bindings.
-
-Binding one exchange to another with multiple bindings will only deliver a
-message once.  For example if you bind your exchange to `amq.fanout` with two
-different binding keys, only a single message will be delivered to your
-exchange even though multiple bindings will match.
-
-Given a message delivered to the source exchange, the message will be forwarded
-to the destination exchange when the routing key is matched.
-
-  ExchangeBind("sell", "MSFT", "trade", false, nil)
-  ExchangeBind("buy", "AAPL", "trade", false, nil)
-
-  Delivery       Source      Key      Destination
-  example        exchange             exchange
-  -----------------------------------------------
-  key: AAPL  --> trade ----> MSFT     sell
-                       \---> AAPL --> buy
-
-When noWait is true, do not wait for the server to confirm the binding.  If any
-error occurs the channel will be closed.  Add a listener to NotifyClose to
-handle these errors.
-
-Optional arguments specific to the exchanges bound can also be specified.
-*/
-func (me *Channel) ExchangeBind(destination, key, source string, noWait bool, args Table) error {
-	if err := args.Validate(); err != nil {
-		return err
-	}
-
-	return me.call(
-		&exchangeBind{
-			Destination: destination,
-			Source:      source,
-			RoutingKey:  key,
-			NoWait:      noWait,
-			Arguments:   args,
-		},
-		&exchangeBindOk{},
-	)
-}
-
-/*
-ExchangeUnbind unbinds the destination exchange from the source exchange on the
-server by removing the routing key between them.  This is the inverse of
-ExchangeBind.  If the binding does not currently exist, an error will be
-returned.
-
-When noWait is true, do not wait for the server to confirm the deletion of the
-binding.  If any error occurs the channel will be closed.  Add a listener to
-NotifyClose to handle these errors.
-
-Optional arguments that are specific to the type of exchanges bound can also be
-provided.  These must match the same arguments specified in ExchangeBind to
-identify the binding.
-*/
-func (me *Channel) ExchangeUnbind(destination, key, source string, noWait bool, args Table) error {
-	if err := args.Validate(); err != nil {
-		return err
-	}
-
-	return me.call(
-		&exchangeUnbind{
-			Destination: destination,
-			Source:      source,
-			RoutingKey:  key,
-			NoWait:      noWait,
-			Arguments:   args,
-		},
-		&exchangeUnbindOk{},
-	)
-}
-
-/*
-Publish sends a Publishing from the client to an exchange on the server.
-
-When you want a single message to be delivered to a single queue, you can
-publish to the default exchange with the routingKey of the queue name.  This is
-because every declared queue gets an implicit route to the default exchange.
-
-Since publishings are asynchronous, any undeliverable message will get returned
-by the server.  Add a listener with Channel.NotifyReturn to handle any
-undeliverable message when calling publish with either the mandatory or
-immediate parameters as true.
-
-Publishings can be undeliverable when the mandatory flag is true and no queue is
-bound that matches the routing key, or when the immediate flag is true and no
-consumer on the matched queue is ready to accept the delivery.
-
-This can return an error when the channel, connection or socket is closed.  The
-error or lack of an error does not indicate whether the server has received this
-publishing.
-
-It is possible for publishing to not reach the broker if the underlying socket
-is shutdown without pending publishing packets being flushed from the kernel
-buffers.  The easy way of making it probable that all publishings reach the
-server is to always call Connection.Close before terminating your publishing
-application.  The way to ensure that all publishings reach the server is to add
-a listener to Channel.NotifyConfirm and keep track of the server acks and nacks
-for every publishing you publish, only exiting when all publishings are
-accounted for.
-
-*/
-func (me *Channel) Publish(exchange, key string, mandatory, immediate bool, msg Publishing) error {
-	if err := msg.Headers.Validate(); err != nil {
-		return err
-	}
-
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if err := me.send(me, &basicPublish{
-		Exchange:   exchange,
-		RoutingKey: key,
-		Mandatory:  mandatory,
-		Immediate:  immediate,
-		Body:       msg.Body,
-		Properties: properties{
-			Headers:         msg.Headers,
-			ContentType:     msg.ContentType,
-			ContentEncoding: msg.ContentEncoding,
-			DeliveryMode:    msg.DeliveryMode,
-			Priority:        msg.Priority,
-			CorrelationId:   msg.CorrelationId,
-			ReplyTo:         msg.ReplyTo,
-			Expiration:      msg.Expiration,
-			MessageId:       msg.MessageId,
-			Timestamp:       msg.Timestamp,
-			Type:            msg.Type,
-			UserId:          msg.UserId,
-			AppId:           msg.AppId,
-		},
-	}); err != nil {
-		return err
-	}
-
-	me.publishCounter += 1
-
-	if me.confirms != nil {
-		heap.Push(&me.confirms, me.publishCounter)
-	}
-
-	return nil
-}
-
-/*
-Get synchronously receives a single Delivery from the head of a queue from the
-server to the client.  In almost all cases, using Channel.Consume will be
-preferred.
-
-If there was a delivery waiting on the queue and that delivery was received the
-second return value will be true.  If there was no delivery waiting or an error
-occured, the ok bool will be false.
-
-All deliveries must be acknowledged including those from Channel.Get.  Call
-Delivery.Ack on the returned delivery when you have fully processed this
-delivery.
-
-When autoAck is true, the server will automatically acknowledge this message so
-you don't have to.  But if you are unable to fully process this message before
-the channel or connection is closed, the message will not get requeued.
-
-*/
-func (me *Channel) Get(queue string, autoAck bool) (msg Delivery, ok bool, err error) {
-	req := &basicGet{Queue: queue, NoAck: autoAck}
-	res := &basicGetOk{}
-	empty := &basicGetEmpty{}
-
-	if err := me.call(req, res, empty); err != nil {
-		return Delivery{}, false, err
-	}
-
-	if res.DeliveryTag > 0 {
-		return *(newDelivery(me, res)), true, nil
-	}
-
-	return Delivery{}, false, nil
-}
-
-/*
-Tx puts the channel into transaction mode on the server.  All publishings and
-acknowledgments following this method will be atomically committed or rolled
-back for a single queue.  Call either Channel.TxCommit or Channel.TxRollback to
-leave a this transaction and immediately start a new transaction.
-
-The atomicity across multiple queues is not defined as queue declarations and
-bindings are not included in the transaction.
-
-The behavior of publishings that are delivered as mandatory or immediate while
-the channel is in a transaction is not defined.
-
-Once a channel has been put into transaction mode, it cannot be taken out of
-transaction mode.  Use a different channel for non-transactional semantics.
-
-*/
-func (me *Channel) Tx() error {
-	return me.call(
-		&txSelect{},
-		&txSelectOk{},
-	)
-}
-
-/*
-TxCommit atomically commits all publishings and acknowledgments for a single
-queue and immediately start a new transaction.
-
-Calling this method without having called Channel.Tx is an error.
-
-*/
-func (me *Channel) TxCommit() error {
-	return me.call(
-		&txCommit{},
-		&txCommitOk{},
-	)
-}
-
-/*
-TxRollback atomically rolls back all publishings and acknowledgments for a
-single queue and immediately start a new transaction.
-
-Calling this method without having called Channel.Tx is an error.
-
-*/
-func (me *Channel) TxRollback() error {
-	return me.call(
-		&txRollback{},
-		&txRollbackOk{},
-	)
-}
-
-/*
-Flow pauses the delivery of messages to consumers on this channel.  Channels
-are opened with flow control not active, to open a channel with paused
-deliveries immediately call this method with true after calling
-Connection.Channel.
-
-When active is true, this method asks the server to temporarily pause deliveries
-until called again with active as false.
-
-Channel.Get methods will not be affected by flow control.
-
-This method is not intended to act as window control.  Use Channel.Qos to limit
-the number of unacknowledged messages or bytes in flight instead.
-
-The server may also send us flow methods to throttle our publishings.  A well
-behaving publishing client should add a listener with Channel.NotifyFlow and
-pause its publishings when true is sent on that channel.
-
-Note: RabbitMQ prefers to use TCP push back to control flow for all channels on
-a connection, so under high volume scenarios, it's wise to open separate
-Connections for publishings and deliveries.
-
-*/
-func (me *Channel) Flow(active bool) error {
-	return me.call(
-		&channelFlow{Active: active},
-		&channelFlowOk{},
-	)
-}
-
-/*
-Confirm puts this channel into confirm mode so that the client can ensure all
-publishings have successfully been received by the server.  After entering this
-mode, the server will send a basic.ack or basic.nack message with the deliver
-tag set to a 1 based incrementing index corresponding to every publishing
-received after the this method returns.
-
-Add a listener to Channel.NotifyConfirm to respond to the acknowledgments and
-negative acknowledgments before publishing.  If Channel.NotifyConfirm is not
-called, the Ack/Nacks will be silently ignored.
-
-The order of acknowledgments is not bound to the order of deliveries.
-
-Ack and Nack confirmations will arrive at some point in the future.
-
-Unroutable mandatory or immediate messages are acknowledged immediately after
-any Channel.NotifyReturn listeners have been notified.  Other messages are
-acknowledged when all queues that should have the message routed to them have
-either have received acknowledgment of delivery or have enqueued the message,
-persisting the message if necessary.
-
-When noWait is true, the client will not wait for a response.  A channel
-exception could occur if the server does not support this method.
-
-*/
-func (me *Channel) Confirm(noWait bool) error {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if err := me.call(
-		&confirmSelect{Nowait: noWait},
-		&confirmSelectOk{},
-	); err != nil {
-		return err
-	}
-
-	// Indicates we're in confirm mode
-	me.confirms = make(tagSet, 0)
-
-	return nil
-}
-
-/*
-Recover redelivers all unacknowledged deliveries on this channel.
-
-When requeue is false, messages will be redelivered to the original consumer.
-
-When requeue is true, messages will be redelivered to any available consumer,
-potentially including the original.
-
-If the deliveries cannot be recovered, an error will be returned and the channel
-will be closed.
-
-Note: this method is not implemented on RabbitMQ, use Delivery.Nack instead
-*/
-func (me *Channel) Recover(requeue bool) error {
-	return me.call(
-		&basicRecover{Requeue: requeue},
-		&basicRecoverOk{},
-	)
-}
-
-/*
-Ack acknowledges a delivery by its delivery tag when having been consumed with
-Channel.Consume or Channel.Get.
-
-Ack acknowledges all message received prior to the delivery tag when multiple
-is true.
-
-See also Delivery.Ack
-*/
-func (me *Channel) Ack(tag uint64, multiple bool) error {
-	return me.send(me, &basicAck{
-		DeliveryTag: tag,
-		Multiple:    multiple,
-	})
-}
-
-/*
-Nack negatively acknowledges a delivery by its delivery tag.  Prefer this
-method to notify the server that you were not able to process this delivery and
-it must be redelivered or dropped.
-
-See also Delivery.Nack
-*/
-func (me *Channel) Nack(tag uint64, multiple bool, requeue bool) error {
-	return me.send(me, &basicNack{
-		DeliveryTag: tag,
-		Multiple:    multiple,
-		Requeue:     requeue,
-	})
-}
-
-/*
-Reject negatively acknowledges a delivery by its delivery tag.  Prefer Nack
-over Reject when communicating with a RabbitMQ server because you can Nack
-multiple messages, reducing the amount of protocol messages to exchange.
-
-See also Delivery.Reject
-*/
-func (me *Channel) Reject(tag uint64, requeue bool) error {
-	return me.send(me, &basicReject{
-		DeliveryTag: tag,
-		Requeue:     requeue,
-	})
-}

+ 0 - 559
vendor/github.com/streadway/amqp/client_test.go

@@ -1,559 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"bytes"
-	"io"
-	"reflect"
-	"testing"
-	"time"
-)
-
-type server struct {
-	*testing.T
-	r reader             // framer <- client
-	w writer             // framer -> client
-	S io.ReadWriteCloser // Server IO
-	C io.ReadWriteCloser // Client IO
-
-	// captured client frames
-	start connectionStartOk
-	tune  connectionTuneOk
-}
-
-func defaultConfig() Config {
-	return Config{SASL: []Authentication{&PlainAuth{"guest", "guest"}}, Vhost: "/"}
-}
-
-func newSession(t *testing.T) (io.ReadWriteCloser, *server) {
-	rs, wc := io.Pipe()
-	rc, ws := io.Pipe()
-
-	rws := &logIO{t, "server", pipe{rs, ws}}
-	rwc := &logIO{t, "client", pipe{rc, wc}}
-
-	server := server{
-		T: t,
-		r: reader{rws},
-		w: writer{rws},
-		S: rws,
-		C: rwc,
-	}
-
-	return rwc, &server
-}
-
-func (t *server) expectBytes(b []byte) {
-	in := make([]byte, len(b))
-	if _, err := io.ReadFull(t.S, in); err != nil {
-		t.Fatalf("io error expecting bytes: %v", err)
-	}
-
-	if bytes.Compare(b, in) != 0 {
-		t.Fatalf("failed bytes: expected: %s got: %s", string(b), string(in))
-	}
-}
-
-func (t *server) send(channel int, m message) {
-	defer time.AfterFunc(time.Second, func() { panic("send deadlock") }).Stop()
-
-	if err := t.w.WriteFrame(&methodFrame{
-		ChannelId: uint16(channel),
-		Method:    m,
-	}); err != nil {
-		t.Fatalf("frame err, write: %s", err)
-	}
-}
-
-// drops all but method frames expected on the given channel
-func (t *server) recv(channel int, m message) message {
-	defer time.AfterFunc(time.Second, func() { panic("recv deadlock") }).Stop()
-
-	var remaining int
-	var header *headerFrame
-	var body []byte
-
-	for {
-		frame, err := t.r.ReadFrame()
-		if err != nil {
-			t.Fatalf("frame err, read: %s", err)
-		}
-
-		if frame.channel() != uint16(channel) {
-			t.Fatalf("expected frame on channel %d, got channel %d", channel, frame.channel())
-		}
-
-		switch f := frame.(type) {
-		case *heartbeatFrame:
-			// drop
-
-		case *headerFrame:
-			// start content state
-			header = f
-			remaining = int(header.Size)
-			if remaining == 0 {
-				m.(messageWithContent).setContent(header.Properties, nil)
-				return m
-			}
-
-		case *bodyFrame:
-			// continue until terminated
-			body = append(body, f.Body...)
-			remaining -= len(f.Body)
-			if remaining <= 0 {
-				m.(messageWithContent).setContent(header.Properties, body)
-				return m
-			}
-
-		case *methodFrame:
-			if reflect.TypeOf(m) == reflect.TypeOf(f.Method) {
-				wantv := reflect.ValueOf(m).Elem()
-				havev := reflect.ValueOf(f.Method).Elem()
-				wantv.Set(havev)
-				if _, ok := m.(messageWithContent); !ok {
-					return m
-				}
-			} else {
-				t.Fatalf("expected method type: %T, got: %T", m, f.Method)
-			}
-
-		default:
-			t.Fatalf("unexpected frame: %+v", f)
-		}
-	}
-
-	panic("unreachable")
-}
-
-func (t *server) expectAMQP() {
-	t.expectBytes([]byte{'A', 'M', 'Q', 'P', 0, 0, 9, 1})
-}
-
-func (t *server) connectionStart() {
-	t.send(0, &connectionStart{
-		VersionMajor: 0,
-		VersionMinor: 9,
-		Mechanisms:   "PLAIN",
-		Locales:      "en-us",
-	})
-
-	t.recv(0, &t.start)
-}
-
-func (t *server) connectionTune() {
-	t.send(0, &connectionTune{
-		ChannelMax: 11,
-		FrameMax:   20000,
-		Heartbeat:  10,
-	})
-
-	t.recv(0, &t.tune)
-}
-
-func (t *server) connectionOpen() {
-	t.expectAMQP()
-	t.connectionStart()
-	t.connectionTune()
-
-	t.recv(0, &connectionOpen{})
-	t.send(0, &connectionOpenOk{})
-}
-
-func (t *server) connectionClose() {
-	t.recv(0, &connectionClose{})
-	t.send(0, &connectionCloseOk{})
-}
-
-func (t *server) channelOpen(id int) {
-	t.recv(id, &channelOpen{})
-	t.send(id, &channelOpenOk{})
-}
-
-func TestDefaultClientProperties(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	go func() {
-		srv.connectionOpen()
-		rwc.Close()
-	}()
-
-	if c, err := Open(rwc, defaultConfig()); err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-
-	if want, got := defaultProduct, srv.start.ClientProperties["product"]; want != got {
-		t.Errorf("expected product %s got: %s", want, got)
-	}
-
-	if want, got := defaultVersion, srv.start.ClientProperties["version"]; want != got {
-		t.Errorf("expected version %s got: %s", want, got)
-	}
-}
-
-func TestCustomClientProperties(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	config := defaultConfig()
-	config.Properties = Table{
-		"product": "foo",
-		"version": "1.0",
-	}
-
-	go func() {
-		srv.connectionOpen()
-		rwc.Close()
-	}()
-
-	if c, err := Open(rwc, config); err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-
-	if want, got := config.Properties["product"], srv.start.ClientProperties["product"]; want != got {
-		t.Errorf("expected product %s got: %s", want, got)
-	}
-
-	if want, got := config.Properties["version"], srv.start.ClientProperties["version"]; want != got {
-		t.Errorf("expected version %s got: %s", want, got)
-	}
-}
-
-func TestOpen(t *testing.T) {
-	rwc, srv := newSession(t)
-	go func() {
-		srv.connectionOpen()
-		rwc.Close()
-	}()
-
-	if c, err := Open(rwc, defaultConfig()); err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-}
-
-func TestChannelOpen(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	go func() {
-		srv.connectionOpen()
-		srv.channelOpen(1)
-
-		rwc.Close()
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-
-	ch, err := c.Channel()
-	if err != nil {
-		t.Fatalf("could not open channel: %v (%s)", ch, err)
-	}
-}
-
-func TestOpenFailedSASLUnsupportedMechanisms(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	go func() {
-		srv.expectAMQP()
-		srv.send(0, &connectionStart{
-			VersionMajor: 0,
-			VersionMinor: 9,
-			Mechanisms:   "KERBEROS NTLM",
-			Locales:      "en-us",
-		})
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != ErrSASL {
-		t.Fatalf("expected ErrSASL got: %+v on %+v", err, c)
-	}
-}
-
-func TestOpenFailedCredentials(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	go func() {
-		srv.expectAMQP()
-		srv.connectionStart()
-		// Now kill/timeout the connection indicating bad auth
-		rwc.Close()
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != ErrCredentials {
-		t.Fatalf("expected ErrCredentials got: %+v on %+v", err, c)
-	}
-}
-
-func TestOpenFailedVhost(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	go func() {
-		srv.expectAMQP()
-		srv.connectionStart()
-		srv.connectionTune()
-		srv.recv(0, &connectionOpen{})
-
-		// Now kill/timeout the connection on bad Vhost
-		rwc.Close()
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != ErrVhost {
-		t.Fatalf("expected ErrVhost got: %+v on %+v", err, c)
-	}
-}
-
-func TestConfirmMultipleOrdersDeliveryTags(t *testing.T) {
-	rwc, srv := newSession(t)
-	defer rwc.Close()
-
-	go func() {
-		srv.connectionOpen()
-		srv.channelOpen(1)
-
-		srv.recv(1, &confirmSelect{})
-		srv.send(1, &confirmSelectOk{})
-
-		srv.recv(1, &basicPublish{})
-		srv.recv(1, &basicPublish{})
-		srv.recv(1, &basicPublish{})
-		srv.recv(1, &basicPublish{})
-
-		// Single tag, plus multiple, should produce
-		// 2, 1, 3, 4
-		srv.send(1, &basicAck{DeliveryTag: 2})
-		srv.send(1, &basicAck{DeliveryTag: 4, Multiple: true})
-
-		srv.recv(1, &basicPublish{})
-		srv.recv(1, &basicPublish{})
-		srv.recv(1, &basicPublish{})
-		srv.recv(1, &basicPublish{})
-
-		// And some more, but in reverse order, multiple then one
-		// 5, 6, 7, 8
-		srv.send(1, &basicAck{DeliveryTag: 6, Multiple: true})
-		srv.send(1, &basicAck{DeliveryTag: 8})
-		srv.send(1, &basicAck{DeliveryTag: 7})
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-
-	ch, err := c.Channel()
-	if err != nil {
-		t.Fatalf("could not open channel: %v (%s)", ch, err)
-	}
-
-	acks, _ := ch.NotifyConfirm(make(chan uint64), make(chan uint64))
-
-	ch.Confirm(false)
-
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 1")})
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 2")})
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 3")})
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 4")})
-
-	for i, tag := range []uint64{2, 1, 3, 4} {
-		if ack := <-acks; tag != ack {
-			t.Fatalf("failed ack, expected ack#%d to be %d, got %d", i, tag, ack)
-		}
-	}
-
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 5")})
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 6")})
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 7")})
-	ch.Publish("", "q", false, false, Publishing{Body: []byte("pub 8")})
-
-	for i, tag := range []uint64{5, 6, 8, 7} {
-		if ack := <-acks; tag != ack {
-			t.Fatalf("failed ack, expected ack#%d to be %d, got %d", i, tag, ack)
-		}
-	}
-
-}
-
-func TestNotifyClosesReusedPublisherConfirmChan(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	go func() {
-		srv.connectionOpen()
-		srv.channelOpen(1)
-
-		srv.recv(1, &confirmSelect{})
-		srv.send(1, &confirmSelectOk{})
-
-		srv.recv(0, &connectionClose{})
-		srv.send(0, &connectionCloseOk{})
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-
-	ch, err := c.Channel()
-	if err != nil {
-		t.Fatalf("could not open channel: %v (%s)", ch, err)
-	}
-
-	ackAndNack := make(chan uint64)
-	ch.NotifyConfirm(ackAndNack, ackAndNack)
-
-	if err := ch.Confirm(false); err != nil {
-		t.Fatalf("expected to enter confirm mode: %v", err)
-	}
-
-	if err := c.Close(); err != nil {
-		t.Fatalf("could not close connection: %v (%s)", c, err)
-	}
-}
-
-func TestNotifyClosesAllChansAfterConnectionClose(t *testing.T) {
-	rwc, srv := newSession(t)
-
-	go func() {
-		srv.connectionOpen()
-		srv.channelOpen(1)
-
-		srv.recv(0, &connectionClose{})
-		srv.send(0, &connectionCloseOk{})
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-
-	ch, err := c.Channel()
-	if err != nil {
-		t.Fatalf("could not open channel: %v (%s)", ch, err)
-	}
-
-	if err := c.Close(); err != nil {
-		t.Fatalf("could not close connection: %v (%s)", c, err)
-	}
-
-	select {
-	case <-c.NotifyClose(make(chan *Error)):
-	case <-time.After(time.Millisecond):
-		t.Errorf("expected to close NotifyClose chan after Connection.Close")
-	}
-
-	select {
-	case <-ch.NotifyClose(make(chan *Error)):
-	case <-time.After(time.Millisecond):
-		t.Errorf("expected to close Connection.NotifyClose chan after Connection.Close")
-	}
-
-	select {
-	case <-ch.NotifyFlow(make(chan bool)):
-	case <-time.After(time.Millisecond):
-		t.Errorf("expected to close Channel.NotifyFlow chan after Connection.Close")
-	}
-
-	select {
-	case <-ch.NotifyCancel(make(chan string)):
-	case <-time.After(time.Millisecond):
-		t.Errorf("expected to close Channel.NofityCancel chan after Connection.Close")
-	}
-
-	select {
-	case <-ch.NotifyReturn(make(chan Return)):
-	case <-time.After(time.Millisecond):
-		t.Errorf("expected to close Channel.NotifyReturn chan after Connection.Close")
-	}
-
-	ack, nack := ch.NotifyConfirm(make(chan uint64), make(chan uint64))
-
-	select {
-	case <-ack:
-	case <-time.After(time.Millisecond):
-		t.Errorf("expected to close acks on Channel.NotifyConfirm chan after Connection.Close")
-	}
-
-	select {
-	case <-nack:
-	case <-time.After(time.Millisecond):
-		t.Errorf("expected to close nacks Channel.NotifyConfirm chan after Connection.Close")
-	}
-}
-
-// Should not panic when sending bodies split at differnet boundaries
-func TestPublishBodySliceIssue74(t *testing.T) {
-	rwc, srv := newSession(t)
-	defer rwc.Close()
-
-	const frameSize = 100
-	const publishings = frameSize * 3
-
-	done := make(chan bool)
-	base := make([]byte, publishings)
-
-	go func() {
-		srv.connectionOpen()
-		srv.channelOpen(1)
-
-		for i := 0; i < publishings; i++ {
-			srv.recv(1, &basicPublish{})
-		}
-
-		done <- true
-	}()
-
-	cfg := defaultConfig()
-	cfg.FrameSize = frameSize
-
-	c, err := Open(rwc, cfg)
-	if err != nil {
-		t.Fatalf("could not create connection: %v (%s)", c, err)
-	}
-
-	ch, err := c.Channel()
-	if err != nil {
-		t.Fatalf("could not open channel: %v (%s)", ch, err)
-	}
-
-	for i := 0; i < publishings; i++ {
-		go ch.Publish("", "q", false, false, Publishing{Body: base[0:i]})
-	}
-
-	<-done
-}
-
-func TestPublishAndShutdownDeadlockIssue84(t *testing.T) {
-	rwc, srv := newSession(t)
-	defer rwc.Close()
-
-	go func() {
-		srv.connectionOpen()
-		srv.channelOpen(1)
-		srv.recv(1, &basicPublish{})
-		// Mimic a broken io pipe so that Publish catches the error and goes into shutdown
-		srv.S.Close()
-	}()
-
-	c, err := Open(rwc, defaultConfig())
-	if err != nil {
-		t.Fatalf("couldn't create connection: %v (%s)", c, err)
-	}
-
-	ch, err := c.Channel()
-	if err != nil {
-		t.Fatalf("couldn't open channel: %v (%s)", ch, err)
-	}
-
-	defer time.AfterFunc(500*time.Millisecond, func() { panic("Publish deadlock") }).Stop()
-	for {
-		if err := ch.Publish("exchange", "q", false, false, Publishing{Body: []byte("test")}); err != nil {
-			t.Log("successfully caught disconnect error", err)
-			return
-		}
-	}
-}

+ 0 - 764
vendor/github.com/streadway/amqp/connection.go

@@ -1,764 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"bufio"
-	"crypto/tls"
-	"io"
-	"net"
-	"reflect"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-)
-
-const (
-	defaultHeartbeat         = 10 * time.Second
-	defaultConnectionTimeout = 30 * time.Second
-	defaultProduct           = "https://github.com/streadway/amqp"
-	defaultVersion           = "β"
-	defaultChannelMax        = (2 << 16) - 1
-)
-
-// Config is used in DialConfig and Open to specify the desired tuning
-// parameters used during a connection open handshake.  The negotiated tuning
-// will be stored in the returned connection's Config field.
-type Config struct {
-	// The SASL mechanisms to try in the client request, and the successful
-	// mechanism used on the Connection object.
-	// If SASL is nil, PlainAuth from the URL is used.
-	SASL []Authentication
-
-	// Vhost specifies the namespace of permissions, exchanges, queues and
-	// bindings on the server.  Dial sets this to the path parsed from the URL.
-	Vhost string
-
-	ChannelMax int           // 0 max channels means 2^16 - 1
-	FrameSize  int           // 0 max bytes means unlimited
-	Heartbeat  time.Duration // less than 1s uses the server's interval
-
-	// TLSClientConfig specifies the client configuration of the TLS connection
-	// when establishing a tls transport.
-	// If the URL uses an amqps scheme, then an empty tls.Config with the
-	// ServerName from the URL is used.
-	TLSClientConfig *tls.Config
-
-	// Properties is table of properties that the client advertises to the server.
-	// This is an optional setting - if the application does not set this,
-	// the underlying library will use a generic set of client properties.
-	Properties Table
-
-	// Dial returns a net.Conn prepared for a TLS handshake with TSLClientConfig,
-	// then an AMQP connection handshake.
-	// If Dial is nil, net.DialTimeout with a 30s connection and 30s read
-	// deadline is used.
-	Dial func(network, addr string) (net.Conn, error)
-}
-
-// Connection manages the serialization and deserialization of frames from IO
-// and dispatches the frames to the appropriate channel.  All RPC methods and
-// asyncronous Publishing, Delivery, Ack, Nack and Return messages are
-// multiplexed on this channel.  There must always be active receivers for
-// every asynchronous message on this connection.
-type Connection struct {
-	destructor sync.Once  // shutdown once
-	sendM      sync.Mutex // conn writer mutex
-	m          sync.Mutex // struct field mutex
-
-	conn io.ReadWriteCloser
-
-	rpc       chan message
-	writer    *writer
-	sends     chan time.Time     // timestamps of each frame sent
-	deadlines chan readDeadliner // heartbeater updates read deadlines
-
-	allocator *allocator // id generator valid after openTune
-	channels  map[uint16]*Channel
-
-	noNotify bool // true when we will never notify again
-	closes   []chan *Error
-	blocks   []chan Blocking
-
-	errors chan *Error
-
-	Config Config // The negotiated Config after connection.open
-
-	Major      int   // Server's major version
-	Minor      int   // Server's minor version
-	Properties Table // Server properties
-}
-
-type readDeadliner interface {
-	SetReadDeadline(time.Time) error
-}
-
-type localNetAddr interface {
-	LocalAddr() net.Addr
-}
-
-// defaultDial establishes a connection when config.Dial is not provided
-func defaultDial(network, addr string) (net.Conn, error) {
-	conn, err := net.DialTimeout(network, addr, defaultConnectionTimeout)
-	if err != nil {
-		return nil, err
-	}
-
-	// Heartbeating hasn't started yet, don't stall forever on a dead server.
-	if err := conn.SetReadDeadline(time.Now().Add(defaultConnectionTimeout)); err != nil {
-		return nil, err
-	}
-
-	return conn, nil
-}
-
-// Dial accepts a string in the AMQP URI format and returns a new Connection
-// over TCP using PlainAuth.  Defaults to a server heartbeat interval of 10
-// seconds and sets the initial read deadline to 30 seconds.
-//
-// Dial uses the zero value of tls.Config when it encounters an amqps://
-// scheme.  It is equivalent to calling DialTLS(amqp, nil).
-func Dial(url string) (*Connection, error) {
-	return DialConfig(url, Config{
-		Heartbeat: defaultHeartbeat,
-	})
-}
-
-// DialTLS accepts a string in the AMQP URI format and returns a new Connection
-// over TCP using PlainAuth.  Defaults to a server heartbeat interval of 10
-// seconds and sets the initial read deadline to 30 seconds.
-//
-// DialTLS uses the provided tls.Config when encountering an amqps:// scheme.
-func DialTLS(url string, amqps *tls.Config) (*Connection, error) {
-	return DialConfig(url, Config{
-		Heartbeat:       defaultHeartbeat,
-		TLSClientConfig: amqps,
-	})
-}
-
-// DialConfig accepts a string in the AMQP URI format and a configuration for
-// the transport and connection setup, returning a new Connection.  Defaults to
-// a server heartbeat interval of 10 seconds and sets the initial read deadline
-// to 30 seconds.
-func DialConfig(url string, config Config) (*Connection, error) {
-	var err error
-	var conn net.Conn
-
-	uri, err := ParseURI(url)
-	if err != nil {
-		return nil, err
-	}
-
-	if config.SASL == nil {
-		config.SASL = []Authentication{uri.PlainAuth()}
-	}
-
-	if config.Vhost == "" {
-		config.Vhost = uri.Vhost
-	}
-
-	if uri.Scheme == "amqps" && config.TLSClientConfig == nil {
-		config.TLSClientConfig = new(tls.Config)
-	}
-
-	addr := net.JoinHostPort(uri.Host, strconv.FormatInt(int64(uri.Port), 10))
-
-	dialer := config.Dial
-	if dialer == nil {
-		dialer = defaultDial
-	}
-
-	conn, err = dialer("tcp", addr)
-	if err != nil {
-		return nil, err
-	}
-
-	if config.TLSClientConfig != nil {
-		// Use the URI's host for hostname validation unless otherwise set. Make a
-		// copy so not to modify the caller's reference when the caller reuses a
-		// tls.Config for a different URL.
-		if config.TLSClientConfig.ServerName == "" {
-			c := *config.TLSClientConfig
-			c.ServerName = uri.Host
-			config.TLSClientConfig = &c
-		}
-
-		client := tls.Client(conn, config.TLSClientConfig)
-		if err := client.Handshake(); err != nil {
-			conn.Close()
-			return nil, err
-		}
-
-		conn = client
-	}
-
-	return Open(conn, config)
-}
-
-/*
-Open accepts an already established connection, or other io.ReadWriteCloser as
-a transport.  Use this method if you have established a TLS connection or wish
-to use your own custom transport.
-
-*/
-func Open(conn io.ReadWriteCloser, config Config) (*Connection, error) {
-	me := &Connection{
-		conn:      conn,
-		writer:    &writer{bufio.NewWriter(conn)},
-		channels:  make(map[uint16]*Channel),
-		rpc:       make(chan message),
-		sends:     make(chan time.Time),
-		errors:    make(chan *Error, 1),
-		deadlines: make(chan readDeadliner, 1),
-	}
-	go me.reader(conn)
-	return me, me.open(config)
-}
-
-/*
-LocalAddr returns the local TCP peer address, or ":0" (the zero value of net.TCPAddr)
-as a fallback default value if the underlying transport does not support LocalAddr().
-*/
-func (me *Connection) LocalAddr() net.Addr {
-	if c, ok := me.conn.(localNetAddr); ok {
-		return c.LocalAddr()
-	}
-	return &net.TCPAddr{}
-}
-
-/*
-NotifyClose registers a listener for close events either initiated by an error
-accompaning a connection.close method or by a normal shutdown.
-
-On normal shutdowns, the chan will be closed.
-
-To reconnect after a transport or protocol error, register a listener here and
-re-run your setup process.
-
-*/
-func (me *Connection) NotifyClose(c chan *Error) chan *Error {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.noNotify {
-		close(c)
-	} else {
-		me.closes = append(me.closes, c)
-	}
-
-	return c
-}
-
-/*
-NotifyBlock registers a listener for RabbitMQ specific TCP flow control method
-extensions connection.blocked and connection.unblocked.  Flow control is active
-with a reason when Blocking.Blocked is true.  When a Connection is blocked, all
-methods will block across all connections until server resources become free
-again.
-
-This optional extension is supported by the server when the
-"connection.blocked" server capability key is true.
-
-*/
-func (me *Connection) NotifyBlocked(c chan Blocking) chan Blocking {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	if me.noNotify {
-		close(c)
-	} else {
-		me.blocks = append(me.blocks, c)
-	}
-
-	return c
-}
-
-/*
-Close requests and waits for the response to close the AMQP connection.
-
-It's advisable to use this message when publishing to ensure all kernel buffers
-have been flushed on the server and client before exiting.
-
-An error indicates that server may not have received this request to close but
-the connection should be treated as closed regardless.
-
-After returning from this call, all resources associated with this connection,
-including the underlying io, Channels, Notify listeners and Channel consumers
-will also be closed.
-*/
-func (me *Connection) Close() error {
-	defer me.shutdown(nil)
-	return me.call(
-		&connectionClose{
-			ReplyCode: replySuccess,
-			ReplyText: "kthxbai",
-		},
-		&connectionCloseOk{},
-	)
-}
-
-func (me *Connection) closeWith(err *Error) error {
-	defer me.shutdown(err)
-	return me.call(
-		&connectionClose{
-			ReplyCode: uint16(err.Code),
-			ReplyText: err.Reason,
-		},
-		&connectionCloseOk{},
-	)
-}
-
-func (me *Connection) send(f frame) error {
-	me.sendM.Lock()
-	err := me.writer.WriteFrame(f)
-	me.sendM.Unlock()
-
-	if err != nil {
-		// shutdown could be re-entrant from signaling notify chans
-		go me.shutdown(&Error{
-			Code:   FrameError,
-			Reason: err.Error(),
-		})
-	} else {
-		// Broadcast we sent a frame, reducing heartbeats, only
-		// if there is something that can receive - like a non-reentrant
-		// call or if the heartbeater isn't running
-		select {
-		case me.sends <- time.Now():
-		default:
-		}
-	}
-
-	return err
-}
-
-func (me *Connection) shutdown(err *Error) {
-	me.destructor.Do(func() {
-		if err != nil {
-			for _, c := range me.closes {
-				c <- err
-			}
-		}
-
-		for _, ch := range me.channels {
-			me.closeChannel(ch, err)
-		}
-
-		if err != nil {
-			me.errors <- err
-		}
-
-		me.conn.Close()
-
-		for _, c := range me.closes {
-			close(c)
-		}
-
-		for _, c := range me.blocks {
-			close(c)
-		}
-
-		me.m.Lock()
-		me.noNotify = true
-		me.m.Unlock()
-	})
-}
-
-// All methods sent to the connection channel should be synchronous so we
-// can handle them directly without a framing component
-func (me *Connection) demux(f frame) {
-	if f.channel() == 0 {
-		me.dispatch0(f)
-	} else {
-		me.dispatchN(f)
-	}
-}
-
-func (me *Connection) dispatch0(f frame) {
-	switch mf := f.(type) {
-	case *methodFrame:
-		switch m := mf.Method.(type) {
-		case *connectionClose:
-			// Send immediately as shutdown will close our side of the writer.
-			me.send(&methodFrame{
-				ChannelId: 0,
-				Method:    &connectionCloseOk{},
-			})
-
-			me.shutdown(newError(m.ReplyCode, m.ReplyText))
-		case *connectionBlocked:
-			for _, c := range me.blocks {
-				c <- Blocking{Active: true, Reason: m.Reason}
-			}
-		case *connectionUnblocked:
-			for _, c := range me.blocks {
-				c <- Blocking{Active: false}
-			}
-		default:
-			me.rpc <- m
-		}
-	case *heartbeatFrame:
-		// kthx - all reads reset our deadline.  so we can drop this
-	default:
-		// lolwat - channel0 only responds to methods and heartbeats
-		me.closeWith(ErrUnexpectedFrame)
-	}
-}
-
-func (me *Connection) dispatchN(f frame) {
-	me.m.Lock()
-	channel := me.channels[f.channel()]
-	me.m.Unlock()
-
-	if channel != nil {
-		channel.recv(channel, f)
-	} else {
-		me.dispatchClosed(f)
-	}
-}
-
-// section 2.3.7: "When a peer decides to close a channel or connection, it
-// sends a Close method.  The receiving peer MUST respond to a Close with a
-// Close-Ok, and then both parties can close their channel or connection.  Note
-// that if peers ignore Close, deadlock can happen when both peers send Close
-// at the same time."
-//
-// When we don't have a channel, so we must respond with close-ok on a close
-// method.  This can happen between a channel exception on an asynchronous
-// method like basic.publish and a synchronous close with channel.close.
-// In that case, we'll get both a channel.close and channel.close-ok in any
-// order.
-func (me *Connection) dispatchClosed(f frame) {
-	// Only consider method frames, drop content/header frames
-	if mf, ok := f.(*methodFrame); ok {
-		switch mf.Method.(type) {
-		case *channelClose:
-			me.send(&methodFrame{
-				ChannelId: f.channel(),
-				Method:    &channelCloseOk{},
-			})
-		case *channelCloseOk:
-			// we are already closed, so do nothing
-		default:
-			// unexpected method on closed channel
-			me.closeWith(ErrClosed)
-		}
-	}
-}
-
-// Reads each frame off the IO and hand off to the connection object that
-// will demux the streams and dispatch to one of the opened channels or
-// handle on channel 0 (the connection channel).
-func (me *Connection) reader(r io.Reader) {
-	buf := bufio.NewReader(r)
-	frames := &reader{buf}
-	conn, haveDeadliner := r.(readDeadliner)
-
-	for {
-		frame, err := frames.ReadFrame()
-
-		if err != nil {
-			me.shutdown(&Error{Code: FrameError, Reason: err.Error()})
-			return
-		}
-
-		me.demux(frame)
-
-		if haveDeadliner {
-			me.deadlines <- conn
-		}
-	}
-}
-
-// Ensures that at least one frame is being sent at the tuned interval with a
-// jitter tolerance of 1s
-func (me *Connection) heartbeater(interval time.Duration, done chan *Error) {
-	const maxServerHeartbeatsInFlight = 3
-
-	var sendTicks <-chan time.Time
-	if interval > 0 {
-		ticker := time.NewTicker(interval)
-		defer ticker.Stop()
-		sendTicks = ticker.C
-	}
-
-	lastSent := time.Now()
-
-	for {
-		select {
-		case at, stillSending := <-me.sends:
-			// When actively sending, depend on sent frames to reset server timer
-			if stillSending {
-				lastSent = at
-			} else {
-				return
-			}
-
-		case at := <-sendTicks:
-			// When idle, fill the space with a heartbeat frame
-			if at.Sub(lastSent) > interval-time.Second {
-				if err := me.send(&heartbeatFrame{}); err != nil {
-					// send heartbeats even after close/closeOk so we
-					// tick until the connection starts erroring
-					return
-				}
-			}
-
-		case conn := <-me.deadlines:
-			// When reading, reset our side of the deadline, if we've negotiated one with
-			// a deadline that covers at least 2 server heartbeats
-			if interval > 0 {
-				conn.SetReadDeadline(time.Now().Add(maxServerHeartbeatsInFlight * interval))
-			}
-
-		case <-done:
-			return
-		}
-	}
-}
-
-// Convenience method to inspect the Connection.Properties["capabilities"]
-// Table for server identified capabilities like "basic.ack" or
-// "confirm.select".
-func (me *Connection) isCapable(featureName string) bool {
-	capabilities, _ := me.Properties["capabilities"].(Table)
-	hasFeature, _ := capabilities[featureName].(bool)
-	return hasFeature
-}
-
-// allocateChannel records but does not open a new channel with a unique id.
-// This method is the initial part of the channel lifecycle and paired with
-// releaseChannel
-func (me *Connection) allocateChannel() (*Channel, error) {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	id, ok := me.allocator.next()
-	if !ok {
-		return nil, ErrChannelMax
-	}
-
-	ch := newChannel(me, uint16(id))
-	me.channels[uint16(id)] = ch
-
-	return ch, nil
-}
-
-// releaseChannel removes a channel from the registry as the final part of the
-// channel lifecycle
-func (me *Connection) releaseChannel(id uint16) {
-	me.m.Lock()
-	defer me.m.Unlock()
-
-	delete(me.channels, id)
-	me.allocator.release(int(id))
-}
-
-// openChannel allocates and opens a channel, must be paired with closeChannel
-func (me *Connection) openChannel() (*Channel, error) {
-	ch, err := me.allocateChannel()
-	if err != nil {
-		return nil, err
-	}
-
-	if err := ch.open(); err != nil {
-		return nil, err
-	}
-	return ch, nil
-}
-
-// closeChannel releases and initiates a shutdown of the channel.  All channel
-// closures should be initiated here for proper channel lifecycle management on
-// this connection.
-func (me *Connection) closeChannel(ch *Channel, e *Error) {
-	ch.shutdown(e)
-	me.releaseChannel(ch.id)
-}
-
-/*
-Channel opens a unique, concurrent server channel to process the bulk of AMQP
-messages.  Any error from methods on this receiver will render the receiver
-invalid and a new Channel should be opened.
-
-*/
-func (me *Connection) Channel() (*Channel, error) {
-	return me.openChannel()
-}
-
-func (me *Connection) call(req message, res ...message) error {
-	// Special case for when the protocol header frame is sent insted of a
-	// request method
-	if req != nil {
-		if err := me.send(&methodFrame{ChannelId: 0, Method: req}); err != nil {
-			return err
-		}
-	}
-
-	select {
-	case err := <-me.errors:
-		return err
-
-	case msg := <-me.rpc:
-		// Try to match one of the result types
-		for _, try := range res {
-			if reflect.TypeOf(msg) == reflect.TypeOf(try) {
-				// *res = *msg
-				vres := reflect.ValueOf(try).Elem()
-				vmsg := reflect.ValueOf(msg).Elem()
-				vres.Set(vmsg)
-				return nil
-			}
-		}
-		return ErrCommandInvalid
-	}
-
-	panic("unreachable")
-}
-
-//    Connection          = open-Connection *use-Connection close-Connection
-//    open-Connection     = C:protocol-header
-//                          S:START C:START-OK
-//                          *challenge
-//                          S:TUNE C:TUNE-OK
-//                          C:OPEN S:OPEN-OK
-//    challenge           = S:SECURE C:SECURE-OK
-//    use-Connection      = *channel
-//    close-Connection    = C:CLOSE S:CLOSE-OK
-//                        / S:CLOSE C:CLOSE-OK
-func (me *Connection) open(config Config) error {
-	if err := me.send(&protocolHeader{}); err != nil {
-		return err
-	}
-
-	return me.openStart(config)
-}
-
-func (me *Connection) openStart(config Config) error {
-	start := &connectionStart{}
-
-	if err := me.call(nil, start); err != nil {
-		return err
-	}
-
-	me.Major = int(start.VersionMajor)
-	me.Minor = int(start.VersionMinor)
-	me.Properties = Table(start.ServerProperties)
-
-	// eventually support challenge/response here by also responding to
-	// connectionSecure.
-	auth, ok := pickSASLMechanism(config.SASL, strings.Split(start.Mechanisms, " "))
-	if !ok {
-		return ErrSASL
-	}
-
-	// Save this mechanism off as the one we chose
-	me.Config.SASL = []Authentication{auth}
-
-	return me.openTune(config, auth)
-}
-
-func (me *Connection) openTune(config Config, auth Authentication) error {
-	if len(config.Properties) == 0 {
-		config.Properties = Table{
-			"product": defaultProduct,
-			"version": defaultVersion,
-		}
-	}
-
-	config.Properties["capabilities"] = Table{
-		"connection.blocked":     true,
-		"consumer_cancel_notify": true,
-	}
-
-	ok := &connectionStartOk{
-		Mechanism:        auth.Mechanism(),
-		Response:         auth.Response(),
-		ClientProperties: config.Properties,
-	}
-	tune := &connectionTune{}
-
-	if err := me.call(ok, tune); err != nil {
-		// per spec, a connection can only be closed when it has been opened
-		// so at this point, we know it's an auth error, but the socket
-		// was closed instead.  Return a meaningful error.
-		return ErrCredentials
-	}
-
-	// When the server and client both use default 0, then the max channel is
-	// only limited by uint16.
-	me.Config.ChannelMax = pick(config.ChannelMax, int(tune.ChannelMax))
-	if me.Config.ChannelMax == 0 {
-		me.Config.ChannelMax = defaultChannelMax
-	}
-
-	// Frame size includes headers and end byte (len(payload)+8), even if
-	// this is less than FrameMinSize, use what the server sends because the
-	// alternative is to stop the handshake here.
-	me.Config.FrameSize = pick(config.FrameSize, int(tune.FrameMax))
-
-	// Save this off for resetDeadline()
-	me.Config.Heartbeat = time.Second * time.Duration(pick(
-		int(config.Heartbeat/time.Second),
-		int(tune.Heartbeat)))
-
-	// "The client should start sending heartbeats after receiving a
-	// Connection.Tune method"
-	go me.heartbeater(me.Config.Heartbeat, me.NotifyClose(make(chan *Error, 1)))
-
-	if err := me.send(&methodFrame{
-		ChannelId: 0,
-		Method: &connectionTuneOk{
-			ChannelMax: uint16(me.Config.ChannelMax),
-			FrameMax:   uint32(me.Config.FrameSize),
-			Heartbeat:  uint16(me.Config.Heartbeat / time.Second),
-		},
-	}); err != nil {
-		return err
-	}
-
-	return me.openVhost(config)
-}
-
-func (me *Connection) openVhost(config Config) error {
-	req := &connectionOpen{VirtualHost: config.Vhost}
-	res := &connectionOpenOk{}
-
-	if err := me.call(req, res); err != nil {
-		// Cannot be closed yet, but we know it's a vhost problem
-		return ErrVhost
-	}
-
-	me.Config.Vhost = config.Vhost
-
-	return me.openComplete()
-}
-
-// openComplete performs any final Connection initialization dependent on the
-// connection handshake.
-func (me *Connection) openComplete() error {
-	me.allocator = newAllocator(1, me.Config.ChannelMax)
-	return nil
-}
-
-func pick(client, server int) int {
-	if client == 0 || server == 0 {
-		// max
-		if client > server {
-			return client
-		} else {
-			return server
-		}
-	} else {
-		// min
-		if client > server {
-			return server
-		} else {
-			return client
-		}
-	}
-	panic("unreachable")
-}

+ 0 - 118
vendor/github.com/streadway/amqp/consumers.go

@@ -1,118 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"fmt"
-	"os"
-	"sync"
-	"sync/atomic"
-)
-
-var consumerSeq uint64
-
-func uniqueConsumerTag() string {
-	return fmt.Sprintf("ctag-%s-%d", os.Args[0], atomic.AddUint64(&consumerSeq, 1))
-}
-
-type consumerBuffers map[string]chan *Delivery
-
-// Concurrent type that manages the consumerTag ->
-// ingress consumerBuffer mapping
-type consumers struct {
-	sync.Mutex
-	chans consumerBuffers
-}
-
-func makeConsumers() *consumers {
-	return &consumers{chans: make(consumerBuffers)}
-}
-
-func bufferDeliveries(in chan *Delivery, out chan Delivery) {
-	var queue []*Delivery
-	var queueIn = in
-
-	for delivery := range in {
-		select {
-		case out <- *delivery:
-			// delivered immediately while the consumer chan can receive
-		default:
-			queue = append(queue, delivery)
-		}
-
-		for len(queue) > 0 {
-			select {
-			case out <- *queue[0]:
-				queue = queue[1:]
-			case delivery, open := <-queueIn:
-				if open {
-					queue = append(queue, delivery)
-				} else {
-					// stop receiving to drain the queue
-					queueIn = nil
-				}
-			}
-		}
-	}
-
-	close(out)
-}
-
-// On key conflict, close the previous channel.
-func (me *consumers) add(tag string, consumer chan Delivery) {
-	me.Lock()
-	defer me.Unlock()
-
-	if prev, found := me.chans[tag]; found {
-		close(prev)
-	}
-
-	in := make(chan *Delivery)
-	go bufferDeliveries(in, consumer)
-
-	me.chans[tag] = in
-}
-
-func (me *consumers) close(tag string) (found bool) {
-	me.Lock()
-	defer me.Unlock()
-
-	ch, found := me.chans[tag]
-
-	if found {
-		delete(me.chans, tag)
-		close(ch)
-	}
-
-	return found
-}
-
-func (me *consumers) closeAll() {
-	me.Lock()
-	defer me.Unlock()
-
-	for _, ch := range me.chans {
-		close(ch)
-	}
-
-	me.chans = make(consumerBuffers)
-}
-
-// Sends a delivery to a the consumer identified by `tag`.
-// If unbuffered channels are used for Consume this method
-// could block all deliveries until the consumer
-// receives on the other end of the channel.
-func (me *consumers) send(tag string, msg *Delivery) bool {
-	me.Lock()
-	defer me.Unlock()
-
-	buffer, found := me.chans[tag]
-	if found {
-		buffer <- msg
-	}
-
-	return found
-}

+ 0 - 173
vendor/github.com/streadway/amqp/delivery.go

@@ -1,173 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"errors"
-	"time"
-)
-
-var errDeliveryNotInitialized = errors.New("delivery not initialized")
-
-// Acknowledger notifies the server of successful or failed consumption of
-// delivieries via identifier found in the Delivery.DeliveryTag field.
-//
-// Applications can provide mock implementations in tests of Delivery handlers.
-type Acknowledger interface {
-	Ack(tag uint64, multiple bool) error
-	Nack(tag uint64, multiple bool, requeue bool) error
-	Reject(tag uint64, requeue bool) error
-}
-
-// Delivery captures the fields for a previously delivered message resident in
-// a queue to be delivered by the server to a consumer from Channel.Consume or
-// Channel.Get.
-type Delivery struct {
-	Acknowledger Acknowledger // the channel from which this delivery arrived
-
-	Headers Table // Application or header exchange table
-
-	// Properties
-	ContentType     string    // MIME content type
-	ContentEncoding string    // MIME content encoding
-	DeliveryMode    uint8     // queue implemention use - non-persistent (1) or persistent (2)
-	Priority        uint8     // queue implementation use - 0 to 9
-	CorrelationId   string    // application use - correlation identifier
-	ReplyTo         string    // application use - address to to reply to (ex: RPC)
-	Expiration      string    // implementation use - message expiration spec
-	MessageId       string    // application use - message identifier
-	Timestamp       time.Time // application use - message timestamp
-	Type            string    // application use - message type name
-	UserId          string    // application use - creating user - should be authenticated user
-	AppId           string    // application use - creating application id
-
-	// Valid only with Channel.Consume
-	ConsumerTag string
-
-	// Valid only with Channel.Get
-	MessageCount uint32
-
-	DeliveryTag uint64
-	Redelivered bool
-	Exchange    string // basic.publish exhange
-	RoutingKey  string // basic.publish routing key
-
-	Body []byte
-}
-
-func newDelivery(channel *Channel, msg messageWithContent) *Delivery {
-	props, body := msg.getContent()
-
-	delivery := Delivery{
-		Acknowledger: channel,
-
-		Headers:         props.Headers,
-		ContentType:     props.ContentType,
-		ContentEncoding: props.ContentEncoding,
-		DeliveryMode:    props.DeliveryMode,
-		Priority:        props.Priority,
-		CorrelationId:   props.CorrelationId,
-		ReplyTo:         props.ReplyTo,
-		Expiration:      props.Expiration,
-		MessageId:       props.MessageId,
-		Timestamp:       props.Timestamp,
-		Type:            props.Type,
-		UserId:          props.UserId,
-		AppId:           props.AppId,
-
-		Body: body,
-	}
-
-	// Properties for the delivery types
-	switch m := msg.(type) {
-	case *basicDeliver:
-		delivery.ConsumerTag = m.ConsumerTag
-		delivery.DeliveryTag = m.DeliveryTag
-		delivery.Redelivered = m.Redelivered
-		delivery.Exchange = m.Exchange
-		delivery.RoutingKey = m.RoutingKey
-
-	case *basicGetOk:
-		delivery.MessageCount = m.MessageCount
-		delivery.DeliveryTag = m.DeliveryTag
-		delivery.Redelivered = m.Redelivered
-		delivery.Exchange = m.Exchange
-		delivery.RoutingKey = m.RoutingKey
-	}
-
-	return &delivery
-}
-
-/*
-Ack delegates an acknowledgement through the Acknowledger interface that the
-client or server has finished work on a delivery.
-
-All deliveries in AMQP must be acknowledged.  If you called Channel.Consume
-with autoAck true then the server will be automatically ack each message and
-this method should not be called.  Otherwise, you must call Delivery.Ack after
-you have successfully processed this delivery.
-
-When multiple is true, this delivery and all prior unacknowledged deliveries
-on the same channel will be acknowledged.  This is useful for batch processing
-of deliveries.
-
-An error will indicate that the acknowledge could not be delivered to the
-channel it was sent from.
-
-Either Delivery.Ack, Delivery.Reject or Delivery.Nack must be called for every
-delivery that is not automatically acknowledged.
-*/
-func (me Delivery) Ack(multiple bool) error {
-	if me.Acknowledger == nil {
-		return errDeliveryNotInitialized
-	}
-	return me.Acknowledger.Ack(me.DeliveryTag, multiple)
-}
-
-/*
-Reject delegates a negatively acknowledgement through the Acknowledger interface.
-
-When requeue is true, queue this message to be delivered to a consumer on a
-different channel.  When requeue is false or the server is unable to queue this
-message, it will be dropped.
-
-If you are batch processing deliveries, and your server supports it, prefer
-Delivery.Nack.
-
-Either Delivery.Ack, Delivery.Reject or Delivery.Nack must be called for every
-delivery that is not automatically acknowledged.
-*/
-func (me Delivery) Reject(requeue bool) error {
-	if me.Acknowledger == nil {
-		return errDeliveryNotInitialized
-	}
-	return me.Acknowledger.Reject(me.DeliveryTag, requeue)
-}
-
-/*
-Nack negatively acknowledge the delivery of message(s) identified by the
-delivery tag from either the client or server.
-
-When multiple is true, nack messages up to and including delivered messages up
-until the delivery tag delivered on the same channel.
-
-When requeue is true, request the server to deliver this message to a different
-consumer.  If it is not possible or requeue is false, the message will be
-dropped or delivered to a server configured dead-letter queue.
-
-This method must not be used to select or requeue messages the client wishes
-not to handle, rather it is to inform the server that the client is incapable
-of handling this message at this time.
-
-Either Delivery.Ack, Delivery.Reject or Delivery.Nack must be called for every
-delivery that is not automatically acknowledged.
-*/
-func (me Delivery) Nack(multiple, requeue bool) error {
-	if me.Acknowledger == nil {
-		return errDeliveryNotInitialized
-	}
-	return me.Acknowledger.Nack(me.DeliveryTag, multiple, requeue)
-}

+ 0 - 33
vendor/github.com/streadway/amqp/delivery_test.go

@@ -1,33 +0,0 @@
-package amqp
-
-import "testing"
-
-func shouldNotPanic(t *testing.T) {
-	if err := recover(); err != nil {
-		t.Fatalf("should not panic, got: %s", err)
-	}
-}
-
-// A closed delivery chan could produce zero value.  Ack/Nack/Reject on these
-// deliveries can produce a nil pointer panic.  Instead return an error when
-// the method can never be successful.
-func TestAckZeroValueAcknowledgerDoesNotPanic(t *testing.T) {
-	defer shouldNotPanic(t)
-	if err := (Delivery{}).Ack(false); err == nil {
-		t.Errorf("expected Delivery{}.Ack to error")
-	}
-}
-
-func TestNackZeroValueAcknowledgerDoesNotPanic(t *testing.T) {
-	defer shouldNotPanic(t)
-	if err := (Delivery{}).Nack(false, false); err == nil {
-		t.Errorf("expected Delivery{}.Ack to error")
-	}
-}
-
-func TestRejectZeroValueAcknowledgerDoesNotPanic(t *testing.T) {
-	defer shouldNotPanic(t)
-	if err := (Delivery{}).Reject(false); err == nil {
-		t.Errorf("expected Delivery{}.Ack to error")
-	}
-}

+ 0 - 108
vendor/github.com/streadway/amqp/doc.go

@@ -1,108 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-/*
-AMQP 0.9.1 client with RabbitMQ extensions
-
-Understand the AMQP 0.9.1 messaging model by reviewing these links first. Much
-of the terminology in this library directly relates to AMQP concepts.
-
-  Resources
-
-  http://www.rabbitmq.com/tutorials/amqp-concepts.html
-  http://www.rabbitmq.com/getstarted.html
-  http://www.rabbitmq.com/amqp-0-9-1-reference.html
-
-Design
-
-Most other broker clients publish to queues, but in AMQP, clients publish
-Exchanges instead.  AMQP is programmable, meaning that both the producers and
-consumers agree on the configuration of the broker, instead requiring an
-operator or system configuration that declares the logical topology in the
-broker.  The routing between producers and consumer queues is via Bindings.
-These bindings form the logical topology of the broker.
-
-In this library, a message sent from publisher is called a "Publishing" and a
-message received to a consumer is called a "Delivery".  The fields of
-Publishings and Deliveries are close but not exact mappings to the underlying
-wire format to maintain stronger types.  Many other libraries will combine
-message properties with message headers.  In this library, the message well
-known properties are strongly typed fields on the Publishings and Deliveries,
-whereas the user defined headers are in the Headers field.
-
-The method naming closely matches the protocol's method name with positional
-parameters mapping to named protocol message fields.  The motivation here is to
-present a comprehensive view over all possible interactions with the server.
-
-Generally, methods that map to protocol methods of the "basic" class will be
-elided in this interface, and "select" methods of various channel mode selectors
-will be elided for example Channel.Confirm and Channel.Tx.
-
-The library is intentionally designed to be synchronous, where responses for
-each protocol message are required to be received in an RPC manner.  Some
-methods have a noWait parameter like Channel.QueueDeclare, and some methods are
-asynchronous like Channel.Publish.  The error values should still be checked for
-these methods as they will indicate IO failures like when the underlying
-connection closes.
-
-Asynchronous Events
-
-Clients of this library may be interested in receiving some of the protocol
-messages other than Deliveries like basic.ack methods while a channel is in
-confirm mode.
-
-The Notify* methods with Connection and Channel receivers model the pattern of
-asynchronous events like closes due to exceptions, or messages that are sent out
-of band from an RPC call like basic.ack or basic.flow.
-
-Any asynchronous events, including Deliveries and Publishings must always have
-a receiver until the corresponding chans are closed.  Without asynchronous
-receivers, the sychronous methods will block.
-
-Use Case
-
-It's important as a client to an AMQP topology to ensure the state of the
-broker matches your expectations.  For both publish and consume use cases,
-make sure you declare the queues, exchanges and bindings you expect to exist
-prior to calling Channel.Publish or Channel.Consume.
-
-  // Connections start with amqp.Dial() typically from a command line argument
-  // or environment variable.
-  connection, err := amqp.Dial(os.Getenv("AMQP_URL"))
-
-  // To cleanly shutdown by flushing kernel buffers, make sure to close and
-  // wait for the response.
-  defer connection.Close()
-
-  // Most operations happen on a channel.  If any error is returned on a
-  // channel, the channel will no longer be valid, throw it away and try with
-  // a different channel.  If you use many channels, it's useful for the
-  // server to
-  channel, err := connection.Channel()
-
-  // Declare your topology here, if it doesn't exist, it will be created, if
-  // it existed already and is not what you expect, then that's considered an
-  // error.
-
-  // Use your connection on this topology with either Publish or Consume, or
-  // inspect your queues with QueueInspect.  It's unwise to mix Publish and
-  // Consume to let TCP do its job well.
-
-SSL/TLS - Secure connections
-
-When Dial encounters an amqps:// scheme, it will use the zero value of a
-tls.Config.  This will only perform server certificate and host verification.
-
-Use DialTLS when you wish to provide a client certificate (recommended),
-include a private certificate authority's certificate in the cert chain for
-server validity, or run insecure by not verifying the server certificate dial
-your own connection.  DialTLS will use the provided tls.Config when it
-encounters an amqps:// scheme and will dial a plain connection when it
-encounters an amqp:// scheme.
-
-SSL/TLS in RabbitMQ is documented here: http://www.rabbitmq.com/ssl.html
-
-*/
-package amqp

+ 0 - 395
vendor/github.com/streadway/amqp/examples_test.go

@@ -1,395 +0,0 @@
-package amqp_test
-
-import (
-	"crypto/tls"
-	"crypto/x509"
-	"github.com/streadway/amqp"
-	"io/ioutil"
-	"log"
-	"net"
-	"runtime"
-	"time"
-)
-
-func ExampleConfig_timeout() {
-	// Provide your own anonymous Dial function that delgates to net.DialTimout
-	// for custom timeouts
-
-	conn, err := amqp.DialConfig("amqp:///", amqp.Config{
-		Dial: func(network, addr string) (net.Conn, error) {
-			return net.DialTimeout(network, addr, 2*time.Second)
-		},
-	})
-
-	log.Printf("conn: %v, err: %v", conn, err)
-}
-
-func ExampleDialTLS() {
-	// To get started with SSL/TLS follow the instructions for adding SSL/TLS
-	// support in RabbitMQ with a private certificate authority here:
-	//
-	// http://www.rabbitmq.com/ssl.html
-	//
-	// Then in your rabbitmq.config, disable the plain AMQP port, verify clients
-	// and fail if no certificate is presented with the following:
-	//
-	//   [
-	//   {rabbit, [
-	//     {tcp_listeners, []},     % listens on 127.0.0.1:5672
-	//     {ssl_listeners, [5671]}, % listens on 0.0.0.0:5671
-	//     {ssl_options, [{cacertfile,"/path/to/your/testca/cacert.pem"},
-	//                    {certfile,"/path/to/your/server/cert.pem"},
-	//                    {keyfile,"/path/to/your/server/key.pem"},
-	//                    {verify,verify_peer},
-	//                    {fail_if_no_peer_cert,true}]}
-	//     ]}
-	//   ].
-
-	cfg := new(tls.Config)
-
-	// The self-signing certificate authority's certificate must be included in
-	// the RootCAs to be trusted so that the server certificate can be verified.
-	//
-	// Alternatively to adding it to the tls.Config you can add the CA's cert to
-	// your system's root CAs.  The tls package will use the system roots
-	// specific to each support OS.  Under OS X, add (drag/drop) your cacert.pem
-	// file to the 'Certificates' section of KeyChain.app to add and always
-	// trust.
-	//
-	// Or with the command line add and trust the DER encoded certificate:
-	//
-	//   security add-certificate testca/cacert.cer
-	//   security add-trusted-cert testca/cacert.cer
-	//
-	// If you depend on the system root CAs, then use nil for the RootCAs field
-	// so the system roots will be loaded.
-
-	cfg.RootCAs = x509.NewCertPool()
-
-	if ca, err := ioutil.ReadFile("testca/cacert.pem"); err == nil {
-		cfg.RootCAs.AppendCertsFromPEM(ca)
-	}
-
-	// Move the client cert and key to a location specific to your application
-	// and load them here.
-
-	if cert, err := tls.LoadX509KeyPair("client/cert.pem", "client/key.pem"); err == nil {
-		cfg.Certificates = append(cfg.Certificates, cert)
-	}
-
-	// Server names are validated by the crypto/tls package, so the server
-	// certificate must be made for the hostname in the URL.  Find the commonName
-	// (CN) and make sure the hostname in the URL matches this common name.  Per
-	// the RabbitMQ instructions for a self-signed cert, this defautls to the
-	// current hostname.
-	//
-	//   openssl x509 -noout -in server/cert.pem -subject
-	//
-	// If your server name in your certificate is different than the host you are
-	// connecting to, set the hostname used for verification in
-	// ServerName field of the tls.Config struct.
-
-	conn, err := amqp.DialTLS("amqps://server-name-from-certificate/", cfg)
-
-	log.Printf("conn: %v, err: %v", conn, err)
-}
-
-func ExampleChannel_Confirm_bridge() {
-	// This example acts as a bridge, shoveling all messages sent from the source
-	// exchange "log" to destination exchange "log".
-
-	// Confirming publishes can help from overproduction and ensure every message
-	// is delivered.
-
-	// Setup the source of the store and forward
-	source, err := amqp.Dial("amqp://source/")
-	if err != nil {
-		log.Fatalf("connection.open source: %s", err)
-	}
-	defer source.Close()
-
-	chs, err := source.Channel()
-	if err != nil {
-		log.Fatalf("channel.open source: %s", err)
-	}
-
-	if err := chs.ExchangeDeclare("log", "topic", true, false, false, false, nil); err != nil {
-		log.Fatalf("exchange.declare destination: %s", err)
-	}
-
-	if _, err := chs.QueueDeclare("remote-tee", true, true, false, false, nil); err != nil {
-		log.Fatalf("queue.declare source: %s", err)
-	}
-
-	if err := chs.QueueBind("remote-tee", "#", "logs", false, nil); err != nil {
-		log.Fatalf("queue.bind source: %s", err)
-	}
-
-	shovel, err := chs.Consume("remote-tee", "shovel", false, false, false, false, nil)
-	if err != nil {
-		log.Fatalf("basic.consume source: %s", err)
-	}
-
-	// Setup the destination of the store and forward
-	destination, err := amqp.Dial("amqp://destination/")
-	if err != nil {
-		log.Fatalf("connection.open destination: %s", err)
-	}
-	defer destination.Close()
-
-	chd, err := destination.Channel()
-	if err != nil {
-		log.Fatalf("channel.open destination: %s", err)
-	}
-
-	if err := chd.ExchangeDeclare("log", "topic", true, false, false, false, nil); err != nil {
-		log.Fatalf("exchange.declare destination: %s", err)
-	}
-
-	// Buffer of 1 for our single outstanding publishing
-	pubAcks, pubNacks := chd.NotifyConfirm(make(chan uint64, 1), make(chan uint64, 1))
-
-	if err := chd.Confirm(false); err != nil {
-		log.Fatalf("confirm.select destination: %s", err)
-	}
-
-	// Now pump the messages, one by one, a smarter implementation
-	// would batch the deliveries and use multiple ack/nacks
-	for {
-		msg, ok := <-shovel
-		if !ok {
-			log.Fatalf("source channel closed, see the reconnect example for handling this")
-		}
-
-		err = chd.Publish("logs", msg.RoutingKey, false, false, amqp.Publishing{
-			// Copy all the properties
-			ContentType:     msg.ContentType,
-			ContentEncoding: msg.ContentEncoding,
-			DeliveryMode:    msg.DeliveryMode,
-			Priority:        msg.Priority,
-			CorrelationId:   msg.CorrelationId,
-			ReplyTo:         msg.ReplyTo,
-			Expiration:      msg.Expiration,
-			MessageId:       msg.MessageId,
-			Timestamp:       msg.Timestamp,
-			Type:            msg.Type,
-			UserId:          msg.UserId,
-			AppId:           msg.AppId,
-
-			// Custom headers
-			Headers: msg.Headers,
-
-			// And the body
-			Body: msg.Body,
-		})
-
-		if err != nil {
-			msg.Nack(false, false)
-			log.Fatalf("basic.publish destination: %s", msg)
-		}
-
-		// only ack the source delivery when the destination acks the publishing
-		// here you could check for delivery order by keeping a local state of
-		// expected delivery tags
-		select {
-		case <-pubAcks:
-			msg.Ack(false)
-		case <-pubNacks:
-			msg.Nack(false, false)
-		}
-	}
-}
-
-func ExampleChannel_Consume() {
-	// Connects opens an AMQP connection from the credentials in the URL.
-	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
-	if err != nil {
-		log.Fatalf("connection.open: %s", err)
-	}
-	defer conn.Close()
-
-	c, err := conn.Channel()
-	if err != nil {
-		log.Fatalf("channel.open: %s", err)
-	}
-
-	// We declare our topology on both the publisher and consumer to ensure they
-	// are the same.  This is part of AMQP being a programmable messaging model.
-	//
-	// See the Channel.Publish example for the complimentary declare.
-	err = c.ExchangeDeclare("logs", "topic", true, false, false, false, nil)
-	if err != nil {
-		log.Fatalf("exchange.declare: %s", err)
-	}
-
-	// Establish our queue topologies that we are responsible for
-	type bind struct {
-		queue string
-		key   string
-	}
-
-	bindings := []bind{
-		bind{"page", "alert"},
-		bind{"email", "info"},
-		bind{"firehose", "#"},
-	}
-
-	for _, b := range bindings {
-		_, err = c.QueueDeclare(b.queue, true, false, false, false, nil)
-		if err != nil {
-			log.Fatalf("queue.declare: %v", err)
-		}
-
-		err = c.QueueBind(b.queue, b.key, "logs", false, nil)
-		if err != nil {
-			log.Fatalf("queue.bind: %v", err)
-		}
-	}
-
-	// Set our quality of service.  Since we're sharing 3 consumers on the same
-	// channel, we want at least 3 messages in flight.
-	err = c.Qos(3, 0, false)
-	if err != nil {
-		log.Fatalf("basic.qos: %v", err)
-	}
-
-	// Establish our consumers that have different responsibilities.  Our first
-	// two queues do not ack the messages on the server, so require to be acked
-	// on the client.
-
-	pages, err := c.Consume("page", "pager", false, false, false, false, nil)
-	if err != nil {
-		log.Fatalf("basic.consume: %v", err)
-	}
-
-	go func() {
-		for log := range pages {
-			// ... this consumer is responsible for sending pages per log
-			log.Ack(false)
-		}
-	}()
-
-	// Notice how the concern for which messages arrive here are in the AMQP
-	// topology and not in the queue.  We let the server pick a consumer tag this
-	// time.
-
-	emails, err := c.Consume("email", "", false, false, false, false, nil)
-	if err != nil {
-		log.Fatalf("basic.consume: %v", err)
-	}
-
-	go func() {
-		for log := range emails {
-			// ... this consumer is responsible for sending emails per log
-			log.Ack(false)
-		}
-	}()
-
-	// This consumer requests that every message is acknowledged as soon as it's
-	// delivered.
-
-	firehose, err := c.Consume("firehose", "", true, false, false, false, nil)
-	if err != nil {
-		log.Fatalf("basic.consume: %v", err)
-	}
-
-	// To show how to process the items in parallel, we'll use a work pool.
-	for i := 0; i < runtime.NumCPU(); i++ {
-		go func(work <-chan amqp.Delivery) {
-			for _ = range work {
-				// ... this consumer pulls from the firehose and doesn't need to acknowledge
-			}
-		}(firehose)
-	}
-
-	// Wait until you're ready to finish, could be a signal handler here.
-	time.Sleep(10 * time.Second)
-
-	// Cancelling a consumer by name will finish the range and gracefully end the
-	// goroutine
-	err = c.Cancel("pager", false)
-	if err != nil {
-		log.Fatalf("basic.cancel: %v", err)
-	}
-
-	// deferred closing the Connection will also finish the consumer's ranges of
-	// their delivery chans.  If you need every delivery to be processed, make
-	// sure to wait for all consumers goroutines to finish before exiting your
-	// process.
-}
-
-func ExampleChannel_Publish() {
-	// Connects opens an AMQP connection from the credentials in the URL.
-	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
-	if err != nil {
-		log.Fatalf("connection.open: %s", err)
-	}
-
-	// This waits for a server acknowledgment which means the sockets will have
-	// flushed all outbound publishings prior to returning.  It's important to
-	// block on Close to not lose any publishings.
-	defer conn.Close()
-
-	c, err := conn.Channel()
-	if err != nil {
-		log.Fatalf("channel.open: %s", err)
-	}
-
-	// We declare our topology on both the publisher and consumer to ensure they
-	// are the same.  This is part of AMQP being a programmable messaging model.
-	//
-	// See the Channel.Consume example for the complimentary declare.
-	err = c.ExchangeDeclare("logs", "topic", true, false, false, false, nil)
-	if err != nil {
-		log.Fatalf("exchange.declare: %v", err)
-	}
-
-	// Prepare this message to be persistent.  Your publishing requirements may
-	// be different.
-	msg := amqp.Publishing{
-		DeliveryMode: amqp.Persistent,
-		Timestamp:    time.Now(),
-		ContentType:  "text/plain",
-		Body:         []byte("Go Go AMQP!"),
-	}
-
-	// This is not a mandatory delivery, so it will be dropped if there are no
-	// queues bound to the logs exchange.
-	err = c.Publish("logs", "info", false, false, msg)
-	if err != nil {
-		// Since publish is asynchronous this can happen if the network connection
-		// is reset or if the server has run out of resources.
-		log.Fatalf("basic.publish: %v", err)
-	}
-}
-
-func publishAllTheThings(conn *amqp.Connection) {
-	// ... snarf snarf, barf barf
-}
-
-func ExampleConnection_NotifyBlocked() {
-	// Simply logs when the server throttles the TCP connection for publishers
-
-	// Test this by tuning your server to have a low memory watermark:
-	// rabbitmqctl set_vm_memory_high_watermark 0.00000001
-
-	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
-	if err != nil {
-		log.Fatalf("connection.open: %s", err)
-	}
-	defer conn.Close()
-
-	blockings := conn.NotifyBlocked(make(chan amqp.Blocking))
-	go func() {
-		for b := range blockings {
-			if b.Active {
-				log.Printf("TCP blocked: %q", b.Reason)
-			} else {
-				log.Printf("TCP unblocked")
-			}
-		}
-	}()
-
-	// Your application domain channel setup publishings
-	publishAllTheThings(conn)
-}

+ 0 - 2
vendor/github.com/streadway/amqp/gen.sh

@@ -1,2 +0,0 @@
-#!/bin/sh
-go run spec/gen.go < spec/amqp0-9-1.stripped.extended.xml | gofmt > spec091.go

+ 0 - 1772
vendor/github.com/streadway/amqp/integration_test.go

@@ -1,1772 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-// +build integration
-
-package amqp
-
-import (
-	"bytes"
-	devrand "crypto/rand"
-	"encoding/binary"
-	"fmt"
-	"hash/crc32"
-	"io"
-	"math/rand"
-	"net"
-	"os"
-	"reflect"
-	"strconv"
-	"testing"
-	"testing/quick"
-	"time"
-)
-
-func TestIntegrationOpenClose(t *testing.T) {
-	if c := integrationConnection(t, "open-close"); c != nil {
-		t.Logf("have connection, calling connection close")
-		if err := c.Close(); err != nil {
-			t.Fatalf("connection close: %s", err)
-		}
-		t.Logf("connection close OK")
-	}
-}
-
-func TestIntegrationOpenCloseChannel(t *testing.T) {
-	if c := integrationConnection(t, "channel"); c != nil {
-		defer c.Close()
-
-		if _, err := c.Channel(); err != nil {
-			t.Errorf("Channel could not be opened: %s", err)
-		}
-	}
-}
-
-func TestIntegrationOpenConfig(t *testing.T) {
-	config := Config{}
-
-	c, err := DialConfig(integrationURLFromEnv(), config)
-	if err != nil {
-		t.Errorf("expected to dial with config %+v integration server: %s", config, err)
-	}
-
-	if _, err := c.Channel(); err != nil {
-		t.Fatalf("expected to open channel: %s", err)
-	}
-
-	if err := c.Close(); err != nil {
-		t.Fatalf("connection close: %s", err)
-	}
-}
-
-func TestIntegrationOpenConfigWithNetDial(t *testing.T) {
-	config := Config{Dial: net.Dial}
-
-	c, err := DialConfig(integrationURLFromEnv(), config)
-	if err != nil {
-		t.Errorf("expected to dial with config %+v integration server: %s", config, err)
-	}
-
-	if _, err := c.Channel(); err != nil {
-		t.Fatalf("expected to open channel: %s", err)
-	}
-
-	if err := c.Close(); err != nil {
-		t.Fatalf("connection close: %s", err)
-	}
-}
-
-func TestIntegrationLocalAddr(t *testing.T) {
-	config := Config{}
-
-	c, err := DialConfig(integrationURLFromEnv(), config)
-	defer c.Close()
-	if err != nil {
-		t.Errorf("expected to dial with config %+v integration server: %s", config, err)
-	}
-
-	a := c.LocalAddr()
-	_, portString, err := net.SplitHostPort(a.String())
-	if err != nil {
-		t.Errorf("expected to get a local network address with config %+v integration server: %s", config, a.String())
-	}
-
-	port, err := strconv.Atoi(portString)
-	if err != nil {
-		t.Errorf("expected to get a TCP port number with config %+v integration server: %s", config, err)
-	}
-	t.Logf("Connected to port %d\n", port)
-}
-
-// https://github.com/streadway/amqp/issues/94
-func TestExchangePassiveOnMissingExchangeShouldError(t *testing.T) {
-	c := integrationConnection(t, "exch")
-	if c != nil {
-		defer c.Close()
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Fatalf("create channel 1: %s", err)
-		}
-		defer ch.Close()
-
-		if err := ch.ExchangeDeclarePassive(
-			"test-integration-missing-passive-exchange",
-			"direct", // type
-			false,    // duration (note: is durable)
-			true,     // auto-delete
-			false,    // internal
-			false,    // nowait
-			nil,      // args
-		); err == nil {
-			t.Fatal("ExchangeDeclarePassive of a missing exchange should return error")
-		}
-	}
-}
-
-// https://github.com/streadway/amqp/issues/94
-func TestIntegrationExchangeDeclarePassiveOnDeclaredShouldNotError(t *testing.T) {
-	c := integrationConnection(t, "exch")
-	if c != nil {
-		defer c.Close()
-
-		exchange := "test-integration-decalred-passive-exchange"
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Fatalf("create channel: %s", err)
-		}
-		defer ch.Close()
-
-		if err := ch.ExchangeDeclare(
-			exchange, // name
-			"direct", // type
-			false,    // durable
-			true,     // auto-delete
-			false,    // internal
-			false,    // nowait
-			nil,      // args
-		); err != nil {
-			t.Fatalf("declare exchange: %s", err)
-		}
-
-		if err := ch.ExchangeDeclarePassive(
-			exchange, // name
-			"direct", // type
-			false,    // durable
-			true,     // auto-delete
-			false,    // internal
-			false,    // nowait
-			nil,      // args
-		); err != nil {
-			t.Fatalf("ExchangeDeclarePassive on a declared exchange should not error, got: %q", err)
-		}
-	}
-}
-
-func TestIntegrationExchange(t *testing.T) {
-	c := integrationConnection(t, "exch")
-	if c != nil {
-		defer c.Close()
-
-		channel, err := c.Channel()
-		if err != nil {
-			t.Fatalf("create channel: %s", err)
-		}
-		t.Logf("create channel OK")
-
-		exchange := "test-integration-exchange"
-
-		if err := channel.ExchangeDeclare(
-			exchange, // name
-			"direct", // type
-			false,    // duration
-			true,     // auto-delete
-			false,    // internal
-			false,    // nowait
-			nil,      // args
-		); err != nil {
-			t.Fatalf("declare exchange: %s", err)
-		}
-		t.Logf("declare exchange OK")
-
-		if err := channel.ExchangeDelete(exchange, false, false); err != nil {
-			t.Fatalf("delete exchange: %s", err)
-		}
-		t.Logf("delete exchange OK")
-
-		if err := channel.Close(); err != nil {
-			t.Fatalf("close channel: %s", err)
-		}
-		t.Logf("close channel OK")
-	}
-}
-
-// https://github.com/streadway/amqp/issues/94
-func TestIntegrationQueueDeclarePassiveOnMissingExchangeShouldError(t *testing.T) {
-	c := integrationConnection(t, "queue")
-	if c != nil {
-		defer c.Close()
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Fatalf("create channel1: %s", err)
-		}
-		defer ch.Close()
-
-		if _, err := ch.QueueDeclarePassive(
-			"test-integration-missing-passive-queue", // name
-			false, // duration (note: not durable)
-			true,  // auto-delete
-			false, // exclusive
-			false, // noWait
-			nil,   // arguments
-		); err == nil {
-			t.Fatal("QueueDeclarePassive of a missing queue should error")
-		}
-	}
-}
-
-// https://github.com/streadway/amqp/issues/94
-func TestIntegrationPassiveQueue(t *testing.T) {
-	c := integrationConnection(t, "queue")
-	if c != nil {
-		defer c.Close()
-
-		name := "test-integration-declared-passive-queue"
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Fatalf("create channel1: %s", err)
-		}
-		defer ch.Close()
-
-		if _, err := ch.QueueDeclare(
-			name,  // name
-			false, // durable
-			true,  // auto-delete
-			false, // exclusive
-			false, // noWait
-			nil,   // arguments
-		); err != nil {
-			t.Fatalf("queue declare: %s", err)
-		}
-
-		if _, err := ch.QueueDeclarePassive(
-			name,  // name
-			false, // durable
-			true,  // auto-delete
-			false, // exclusive
-			false, // noWait
-			nil,   // arguments
-		); err != nil {
-			t.Fatalf("QueueDeclarePassive on declared queue should not error, got: %q", err)
-		}
-
-		if _, err := ch.QueueDeclarePassive(
-			name,  // name
-			true,  // durable (note: differs)
-			true,  // auto-delete
-			false, // exclusive
-			false, // noWait
-			nil,   // arguments
-		); err != nil {
-			t.Fatalf("QueueDeclarePassive on declared queue with different flags should error")
-		}
-	}
-}
-
-func TestIntegrationBasicQueueOperations(t *testing.T) {
-	c := integrationConnection(t, "queue")
-	if c != nil {
-		defer c.Close()
-
-		channel, err := c.Channel()
-		if err != nil {
-			t.Fatalf("create channel: %s", err)
-		}
-		t.Logf("create channel OK")
-
-		exchangeName := "test-basic-ops-exchange"
-		queueName := "test-basic-ops-queue"
-
-		deleteQueueFirstOptions := []bool{true, false}
-		for _, deleteQueueFirst := range deleteQueueFirstOptions {
-
-			if err := channel.ExchangeDeclare(
-				exchangeName, // name
-				"direct",     // type
-				true,         // duration (note: is durable)
-				false,        // auto-delete
-				false,        // internal
-				false,        // nowait
-				nil,          // args
-			); err != nil {
-				t.Fatalf("declare exchange: %s", err)
-			}
-			t.Logf("declare exchange OK")
-
-			if _, err := channel.QueueDeclare(
-				queueName, // name
-				true,      // duration (note: durable)
-				false,     // auto-delete
-				false,     // exclusive
-				false,     // noWait
-				nil,       // arguments
-			); err != nil {
-				t.Fatalf("queue declare: %s", err)
-			}
-			t.Logf("declare queue OK")
-
-			if err := channel.QueueBind(
-				queueName,    // name
-				"",           // routingKey
-				exchangeName, // sourceExchange
-				false,        // noWait
-				nil,          // arguments
-			); err != nil {
-				t.Fatalf("queue bind: %s", err)
-			}
-			t.Logf("queue bind OK")
-
-			if deleteQueueFirst {
-				if _, err := channel.QueueDelete(
-					queueName, // name
-					false,     // ifUnused (false=be aggressive)
-					false,     // ifEmpty (false=be aggressive)
-					false,     // noWait
-				); err != nil {
-					t.Fatalf("delete queue (first): %s", err)
-				}
-				t.Logf("delete queue (first) OK")
-
-				if err := channel.ExchangeDelete(exchangeName, false, false); err != nil {
-					t.Fatalf("delete exchange (after delete queue): %s", err)
-				}
-				t.Logf("delete exchange (after delete queue) OK")
-
-			} else { // deleteExchangeFirst
-				if err := channel.ExchangeDelete(exchangeName, false, false); err != nil {
-					t.Fatalf("delete exchange (first): %s", err)
-				}
-				t.Logf("delete exchange (first) OK")
-
-				if _, err := channel.QueueInspect(queueName); err != nil {
-					t.Fatalf("inspect queue state after deleting exchange: %s", err)
-				}
-				t.Logf("queue properly remains after exchange is deleted")
-
-				if _, err := channel.QueueDelete(
-					queueName,
-					false, // ifUnused
-					false, // ifEmpty
-					false, // noWait
-				); err != nil {
-					t.Fatalf("delete queue (after delete exchange): %s", err)
-				}
-				t.Logf("delete queue (after delete exchange) OK")
-			}
-		}
-
-		if err := channel.Close(); err != nil {
-			t.Fatalf("close channel: %s", err)
-		}
-		t.Logf("close channel OK")
-	}
-}
-
-func TestIntegrationConnectionNegotiatesMaxChannels(t *testing.T) {
-	config := Config{ChannelMax: 0}
-
-	c, err := DialConfig(integrationURLFromEnv(), config)
-	if err != nil {
-		t.Errorf("expected to dial with config %+v integration server: %s", config, err)
-	}
-	defer c.Close()
-
-	if want, got := defaultChannelMax, c.Config.ChannelMax; want != got {
-		t.Fatalf("expected connection to negotiate uint16 (%d) channels, got: %d", want, got)
-	}
-}
-
-func TestIntegrationConnectionNegotiatesClientMaxChannels(t *testing.T) {
-	config := Config{ChannelMax: 16}
-
-	c, err := DialConfig(integrationURLFromEnv(), config)
-	if err != nil {
-		t.Errorf("expected to dial with config %+v integration server: %s", config, err)
-	}
-	defer c.Close()
-
-	if want, got := config.ChannelMax, c.Config.ChannelMax; want != got {
-		t.Fatalf("expected client specified channel limit after handshake %d, got: %d", want, got)
-	}
-}
-
-func TestIntegrationChannelIDsExhausted(t *testing.T) {
-	config := Config{ChannelMax: 16}
-
-	c, err := DialConfig(integrationURLFromEnv(), config)
-	if err != nil {
-		t.Errorf("expected to dial with config %+v integration server: %s", config, err)
-	}
-	defer c.Close()
-
-	for i := 1; i <= c.Config.ChannelMax; i++ {
-		if _, err := c.Channel(); err != nil {
-			t.Fatalf("expected allocating all channel ids to succed, failed on %d with %v", i, err)
-		}
-	}
-
-	if _, err := c.Channel(); err != ErrChannelMax {
-		t.Fatalf("expected allocating all channels to produce the client side error %#v, got: %#v", ErrChannelMax, err)
-	}
-}
-
-func TestIntegrationChannelClosing(t *testing.T) {
-	c := integrationConnection(t, "closings")
-	if c != nil {
-		defer c.Close()
-
-		// This function is run on every channel after it is successfully
-		// opened. It can do something to verify something. It should be
-		// quick; many channels may be opened!
-		f := func(t *testing.T, c *Channel) {
-			return
-		}
-
-		// open and close
-		channel, err := c.Channel()
-		if err != nil {
-			t.Fatalf("basic create channel: %s", err)
-		}
-		t.Logf("basic create channel OK")
-
-		if err := channel.Close(); err != nil {
-			t.Fatalf("basic close channel: %s", err)
-		}
-		t.Logf("basic close channel OK")
-
-		// deferred close
-		signal := make(chan bool)
-		go func() {
-			channel, err := c.Channel()
-			if err != nil {
-				t.Fatalf("second create channel: %s", err)
-			}
-			t.Logf("second create channel OK")
-
-			<-signal // a bit of synchronization
-			f(t, channel)
-
-			defer func() {
-				if err := channel.Close(); err != nil {
-					t.Fatalf("deferred close channel: %s", err)
-				}
-				t.Logf("deferred close channel OK")
-				signal <- true
-			}()
-		}()
-		signal <- true
-		select {
-		case <-signal:
-			t.Logf("(got close signal OK)")
-			break
-		case <-time.After(250 * time.Millisecond):
-			t.Fatalf("deferred close: timeout")
-		}
-
-		// multiple channels
-		for _, n := range []int{2, 4, 8, 16, 32, 64, 128, 256} {
-			channels := make([]*Channel, n)
-			for i := 0; i < n; i++ {
-				var err error
-				if channels[i], err = c.Channel(); err != nil {
-					t.Fatalf("create channel %d/%d: %s", i+1, n, err)
-				}
-			}
-			f(t, channel)
-			for i, channel := range channels {
-				if err := channel.Close(); err != nil {
-					t.Fatalf("close channel %d/%d: %s", i+1, n, err)
-				}
-			}
-			t.Logf("created/closed %d channels OK", n)
-		}
-
-	}
-}
-
-func TestIntegrationMeaningfulChannelErrors(t *testing.T) {
-	c := integrationConnection(t, "pub")
-	if c != nil {
-		defer c.Close()
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Fatalf("Could not create channel")
-		}
-
-		queue := "test.integration.channel.error"
-
-		_, err = ch.QueueDeclare(queue, false, true, false, false, nil)
-		if err != nil {
-			t.Fatalf("Could not declare")
-		}
-
-		_, err = ch.QueueDeclare(queue, true, false, false, false, nil)
-		if err == nil {
-			t.Fatalf("Expected error, got nil")
-		}
-
-		e, ok := err.(*Error)
-		if !ok {
-			t.Fatalf("Expected type Error response, got %T", err)
-		}
-
-		if e.Code != PreconditionFailed {
-			t.Fatalf("Expected PreconditionFailed, got: %+v", e)
-		}
-
-		_, err = ch.QueueDeclare(queue, false, true, false, false, nil)
-		if err != ErrClosed {
-			t.Fatalf("Expected channel to be closed, got: %T", err)
-		}
-	}
-}
-
-// https://github.com/streadway/amqp/issues/6
-func TestIntegrationNonBlockingClose(t *testing.T) {
-	c := integrationConnection(t, "#6")
-	if c != nil {
-		defer c.Close()
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Fatalf("Could not create channel")
-		}
-
-		queue := "test.integration.blocking.close"
-
-		_, err = ch.QueueDeclare(queue, false, true, false, false, nil)
-		if err != nil {
-			t.Fatalf("Could not declare")
-		}
-
-		msgs, err := ch.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Fatalf("Could not consume")
-		}
-
-		// Simulate a consumer
-		go func() {
-			for _ = range msgs {
-				t.Logf("Oh my, received message on an empty queue")
-			}
-		}()
-
-		succeed := make(chan bool)
-
-		go func() {
-			if err = ch.Close(); err != nil {
-				t.Fatalf("Close produced an error when it shouldn't")
-			}
-			succeed <- true
-		}()
-
-		select {
-		case <-succeed:
-			break
-		case <-time.After(1 * time.Second):
-			t.Fatalf("Close timed out after 1s")
-		}
-	}
-}
-
-func TestIntegrationPublishConsume(t *testing.T) {
-	queue := "test.integration.publish.consume"
-
-	c1 := integrationConnection(t, "pub")
-	c2 := integrationConnection(t, "sub")
-
-	if c1 != nil && c2 != nil {
-		defer c1.Close()
-		defer c2.Close()
-
-		pub, _ := c1.Channel()
-		sub, _ := c2.Channel()
-
-		pub.QueueDeclare(queue, false, true, false, false, nil)
-		sub.QueueDeclare(queue, false, true, false, false, nil)
-		defer pub.QueueDelete(queue, false, false, false)
-
-		messages, _ := sub.Consume(queue, "", false, false, false, false, nil)
-
-		pub.Publish("", queue, false, false, Publishing{Body: []byte("pub 1")})
-		pub.Publish("", queue, false, false, Publishing{Body: []byte("pub 2")})
-		pub.Publish("", queue, false, false, Publishing{Body: []byte("pub 3")})
-
-		assertConsumeBody(t, messages, []byte("pub 1"))
-		assertConsumeBody(t, messages, []byte("pub 2"))
-		assertConsumeBody(t, messages, []byte("pub 3"))
-	}
-}
-
-func TestIntegrationConsumeFlow(t *testing.T) {
-	queue := "test.integration.consumer-flow"
-
-	c1 := integrationConnection(t, "pub-flow")
-	c2 := integrationConnection(t, "sub-flow")
-
-	if c1 != nil && c2 != nil {
-		defer c1.Close()
-		defer c2.Close()
-
-		pub, _ := c1.Channel()
-		sub, _ := c2.Channel()
-
-		pub.QueueDeclare(queue, false, true, false, false, nil)
-		sub.QueueDeclare(queue, false, true, false, false, nil)
-		defer pub.QueueDelete(queue, false, false, false)
-
-		sub.Qos(1, 0, false)
-
-		messages, _ := sub.Consume(queue, "", false, false, false, false, nil)
-
-		pub.Publish("", queue, false, false, Publishing{Body: []byte("pub 1")})
-		pub.Publish("", queue, false, false, Publishing{Body: []byte("pub 2")})
-
-		msg := assertConsumeBody(t, messages, []byte("pub 1"))
-
-		if err := sub.Flow(false); err.(*Error).Code == NotImplemented {
-			t.Log("flow control is not supported on this version of rabbitmq")
-			return
-		}
-
-		msg.Ack(false)
-
-		select {
-		case <-messages:
-			t.Fatalf("message was delivered when flow was not active")
-		default:
-		}
-
-		sub.Flow(true)
-
-		msg = assertConsumeBody(t, messages, []byte("pub 2"))
-		msg.Ack(false)
-	}
-}
-
-func TestIntegrationRecoverNotImplemented(t *testing.T) {
-	queue := "test.recover"
-
-	if c, ch := integrationQueue(t, queue); c != nil {
-		if product, ok := c.Properties["product"]; ok && product.(string) == "RabbitMQ" {
-			defer c.Close()
-
-			err := ch.Recover(false)
-
-			if ex, ok := err.(*Error); !ok || ex.Code != 540 {
-				t.Fatalf("Expected NOT IMPLEMENTED got: %v", ex)
-			}
-		}
-	}
-}
-
-// This test is driven by a private API to simulate the server sending a channelFlow message
-func TestIntegrationPublishFlow(t *testing.T) {
-	// TODO - no idea how to test without affecting the server or mucking internal APIs
-	// i'd like to make sure the RW lock can be held by multiple publisher threads
-	// and that multiple channelFlow messages do not block the dispatch thread
-}
-
-func TestIntegrationConsumeCancel(t *testing.T) {
-	queue := "test.integration.consume-cancel"
-
-	c := integrationConnection(t, "pub")
-
-	if c != nil {
-		defer c.Close()
-
-		ch, _ := c.Channel()
-
-		ch.QueueDeclare(queue, false, true, false, false, nil)
-		defer ch.QueueDelete(queue, false, false, false)
-
-		messages, _ := ch.Consume(queue, "integration-tag", false, false, false, false, nil)
-
-		ch.Publish("", queue, false, false, Publishing{Body: []byte("1")})
-
-		assertConsumeBody(t, messages, []byte("1"))
-
-		err := ch.Cancel("integration-tag", false)
-		if err != nil {
-			t.Fatalf("error cancelling the consumer: %v", err)
-		}
-
-		ch.Publish("", queue, false, false, Publishing{Body: []byte("2")})
-
-		select {
-		case <-time.After(100 * time.Millisecond):
-			t.Fatalf("Timeout on Close")
-		case _, ok := <-messages:
-			if ok {
-				t.Fatalf("Extra message on consumer when consumer should have been closed")
-			}
-		}
-	}
-}
-
-func (c *Connection) Generate(r *rand.Rand, _ int) reflect.Value {
-	urlStr := os.Getenv("AMQP_URL")
-	if urlStr == "" {
-		return reflect.ValueOf(nil)
-	}
-
-	conn, err := Dial(urlStr)
-	if err != nil {
-		return reflect.ValueOf(nil)
-	}
-
-	return reflect.ValueOf(conn)
-}
-
-func (c Publishing) Generate(r *rand.Rand, _ int) reflect.Value {
-	var ok bool
-	var t reflect.Value
-
-	p := Publishing{}
-	//p.DeliveryMode = uint8(r.Intn(3))
-	//p.Priority = uint8(r.Intn(8))
-
-	if r.Intn(2) > 0 {
-		p.ContentType = "application/octet-stream"
-	}
-
-	if r.Intn(2) > 0 {
-		p.ContentEncoding = "gzip"
-	}
-
-	if r.Intn(2) > 0 {
-		p.CorrelationId = fmt.Sprintf("%d", r.Int())
-	}
-
-	if r.Intn(2) > 0 {
-		p.ReplyTo = fmt.Sprintf("%d", r.Int())
-	}
-
-	if r.Intn(2) > 0 {
-		p.MessageId = fmt.Sprintf("%d", r.Int())
-	}
-
-	if r.Intn(2) > 0 {
-		p.Type = fmt.Sprintf("%d", r.Int())
-	}
-
-	if r.Intn(2) > 0 {
-		p.AppId = fmt.Sprintf("%d", r.Int())
-	}
-
-	if r.Intn(2) > 0 {
-		p.Timestamp = time.Unix(r.Int63(), r.Int63())
-	}
-
-	if t, ok = quick.Value(reflect.TypeOf(p.Body), r); ok {
-		p.Body = t.Bytes()
-	}
-
-	return reflect.ValueOf(p)
-}
-
-func TestQuickPublishOnly(t *testing.T) {
-	if c := integrationConnection(t, "quick"); c != nil {
-		defer c.Close()
-		pub, err := c.Channel()
-		queue := "test-publish"
-
-		if _, err = pub.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Errorf("Failed to declare: %s", err)
-			return
-		}
-
-		defer pub.QueueDelete(queue, false, false, false)
-
-		quick.Check(func(msg Publishing) bool {
-			return pub.Publish("", queue, false, false, msg) == nil
-		}, nil)
-	}
-}
-
-func TestPublishEmptyBody(t *testing.T) {
-	c := integrationConnection(t, "empty")
-	if c != nil {
-		defer c.Close()
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Errorf("Failed to create channel")
-			return
-		}
-
-		queue := "test-TestPublishEmptyBody"
-
-		if _, err := ch.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Fatalf("Could not declare")
-		}
-
-		messages, err := ch.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Fatalf("Could not consume")
-		}
-
-		err = ch.Publish("", queue, false, false, Publishing{})
-		if err != nil {
-			t.Fatalf("Could not publish")
-		}
-
-		select {
-		case msg := <-messages:
-			if len(msg.Body) != 0 {
-				t.Errorf("Received non empty body")
-			}
-		case <-time.After(200 * time.Millisecond):
-			t.Errorf("Timeout on receive")
-		}
-	}
-}
-
-func TestPublishEmptyBodyWithHeadersIssue67(t *testing.T) {
-	c := integrationConnection(t, "issue67")
-	if c != nil {
-		defer c.Close()
-
-		ch, err := c.Channel()
-		if err != nil {
-			t.Errorf("Failed to create channel")
-			return
-		}
-
-		queue := "test-TestPublishEmptyBodyWithHeaders"
-
-		if _, err := ch.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Fatalf("Could not declare")
-		}
-
-		messages, err := ch.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Fatalf("Could not consume")
-		}
-
-		headers := Table{
-			"ham": "spam",
-		}
-
-		err = ch.Publish("", queue, false, false, Publishing{Headers: headers})
-		if err != nil {
-			t.Fatalf("Could not publish")
-		}
-
-		select {
-		case msg := <-messages:
-			if msg.Headers["ham"] == nil {
-				t.Fatalf("Headers aren't sent")
-			}
-			if msg.Headers["ham"] != "spam" {
-				t.Fatalf("Headers are wrong")
-			}
-		case <-time.After(200 * time.Millisecond):
-			t.Errorf("Timeout on receive")
-		}
-	}
-}
-
-func TestQuickPublishConsumeOnly(t *testing.T) {
-	c1 := integrationConnection(t, "quick-pub")
-	c2 := integrationConnection(t, "quick-sub")
-
-	if c1 != nil && c2 != nil {
-		defer c1.Close()
-		defer c2.Close()
-
-		pub, err := c1.Channel()
-		sub, err := c2.Channel()
-
-		queue := "TestPublishConsumeOnly"
-
-		if _, err = pub.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Errorf("Failed to declare: %s", err)
-			return
-		}
-
-		if _, err = sub.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Errorf("Failed to declare: %s", err)
-			return
-		}
-
-		defer sub.QueueDelete(queue, false, false, false)
-
-		ch, err := sub.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Errorf("Could not sub: %s", err)
-		}
-
-		quick.CheckEqual(
-			func(msg Publishing) []byte {
-				empty := Publishing{Body: msg.Body}
-				if pub.Publish("", queue, false, false, empty) != nil {
-					return []byte{'X'}
-				}
-				return msg.Body
-			},
-			func(msg Publishing) []byte {
-				out := <-ch
-				out.Ack(false)
-				return out.Body
-			},
-			nil)
-	}
-}
-
-func TestQuickPublishConsumeBigBody(t *testing.T) {
-	c1 := integrationConnection(t, "big-pub")
-	c2 := integrationConnection(t, "big-sub")
-
-	if c1 != nil && c2 != nil {
-		defer c1.Close()
-		defer c2.Close()
-
-		pub, err := c1.Channel()
-		sub, err := c2.Channel()
-
-		queue := "test-pubsub"
-
-		if _, err = sub.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Errorf("Failed to declare: %s", err)
-			return
-		}
-
-		ch, err := sub.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Errorf("Could not sub: %s", err)
-		}
-
-		fixture := Publishing{
-			Body: make([]byte, 1e4+1000),
-		}
-
-		if _, err = pub.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Errorf("Failed to declare: %s", err)
-			return
-		}
-
-		err = pub.Publish("", queue, false, false, fixture)
-		if err != nil {
-			t.Errorf("Could not publish big body")
-		}
-
-		select {
-		case msg := <-ch:
-			if bytes.Compare(msg.Body, fixture.Body) != 0 {
-				t.Errorf("Consumed big body didn't match")
-			}
-		case <-time.After(200 * time.Millisecond):
-			t.Errorf("Timeout on receive")
-		}
-	}
-}
-
-func TestIntegrationGetOk(t *testing.T) {
-	if c := integrationConnection(t, "getok"); c != nil {
-		defer c.Close()
-
-		queue := "test.get-ok"
-		ch, _ := c.Channel()
-
-		ch.QueueDeclare(queue, false, true, false, false, nil)
-		ch.Publish("", queue, false, false, Publishing{Body: []byte("ok")})
-
-		msg, ok, err := ch.Get(queue, false)
-
-		if err != nil {
-			t.Fatalf("Failed get: %v", err)
-		}
-
-		if !ok {
-			t.Fatalf("Get on a queued message did not find the message")
-		}
-
-		if string(msg.Body) != "ok" {
-			t.Fatalf("Get did not get the correct message")
-		}
-	}
-}
-
-func TestIntegrationGetEmpty(t *testing.T) {
-	if c := integrationConnection(t, "getok"); c != nil {
-		defer c.Close()
-
-		queue := "test.get-ok"
-		ch, _ := c.Channel()
-
-		ch.QueueDeclare(queue, false, true, false, false, nil)
-
-		_, ok, err := ch.Get(queue, false)
-
-		if err != nil {
-			t.Fatalf("Failed get: %v", err)
-		}
-
-		if !ok {
-			t.Fatalf("Get on a queued message retrieved a message when it shouldn't have")
-		}
-	}
-}
-
-func TestIntegrationTxCommit(t *testing.T) {
-	if c := integrationConnection(t, "txcommit"); c != nil {
-		defer c.Close()
-
-		queue := "test.tx.commit"
-		ch, _ := c.Channel()
-
-		ch.QueueDeclare(queue, false, true, false, false, nil)
-
-		if err := ch.Tx(); err != nil {
-			t.Fatalf("tx.select failed")
-		}
-
-		ch.Publish("", queue, false, false, Publishing{Body: []byte("ok")})
-
-		if err := ch.TxCommit(); err != nil {
-			t.Fatalf("tx.commit failed")
-		}
-
-		msg, ok, err := ch.Get(queue, false)
-
-		if err != nil || !ok {
-			t.Fatalf("Failed get: %v", err)
-		}
-
-		if string(msg.Body) != "ok" {
-			t.Fatalf("Get did not get the correct message from the transaction")
-		}
-	}
-}
-
-func TestIntegrationTxRollback(t *testing.T) {
-	if c := integrationConnection(t, "txrollback"); c != nil {
-		defer c.Close()
-
-		queue := "test.tx.rollback"
-		ch, _ := c.Channel()
-
-		ch.QueueDeclare(queue, false, true, false, false, nil)
-
-		if err := ch.Tx(); err != nil {
-			t.Fatalf("tx.select failed")
-		}
-
-		ch.Publish("", queue, false, false, Publishing{Body: []byte("ok")})
-
-		if err := ch.TxRollback(); err != nil {
-			t.Fatalf("tx.rollback failed")
-		}
-
-		_, ok, err := ch.Get(queue, false)
-
-		if err != nil {
-			t.Fatalf("Failed get: %v", err)
-		}
-
-		if ok {
-			t.Fatalf("message was published when it should have been rolled back")
-		}
-	}
-}
-
-func TestIntegrationReturn(t *testing.T) {
-	if c, ch := integrationQueue(t, "return"); c != nil {
-		defer c.Close()
-
-		ret := make(chan Return, 1)
-
-		ch.NotifyReturn(ret)
-
-		// mandatory publish to an exchange without a binding should be returned
-		ch.Publish("", "return-without-binding", true, false, Publishing{Body: []byte("mandatory")})
-
-		select {
-		case res := <-ret:
-			if string(res.Body) != "mandatory" {
-				t.Fatalf("expected return of the same message")
-			}
-
-			if res.ReplyCode != NoRoute {
-				t.Fatalf("expected no consumers reply code on the Return result, got: %v", res.ReplyCode)
-			}
-
-		case <-time.After(200 * time.Millisecond):
-			t.Fatalf("no return was received within 200ms")
-		}
-	}
-}
-
-func TestIntegrationCancel(t *testing.T) {
-	queue := "cancel"
-	consumerTag := "test.cancel"
-
-	if c, ch := integrationQueue(t, queue); c != nil {
-		defer c.Close()
-
-		cancels := ch.NotifyCancel(make(chan string, 1))
-
-		go func() {
-			if _, err := ch.Consume(queue, consumerTag, false, false, false, false, nil); err != nil {
-				t.Fatalf("cannot consume from %q to test NotifyCancel: %v", queue, err)
-			}
-			if _, err := ch.QueueDelete(queue, false, false, false); err != nil {
-				t.Fatalf("cannot delete integration queue: %v", err)
-			}
-		}()
-
-		select {
-		case tag := <-cancels:
-			if want, got := consumerTag, tag; want != got {
-				t.Fatalf("expected to be notified of deleted queue with consumer tag, got: %q", got)
-			}
-		case <-time.After(200 * time.Millisecond):
-			t.Fatalf("expected to be notified of deleted queue with 200ms")
-		}
-	}
-}
-
-func TestIntegrationConfirm(t *testing.T) {
-	if c, ch := integrationQueue(t, "confirm"); c != nil {
-		defer c.Close()
-
-		ack, nack := make(chan uint64, 1), make(chan uint64, 1)
-
-		ch.NotifyConfirm(ack, nack)
-
-		if err := ch.Confirm(false); err != nil {
-			t.Fatalf("could not confirm")
-		}
-
-		ch.Publish("", "confirm", false, false, Publishing{Body: []byte("confirm")})
-
-		select {
-		case tag := <-ack:
-			if tag != 1 {
-				t.Fatalf("expected ack starting with delivery tag of 1")
-			}
-		case <-time.After(200 * time.Millisecond):
-			t.Fatalf("no ack was received within 200ms")
-		}
-	}
-}
-
-// https://github.com/streadway/amqp/issues/61
-func TestRoundTripAllFieldValueTypes61(t *testing.T) {
-	if conn := integrationConnection(t, "issue61"); conn != nil {
-		defer conn.Close()
-		timestamp := time.Unix(100000000, 0)
-
-		headers := Table{
-			"A": []interface{}{
-				[]interface{}{"nested array", int32(3)},
-				Decimal{2, 1},
-				Table{"S": "nested table in array"},
-				int32(2 << 20),
-				string("array string"),
-				timestamp,
-				nil,
-				byte(2),
-				float64(2.64),
-				float32(2.32),
-				int64(2 << 60),
-				int16(2 << 10),
-				bool(true),
-				[]byte{'b', '2'},
-			},
-			"D": Decimal{1, 1},
-			"F": Table{"S": "nested table in table"},
-			"I": int32(1 << 20),
-			"S": string("string"),
-			"T": timestamp,
-			"V": nil,
-			"b": byte(1),
-			"d": float64(1.64),
-			"f": float32(1.32),
-			"l": int64(1 << 60),
-			"s": int16(1 << 10),
-			"t": bool(true),
-			"x": []byte{'b', '1'},
-		}
-
-		queue := "test.issue61-roundtrip"
-		ch, _ := conn.Channel()
-
-		if _, err := ch.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Fatalf("Could not declare")
-		}
-
-		msgs, err := ch.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Fatalf("Could not consume")
-		}
-
-		err = ch.Publish("", queue, false, false, Publishing{Body: []byte("ignored"), Headers: headers})
-		if err != nil {
-			t.Fatalf("Could not publish: %v", err)
-		}
-
-		msg, ok := <-msgs
-
-		if !ok {
-			t.Fatalf("Channel closed prematurely likely due to publish exception")
-		}
-
-		for k, v := range headers {
-			if !reflect.DeepEqual(v, msg.Headers[k]) {
-				t.Errorf("Round trip header not the same for key %q: expected: %#v, got %#v", k, v, msg.Headers[k])
-			}
-		}
-	}
-}
-
-// Declares a queue with the x-message-ttl extension to exercise integer
-// serialization.
-//
-// Relates to https://github.com/streadway/amqp/issues/60
-//
-func TestDeclareArgsXMessageTTL(t *testing.T) {
-	if conn := integrationConnection(t, "declareTTL"); conn != nil {
-		defer conn.Close()
-
-		ch, _ := conn.Channel()
-		args := Table{"x-message-ttl": int32(9000000)}
-
-		// should not drop the connection
-		if _, err := ch.QueueDeclare("declareWithTTL", false, true, false, false, args); err != nil {
-			t.Fatalf("cannot declare with TTL: got: %v", err)
-		}
-	}
-}
-
-// Sets up the topology where rejected messages will be forwarded
-// to a fanout exchange, with a single queue bound.
-//
-// Relates to https://github.com/streadway/amqp/issues/56
-//
-func TestDeclareArgsRejectToDeadLetterQueue(t *testing.T) {
-	if conn := integrationConnection(t, "declareArgs"); conn != nil {
-		defer conn.Close()
-
-		ex, q := "declareArgs", "declareArgs-deliveries"
-		dlex, dlq := ex+"-dead-letter", q+"-dead-letter"
-
-		ch, _ := conn.Channel()
-
-		if err := ch.ExchangeDeclare(ex, "fanout", false, true, false, false, nil); err != nil {
-			t.Fatalf("cannot declare %v: got: %v", ex, err)
-		}
-
-		if err := ch.ExchangeDeclare(dlex, "fanout", false, true, false, false, nil); err != nil {
-			t.Fatalf("cannot declare %v: got: %v", dlex, err)
-		}
-
-		if _, err := ch.QueueDeclare(dlq, false, true, false, false, nil); err != nil {
-			t.Fatalf("cannot declare %v: got: %v", dlq, err)
-		}
-
-		if err := ch.QueueBind(dlq, "#", dlex, false, nil); err != nil {
-			t.Fatalf("cannot bind %v to %v: got: %v", dlq, dlex, err)
-		}
-
-		if _, err := ch.QueueDeclare(q, false, true, false, false, Table{
-			"x-dead-letter-exchange": dlex,
-		}); err != nil {
-			t.Fatalf("cannot declare %v with dlq %v: got: %v", q, dlex, err)
-		}
-
-		if err := ch.QueueBind(q, "#", ex, false, nil); err != nil {
-			t.Fatalf("cannot bind %v: got: %v", ex, err)
-		}
-
-		fails, err := ch.Consume(q, "", false, false, false, false, nil)
-		if err != nil {
-			t.Fatalf("cannot consume %v: got: %v", q, err)
-		}
-
-		// Reject everything consumed
-		go func() {
-			for d := range fails {
-				d.Reject(false)
-			}
-		}()
-
-		// Publish the 'poison'
-		if err := ch.Publish(ex, q, true, false, Publishing{Body: []byte("ignored")}); err != nil {
-			t.Fatalf("publishing failed")
-		}
-
-		// spin-get until message arrives on the dead-letter queue with a
-		// synchronous parse to exercise the array field (x-death) set by the
-		// server relating to issue-56
-		for i := 0; i < 10; i++ {
-			d, got, err := ch.Get(dlq, false)
-			if !got && err == nil {
-				continue
-			} else if err != nil {
-				t.Fatalf("expected success in parsing reject, got: %v", err)
-			} else {
-				// pass if we've parsed an array
-				if v, ok := d.Headers["x-death"]; ok {
-					if _, ok := v.([]interface{}); ok {
-						return
-					}
-				}
-				t.Fatalf("array field x-death expected in the headers, got: %v (%T)", d.Headers, d.Headers["x-death"])
-			}
-		}
-
-		t.Fatalf("expectd dead-letter after 10 get attempts")
-	}
-}
-
-// https://github.com/streadway/amqp/issues/48
-func TestDeadlockConsumerIssue48(t *testing.T) {
-	if conn := integrationConnection(t, "issue48"); conn != nil {
-		defer conn.Close()
-
-		deadline := make(chan bool)
-		go func() {
-			select {
-			case <-time.After(5 * time.Second):
-				panic("expected to receive 2 deliveries while in an RPC, got a deadlock")
-			case <-deadline:
-				// pass
-			}
-		}()
-
-		ch, err := conn.Channel()
-		if err != nil {
-			t.Fatalf("got error on channel.open: %v", err)
-		}
-
-		queue := "test-issue48"
-
-		if _, err := ch.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Fatalf("expected to declare a queue: %v", err)
-		}
-
-		if err := ch.Confirm(false); err != nil {
-			t.Fatalf("got error on confirm: %v", err)
-		}
-
-		ack, nack := make(chan uint64, 2), make(chan uint64, 2)
-		ch.NotifyConfirm(ack, nack)
-
-		for i := 0; i < cap(ack); i++ {
-			// Fill the queue with some new or remaining publishings
-			ch.Publish("", queue, false, false, Publishing{Body: []byte("")})
-		}
-
-		for i := 0; i < cap(ack); i++ {
-			// Wait for them to land on the queue so they'll be delivered on consume
-			<-ack
-		}
-
-		// Consuming should send them all on the wire
-		msgs, err := ch.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Fatalf("got error on consume: %v", err)
-		}
-
-		// We pop one off the chan, the other is on the wire
-		<-msgs
-
-		// Opening a new channel (any RPC) while another delivery is on the wire
-		if _, err := conn.Channel(); err != nil {
-			t.Fatalf("got error on consume: %v", err)
-		}
-
-		// We pop the next off the chan
-		<-msgs
-
-		deadline <- true
-	}
-}
-
-// https://github.com/streadway/amqp/issues/46
-func TestRepeatedChannelExceptionWithPublishAndMaxProcsIssue46(t *testing.T) {
-	conn := integrationConnection(t, "issue46")
-	if conn != nil {
-		for i := 0; i < 100; i++ {
-			ch, err := conn.Channel()
-			if err != nil {
-				t.Fatalf("expected error only on publish, got error on channel.open: %v", err)
-			}
-
-			for j := 0; j < 10; j++ {
-				err = ch.Publish("not-existing-exchange", "some-key", false, false, Publishing{Body: []byte("some-data")})
-				if err, ok := err.(Error); ok {
-					if err.Code != 504 {
-						t.Fatalf("expected channel only exception, got: %v", err)
-					}
-				}
-			}
-		}
-	}
-}
-
-// https://github.com/streadway/amqp/issues/43
-func TestChannelExceptionWithCloseIssue43(t *testing.T) {
-	conn := integrationConnection(t, "issue43")
-	if conn != nil {
-		go func() {
-			for err := range conn.NotifyClose(make(chan *Error)) {
-				t.Log(err.Error())
-			}
-		}()
-
-		c1, err := conn.Channel()
-		if err != nil {
-			panic(err)
-		}
-
-		go func() {
-			for err := range c1.NotifyClose(make(chan *Error)) {
-				t.Log("Channel1 Close: " + err.Error())
-			}
-		}()
-
-		c2, err := conn.Channel()
-		if err != nil {
-			panic(err)
-		}
-
-		go func() {
-			for err := range c2.NotifyClose(make(chan *Error)) {
-				t.Log("Channel2 Close: " + err.Error())
-			}
-		}()
-
-		// Cause an asynchronous channel exception causing the server
-		// to send a "channel.close" method either before or after the next
-		// asynchronous method.
-		err = c1.Publish("nonexisting-exchange", "", false, false, Publishing{})
-		if err != nil {
-			panic(err)
-		}
-
-		// Receive or send the channel close method, the channel shuts down
-		// but this expects a channel.close-ok to be received.
-		c1.Close()
-
-		// This ensures that the 2nd channel is unaffected by the channel exception
-		// on channel 1.
-		err = c2.ExchangeDeclare("test-channel-still-exists", "direct", false, true, false, false, nil)
-		if err != nil {
-			panic(err)
-		}
-	}
-}
-
-// https://github.com/streadway/amqp/issues/7
-func TestCorruptedMessageIssue7(t *testing.T) {
-	messageCount := 1024
-
-	c1 := integrationConnection(t, "")
-	c2 := integrationConnection(t, "")
-
-	if c1 != nil && c2 != nil {
-		defer c1.Close()
-		defer c2.Close()
-
-		pub, err := c1.Channel()
-		if err != nil {
-			t.Fatalf("Cannot create Channel")
-		}
-
-		sub, err := c2.Channel()
-		if err != nil {
-			t.Fatalf("Cannot create Channel")
-		}
-
-		queue := "test-corrupted-message-regression"
-
-		if _, err := pub.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Fatalf("Cannot declare")
-		}
-
-		if _, err := sub.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-			t.Fatalf("Cannot declare")
-		}
-
-		msgs, err := sub.Consume(queue, "", false, false, false, false, nil)
-		if err != nil {
-			t.Fatalf("Cannot consume")
-		}
-
-		for i := 0; i < messageCount; i++ {
-			err := pub.Publish("", queue, false, false, Publishing{
-				Body: generateCrc32Random(7 * i),
-			})
-
-			if err != nil {
-				t.Fatalf("Failed to publish")
-			}
-		}
-
-		for i := 0; i < messageCount; i++ {
-			select {
-			case msg := <-msgs:
-				assertMessageCrc32(t, msg.Body, fmt.Sprintf("missed match at %d", i))
-			case <-time.After(200 * time.Millisecond):
-				t.Fatalf("Timeout on recv")
-			}
-		}
-	}
-}
-
-func TestExchangeDeclarePrecondition(t *testing.T) {
-	c1 := integrationConnection(t, "exchange-double-declare")
-	c2 := integrationConnection(t, "exchange-double-declare-cleanup")
-	if c1 != nil && c2 != nil {
-		defer c1.Close()
-		defer c2.Close()
-
-		ch, err := c1.Channel()
-		if err != nil {
-			t.Fatalf("Create channel")
-		}
-
-		exchange := "test-mismatched-redeclare"
-
-		err = ch.ExchangeDeclare(
-			exchange,
-			"direct", // exchangeType
-			false,    // durable
-			true,     // auto-delete
-			false,    // internal
-			false,    // noWait
-			nil,      // arguments
-		)
-		if err != nil {
-			t.Fatalf("Could not initially declare exchange")
-		}
-
-		err = ch.ExchangeDeclare(
-			exchange,
-			"direct",
-			true, // different durability
-			true,
-			false,
-			false,
-			nil,
-		)
-
-		if err == nil {
-			t.Fatalf("Expected to fail a redeclare with different durability, didn't receive an error")
-		}
-
-		if err, ok := err.(Error); ok {
-			if err.Code != PreconditionFailed {
-				t.Fatalf("Expected precondition error")
-			}
-			if !err.Recover {
-				t.Fatalf("Expected to be able to recover")
-			}
-		}
-
-		ch2, _ := c2.Channel()
-		if err = ch2.ExchangeDelete(exchange, false, false); err != nil {
-			t.Fatalf("Could not delete exchange: %v", err)
-		}
-	}
-}
-
-func TestRabbitMQQueueTTLGet(t *testing.T) {
-	if c := integrationRabbitMQ(t, "ttl"); c != nil {
-		defer c.Close()
-
-		queue := "test.rabbitmq-message-ttl"
-		channel, err := c.Channel()
-		if err != nil {
-			t.Fatalf("channel: %v", err)
-		}
-
-		if _, err = channel.QueueDeclare(
-			queue,
-			false,
-			true,
-			false,
-			false,
-			Table{"x-message-ttl": int32(100)}, // in ms
-		); err != nil {
-			t.Fatalf("queue declare: %s", err)
-		}
-
-		channel.Publish("", queue, false, false, Publishing{Body: []byte("ttl")})
-
-		time.Sleep(200 * time.Millisecond)
-
-		_, ok, err := channel.Get(queue, false)
-
-		if ok {
-			t.Fatalf("Expected the message to expire in 100ms, it didn't expire after 200ms")
-		}
-
-		if err != nil {
-			t.Fatalf("Failed to get on ttl queue")
-		}
-	}
-}
-
-func TestRabbitMQQueueNackMultipleRequeue(t *testing.T) {
-	if c := integrationRabbitMQ(t, "nack"); c != nil {
-		defer c.Close()
-
-		if c.isCapable("basic.nack") {
-			queue := "test.rabbitmq-basic-nack"
-			channel, err := c.Channel()
-			if err != nil {
-				t.Fatalf("channel: %v", err)
-			}
-
-			if _, err = channel.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-				t.Fatalf("queue declare: %s", err)
-			}
-
-			channel.Publish("", queue, false, false, Publishing{Body: []byte("1")})
-			channel.Publish("", queue, false, false, Publishing{Body: []byte("2")})
-
-			m1, ok, err := channel.Get(queue, false)
-			if !ok || err != nil || m1.Body[0] != '1' {
-				t.Fatalf("could not get message %v", m1)
-			}
-
-			m2, ok, err := channel.Get(queue, false)
-			if !ok || err != nil || m2.Body[0] != '2' {
-				t.Fatalf("could not get message %v", m2)
-			}
-
-			m2.Nack(true, true)
-
-			m1, ok, err = channel.Get(queue, false)
-			if !ok || err != nil || m1.Body[0] != '1' {
-				t.Fatalf("could not get message %v", m1)
-			}
-
-			m2, ok, err = channel.Get(queue, false)
-			if !ok || err != nil || m2.Body[0] != '2' {
-				t.Fatalf("could not get message %v", m2)
-			}
-		}
-	}
-}
-
-/*
- * Support for integration tests
- */
-
-func integrationURLFromEnv() string {
-	url := os.Getenv("AMQP_URL")
-	if url == "" {
-		url = "amqp://"
-	}
-	return url
-}
-
-func loggedConnection(t *testing.T, conn *Connection, name string) *Connection {
-	if name != "" {
-		conn.conn = &logIO{t, name, conn.conn}
-	}
-	return conn
-}
-
-// Returns a conneciton to the AMQP if the AMQP_URL environment
-// variable is set and a connnection can be established.
-func integrationConnection(t *testing.T, name string) *Connection {
-	conn, err := Dial(integrationURLFromEnv())
-	if err != nil {
-		t.Errorf("dial integration server: %s", err)
-		return nil
-	}
-	return loggedConnection(t, conn, name)
-}
-
-// Returns a connection, channel and delcares a queue when the AMQP_URL is in the environment
-func integrationQueue(t *testing.T, name string) (*Connection, *Channel) {
-	if conn := integrationConnection(t, name); conn != nil {
-		if channel, err := conn.Channel(); err == nil {
-			if _, err = channel.QueueDeclare(name, false, true, false, false, nil); err == nil {
-				return conn, channel
-			}
-		}
-	}
-	return nil, nil
-}
-
-// Delegates to integrationConnection and only returns a connection if the
-// product is RabbitMQ
-func integrationRabbitMQ(t *testing.T, name string) *Connection {
-	if conn := integrationConnection(t, "connect"); conn != nil {
-		if server, ok := conn.Properties["product"]; ok && server == "RabbitMQ" {
-			return conn
-		}
-	}
-
-	return nil
-}
-
-func assertConsumeBody(t *testing.T, messages <-chan Delivery, want []byte) (msg *Delivery) {
-	select {
-	case got := <-messages:
-		if bytes.Compare(want, got.Body) != 0 {
-			t.Fatalf("Message body does not match want: %v, got: %v, for: %+v", want, got.Body, got)
-		}
-		msg = &got
-	case <-time.After(200 * time.Millisecond):
-		t.Fatalf("Timeout waiting for %v", want)
-	}
-
-	return msg
-}
-
-// Pulls out the CRC and verifies the remaining content against the CRC
-func assertMessageCrc32(t *testing.T, msg []byte, assert string) {
-	size := binary.BigEndian.Uint32(msg[:4])
-
-	crc := crc32.NewIEEE()
-	crc.Write(msg[8:])
-
-	if binary.BigEndian.Uint32(msg[4:8]) != crc.Sum32() {
-		t.Fatalf("Message does not match CRC: %s", assert)
-	}
-
-	if int(size) != len(msg)-8 {
-		t.Fatalf("Message does not match size, should=%d, is=%d: %s", size, len(msg)-8, assert)
-	}
-}
-
-// Creates a random body size with a leading 32-bit CRC in network byte order
-// that verifies the remaining slice
-func generateCrc32Random(size int) []byte {
-	msg := make([]byte, size+8)
-	if _, err := io.ReadFull(devrand.Reader, msg); err != nil {
-		panic(err)
-	}
-
-	crc := crc32.NewIEEE()
-	crc.Write(msg[8:])
-
-	binary.BigEndian.PutUint32(msg[0:4], uint32(size))
-	binary.BigEndian.PutUint32(msg[4:8], crc.Sum32())
-
-	return msg
-}

+ 0 - 444
vendor/github.com/streadway/amqp/read.go

@@ -1,444 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"bytes"
-	"encoding/binary"
-	"io"
-	"time"
-)
-
-/*
-Reads a frame from an input stream and returns an interface that can be cast into
-one of the following:
-
-   methodFrame
-   PropertiesFrame
-   bodyFrame
-   heartbeatFrame
-
-2.3.5  frame Details
-
-All frames consist of a header (7 octets), a payload of arbitrary size, and a
-'frame-end' octet that detects malformed frames:
-
-  0      1         3             7                  size+7 size+8
-  +------+---------+-------------+  +------------+  +-----------+
-  | type | channel |     size    |  |  payload   |  | frame-end |
-  +------+---------+-------------+  +------------+  +-----------+
-   octet   short         long         size octets       octet
-
-To read a frame, we:
-  1. Read the header and check the frame type and channel.
-	2. Depending on the frame type, we read the payload and process it.
-  3. Read the frame end octet.
-
-In realistic implementations where performance is a concern, we would use
-“read-ahead buffering” or
-
-“gathering reads” to avoid doing three separate system calls to read a frame.
-*/
-func (me *reader) ReadFrame() (frame frame, err error) {
-	var scratch [7]byte
-
-	if _, err = io.ReadFull(me.r, scratch[:7]); err != nil {
-		return
-	}
-
-	typ := uint8(scratch[0])
-	channel := binary.BigEndian.Uint16(scratch[1:3])
-	size := binary.BigEndian.Uint32(scratch[3:7])
-
-	switch typ {
-	case frameMethod:
-		if frame, err = me.parseMethodFrame(channel, size); err != nil {
-			return
-		}
-
-	case frameHeader:
-		if frame, err = me.parseHeaderFrame(channel, size); err != nil {
-			return
-		}
-
-	case frameBody:
-		if frame, err = me.parseBodyFrame(channel, size); err != nil {
-			return
-		}
-
-	case frameHeartbeat:
-		if frame, err = me.parseHeartbeatFrame(channel, size); err != nil {
-			return
-		}
-
-	default:
-		return nil, ErrFrame
-	}
-
-	if _, err = io.ReadFull(me.r, scratch[:1]); err != nil {
-		return
-	}
-
-	if scratch[0] != frameEnd {
-		return nil, ErrFrame
-	}
-
-	return
-}
-
-func readShortstr(r io.Reader) (v string, err error) {
-	var length uint8
-	if err = binary.Read(r, binary.BigEndian, &length); err != nil {
-		return
-	}
-
-	bytes := make([]byte, length)
-	if _, err = io.ReadFull(r, bytes); err != nil {
-		return
-	}
-	return string(bytes), nil
-}
-
-func readLongstr(r io.Reader) (v string, err error) {
-	var length uint32
-	if err = binary.Read(r, binary.BigEndian, &length); err != nil {
-		return
-	}
-
-	bytes := make([]byte, length)
-	if _, err = io.ReadFull(r, bytes); err != nil {
-		return
-	}
-	return string(bytes), nil
-}
-
-func readDecimal(r io.Reader) (v Decimal, err error) {
-	if err = binary.Read(r, binary.BigEndian, &v.Scale); err != nil {
-		return
-	}
-	if err = binary.Read(r, binary.BigEndian, &v.Value); err != nil {
-		return
-	}
-	return
-}
-
-func readFloat32(r io.Reader) (v float32, err error) {
-	if err = binary.Read(r, binary.BigEndian, &v); err != nil {
-		return
-	}
-	return
-}
-
-func readFloat64(r io.Reader) (v float64, err error) {
-	if err = binary.Read(r, binary.BigEndian, &v); err != nil {
-		return
-	}
-	return
-}
-
-func readTimestamp(r io.Reader) (v time.Time, err error) {
-	var sec int64
-	if err = binary.Read(r, binary.BigEndian, &sec); err != nil {
-		return
-	}
-	return time.Unix(sec, 0), nil
-}
-
-/*
-'A': []interface{}
-'D': Decimal
-'F': Table
-'I': int32
-'S': string
-'T': time.Time
-'V': nil
-'b': byte
-'d': float64
-'f': float32
-'l': int64
-'s': int16
-'t': bool
-'x': []byte
-*/
-func readField(r io.Reader) (v interface{}, err error) {
-	var typ byte
-	if err = binary.Read(r, binary.BigEndian, &typ); err != nil {
-		return
-	}
-
-	switch typ {
-	case 't':
-		var value uint8
-		if err = binary.Read(r, binary.BigEndian, &value); err != nil {
-			return
-		}
-		return (value != 0), nil
-
-	case 'b':
-		var value [1]byte
-		if _, err = io.ReadFull(r, value[0:1]); err != nil {
-			return
-		}
-		return value[0], nil
-
-	case 's':
-		var value int16
-		if err = binary.Read(r, binary.BigEndian, &value); err != nil {
-			return
-		}
-		return value, nil
-
-	case 'I':
-		var value int32
-		if err = binary.Read(r, binary.BigEndian, &value); err != nil {
-			return
-		}
-		return value, nil
-
-	case 'l':
-		var value int64
-		if err = binary.Read(r, binary.BigEndian, &value); err != nil {
-			return
-		}
-		return value, nil
-
-	case 'f':
-		var value float32
-		if err = binary.Read(r, binary.BigEndian, &value); err != nil {
-			return
-		}
-		return value, nil
-
-	case 'd':
-		var value float64
-		if err = binary.Read(r, binary.BigEndian, &value); err != nil {
-			return
-		}
-		return value, nil
-
-	case 'D':
-		return readDecimal(r)
-
-	case 'S':
-		return readLongstr(r)
-
-	case 'A':
-		return readArray(r)
-
-	case 'T':
-		return readTimestamp(r)
-
-	case 'F':
-		return readTable(r)
-
-	case 'x':
-		var len int32
-		if err = binary.Read(r, binary.BigEndian, &len); err != nil {
-			return nil, err
-		}
-
-		value := make([]byte, len)
-		if _, err = io.ReadFull(r, value); err != nil {
-			return nil, err
-		}
-		return value, err
-
-	case 'V':
-		return nil, nil
-	}
-
-	return nil, ErrSyntax
-}
-
-/*
-	Field tables are long strings that contain packed name-value pairs.  The
-	name-value pairs are encoded as short string defining the name, and octet
-	defining the values type and then the value itself.   The valid field types for
-	tables are an extension of the native integer, bit, string, and timestamp
-	types, and are shown in the grammar.  Multi-octet integer fields are always
-	held in network byte order.
-*/
-func readTable(r io.Reader) (table Table, err error) {
-	var nested bytes.Buffer
-	var str string
-
-	if str, err = readLongstr(r); err != nil {
-		return
-	}
-
-	nested.Write([]byte(str))
-
-	table = make(Table)
-
-	for nested.Len() > 0 {
-		var key string
-		var value interface{}
-
-		if key, err = readShortstr(&nested); err != nil {
-			return
-		}
-
-		if value, err = readField(&nested); err != nil {
-			return
-		}
-
-		table[key] = value
-	}
-
-	return
-}
-
-func readArray(r io.Reader) ([]interface{}, error) {
-	var size uint32
-	var err error
-
-	if err = binary.Read(r, binary.BigEndian, &size); err != nil {
-		return nil, err
-	}
-
-	lim := &io.LimitedReader{R: r, N: int64(size)}
-	arr := make([]interface{}, 0)
-	var field interface{}
-
-	for {
-		if field, err = readField(lim); err != nil {
-			if err == io.EOF {
-				break
-			}
-			return nil, err
-		}
-		arr = append(arr, field)
-	}
-
-	return arr, nil
-}
-
-// Checks if this bit mask matches the flags bitset
-func hasProperty(mask uint16, prop int) bool {
-	return int(mask)&prop > 0
-}
-
-func (me *reader) parseHeaderFrame(channel uint16, size uint32) (frame frame, err error) {
-	hf := &headerFrame{
-		ChannelId: channel,
-	}
-
-	if err = binary.Read(me.r, binary.BigEndian, &hf.ClassId); err != nil {
-		return
-	}
-
-	if err = binary.Read(me.r, binary.BigEndian, &hf.weight); err != nil {
-		return
-	}
-
-	if err = binary.Read(me.r, binary.BigEndian, &hf.Size); err != nil {
-		return
-	}
-
-	var flags uint16
-
-	if err = binary.Read(me.r, binary.BigEndian, &flags); err != nil {
-		return
-	}
-
-	if hasProperty(flags, flagContentType) {
-		if hf.Properties.ContentType, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagContentEncoding) {
-		if hf.Properties.ContentEncoding, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagHeaders) {
-		if hf.Properties.Headers, err = readTable(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagDeliveryMode) {
-		if err = binary.Read(me.r, binary.BigEndian, &hf.Properties.DeliveryMode); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagPriority) {
-		if err = binary.Read(me.r, binary.BigEndian, &hf.Properties.Priority); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagCorrelationId) {
-		if hf.Properties.CorrelationId, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagReplyTo) {
-		if hf.Properties.ReplyTo, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagExpiration) {
-		if hf.Properties.Expiration, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagMessageId) {
-		if hf.Properties.MessageId, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagTimestamp) {
-		if hf.Properties.Timestamp, err = readTimestamp(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagType) {
-		if hf.Properties.Type, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagUserId) {
-		if hf.Properties.UserId, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagAppId) {
-		if hf.Properties.AppId, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-	if hasProperty(flags, flagReserved1) {
-		if hf.Properties.reserved1, err = readShortstr(me.r); err != nil {
-			return
-		}
-	}
-
-	return hf, nil
-}
-
-func (me *reader) parseBodyFrame(channel uint16, size uint32) (frame frame, err error) {
-	bf := &bodyFrame{
-		ChannelId: channel,
-		Body:      make([]byte, size),
-	}
-
-	if _, err = io.ReadFull(me.r, bf.Body); err != nil {
-		return
-	}
-
-	return bf, nil
-}
-
-func (me *reader) parseHeartbeatFrame(channel uint16, size uint32) (frame frame, err error) {
-	hf := &heartbeatFrame{
-		ChannelId: channel,
-	}
-
-	if size > 0 {
-		panic("Heartbeats should not have a payload")
-	}
-
-	return hf, nil
-}

+ 0 - 113
vendor/github.com/streadway/amqp/reconnect_test.go

@@ -1,113 +0,0 @@
-package amqp_test
-
-import (
-	"fmt"
-	"github.com/streadway/amqp"
-	"os"
-)
-
-// Every connection should declare the topology they expect
-func setup(url, queue string) (*amqp.Connection, *amqp.Channel, error) {
-	conn, err := amqp.Dial(url)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	ch, err := conn.Channel()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	if _, err := ch.QueueDeclare(queue, false, true, false, false, nil); err != nil {
-		return nil, nil, err
-	}
-
-	return conn, ch, nil
-}
-
-func consume(url, queue string) (*amqp.Connection, <-chan amqp.Delivery, error) {
-	conn, ch, err := setup(url, queue)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// Indicate we only want 1 message to acknowledge at a time.
-	if err := ch.Qos(1, 0, false); err != nil {
-		return nil, nil, err
-	}
-
-	// Exclusive consumer
-	deliveries, err := ch.Consume(queue, "", false, true, false, false, nil)
-
-	return conn, deliveries, err
-}
-
-func ExampleConnection_reconnect() {
-	if url := os.Getenv("AMQP_URL"); url != "" {
-		queue := "example.reconnect"
-
-		// The connection/channel for publishing to interleave the ingress messages
-		// between reconnects, shares the same topology as the consumer.  If we rather
-		// sent all messages up front, the first consumer would receive every message.
-		// We would rather show how the messages are not lost between reconnects.
-		_, pub, err := setup(url, queue)
-		if err != nil {
-			fmt.Println("err publisher setup:", err)
-			return
-		}
-
-		// Purge the queue from the publisher side to establish initial state
-		if _, err := pub.QueuePurge(queue, false); err != nil {
-			fmt.Println("err purge:", err)
-			return
-		}
-
-		// Reconnect simulation, should be for { ... } in production
-		for i := 1; i <= 3; i++ {
-			fmt.Println("connect")
-
-			conn, deliveries, err := consume(url, queue)
-			if err != nil {
-				fmt.Println("err consume:", err)
-				return
-			}
-
-			// Simulate a producer on a different connection showing that consumers
-			// continue where they were left off after each reconnect.
-			if err := pub.Publish("", queue, false, false, amqp.Publishing{
-				Body: []byte(fmt.Sprintf("%d", i)),
-			}); err != nil {
-				fmt.Println("err publish:", err)
-				return
-			}
-
-			// Simulates a consumer that when the range finishes, will setup a new
-			// session and begin ranging over the deliveries again.
-			for msg := range deliveries {
-				fmt.Println(string(msg.Body))
-				msg.Ack(false)
-
-				// Simulate an error like a server restart, loss of route or operator
-				// intervention that results in the connection terminating
-				go conn.Close()
-			}
-		}
-	} else {
-		// pass with expected output when not running in an integration
-		// environment.
-		fmt.Println("connect")
-		fmt.Println("1")
-		fmt.Println("connect")
-		fmt.Println("2")
-		fmt.Println("connect")
-		fmt.Println("3")
-	}
-
-	// Output:
-	// connect
-	// 1
-	// connect
-	// 2
-	// connect
-	// 3
-}

+ 0 - 64
vendor/github.com/streadway/amqp/return.go

@@ -1,64 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"time"
-)
-
-// Return captures a flattened struct of fields returned by the server when a
-// Publishing is unable to be delivered either due to the `mandatory` flag set
-// and no route found, or `immediate` flag set and no free consumer.
-type Return struct {
-	ReplyCode  uint16 // reason
-	ReplyText  string // description
-	Exchange   string // basic.publish exchange
-	RoutingKey string // basic.publish routing key
-
-	// Properties
-	ContentType     string    // MIME content type
-	ContentEncoding string    // MIME content encoding
-	Headers         Table     // Application or header exchange table
-	DeliveryMode    uint8     // queue implemention use - non-persistent (1) or persistent (2)
-	Priority        uint8     // queue implementation use - 0 to 9
-	CorrelationId   string    // application use - correlation identifier
-	ReplyTo         string    // application use - address to to reply to (ex: RPC)
-	Expiration      string    // implementation use - message expiration spec
-	MessageId       string    // application use - message identifier
-	Timestamp       time.Time // application use - message timestamp
-	Type            string    // application use - message type name
-	UserId          string    // application use - creating user id
-	AppId           string    // application use - creating application
-
-	Body []byte
-}
-
-func newReturn(msg basicReturn) *Return {
-	props, body := msg.getContent()
-
-	return &Return{
-		ReplyCode:  msg.ReplyCode,
-		ReplyText:  msg.ReplyText,
-		Exchange:   msg.Exchange,
-		RoutingKey: msg.RoutingKey,
-
-		Headers:         props.Headers,
-		ContentType:     props.ContentType,
-		ContentEncoding: props.ContentEncoding,
-		DeliveryMode:    props.DeliveryMode,
-		Priority:        props.Priority,
-		CorrelationId:   props.CorrelationId,
-		ReplyTo:         props.ReplyTo,
-		Expiration:      props.Expiration,
-		MessageId:       props.MessageId,
-		Timestamp:       props.Timestamp,
-		Type:            props.Type,
-		UserId:          props.UserId,
-		AppId:           props.AppId,
-
-		Body: body,
-	}
-}

+ 0 - 71
vendor/github.com/streadway/amqp/shared_test.go

@@ -1,71 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"encoding/hex"
-	"io"
-	"testing"
-)
-
-type pipe struct {
-	r *io.PipeReader
-	w *io.PipeWriter
-}
-
-func (p pipe) Read(b []byte) (int, error) {
-	return p.r.Read(b)
-}
-
-func (p pipe) Write(b []byte) (int, error) {
-	return p.w.Write(b)
-}
-
-func (p pipe) Close() error {
-	p.r.Close()
-	p.w.Close()
-	return nil
-}
-
-type logIO struct {
-	t      *testing.T
-	prefix string
-	proxy  io.ReadWriteCloser
-}
-
-func (me *logIO) Read(p []byte) (n int, err error) {
-	me.t.Logf("%s reading %d\n", me.prefix, len(p))
-	n, err = me.proxy.Read(p)
-	if err != nil {
-		me.t.Logf("%s read %x: %v\n", me.prefix, p[0:n], err)
-	} else {
-		me.t.Logf("%s read:\n%s\n", me.prefix, hex.Dump(p[0:n]))
-		//fmt.Printf("%s read:\n%s\n", me.prefix, hex.Dump(p[0:n]))
-	}
-	return
-}
-
-func (me *logIO) Write(p []byte) (n int, err error) {
-	me.t.Logf("%s writing %d\n", me.prefix, len(p))
-	n, err = me.proxy.Write(p)
-	if err != nil {
-		me.t.Logf("%s write %d, %x: %v\n", me.prefix, len(p), p[0:n], err)
-	} else {
-		me.t.Logf("%s write %d:\n%s", me.prefix, len(p), hex.Dump(p[0:n]))
-		//fmt.Printf("%s write %d:\n%s", me.prefix, len(p), hex.Dump(p[0:n]))
-	}
-	return
-}
-
-func (me *logIO) Close() (err error) {
-	err = me.proxy.Close()
-	if err != nil {
-		me.t.Logf("%s close : %v\n", me.prefix, err)
-	} else {
-		me.t.Logf("%s close\n", me.prefix, err)
-	}
-	return
-}

+ 0 - 537
vendor/github.com/streadway/amqp/spec/amqp0-9-1.stripped.extended.xml

@@ -1,537 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-     WARNING: Modified from the official 0-9-1 specification XML by
-     the addition of:
-     confirm.select and confirm.select-ok,
-     exchange.bind and exchange.bind-ok,
-     exchange.unbind and exchange.unbind-ok,
-     basic.nack,
-     the ability for the Server to send basic.ack, basic.nack and
-      basic.cancel to the client, and
-     the un-deprecation of exchange.declare{auto-delete} and exchange.declare{internal}
-
-     Modifications are (c) 2010-2013 VMware, Inc. and may be distributed
-     under the same BSD license as below.
--->
-
-<!--
-Copyright (c) 2009 AMQP Working Group.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--->
-<amqp major="0" minor="9" revision="1" port="5672">
-  <constant name="frame-method" value="1"/>
-  <constant name="frame-header" value="2"/>
-  <constant name="frame-body" value="3"/>
-  <constant name="frame-heartbeat" value="8"/>
-  <constant name="frame-min-size" value="4096"/>
-  <constant name="frame-end" value="206"/>
-  <constant name="reply-success" value="200"/>
-  <constant name="content-too-large" value="311" class="soft-error"/>
-  <constant name="no-route" value="312" class = "soft-error">
-    <doc>
-      Errata: Section 1.2 ought to define an exception 312 "No route", which used to
-      exist in 0-9 and is what RabbitMQ sends back with 'basic.return' when a
-      'mandatory' message cannot be delivered to any queue.
-    </doc>
-  </constant>
-  <constant name="no-consumers" value="313" class="soft-error"/>
-  <constant name="connection-forced" value="320" class="hard-error"/>
-  <constant name="invalid-path" value="402" class="hard-error"/>
-  <constant name="access-refused" value="403" class="soft-error"/>
-  <constant name="not-found" value="404" class="soft-error"/>
-  <constant name="resource-locked" value="405" class="soft-error"/>
-  <constant name="precondition-failed" value="406" class="soft-error"/>
-  <constant name="frame-error" value="501" class="hard-error"/>
-  <constant name="syntax-error" value="502" class="hard-error"/>
-  <constant name="command-invalid" value="503" class="hard-error"/>
-  <constant name="channel-error" value="504" class="hard-error"/>
-  <constant name="unexpected-frame" value="505" class="hard-error"/>
-  <constant name="resource-error" value="506" class="hard-error"/>
-  <constant name="not-allowed" value="530" class="hard-error"/>
-  <constant name="not-implemented" value="540" class="hard-error"/>
-  <constant name="internal-error" value="541" class="hard-error"/>
-  <domain name="class-id" type="short"/>
-  <domain name="consumer-tag" type="shortstr"/>
-  <domain name="delivery-tag" type="longlong"/>
-  <domain name="exchange-name" type="shortstr">
-    <assert check="length" value="127"/>
-    <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
-  </domain>
-  <domain name="method-id" type="short"/>
-  <domain name="no-ack" type="bit"/>
-  <domain name="no-local" type="bit"/>
-  <domain name="no-wait" type="bit"/>
-  <domain name="path" type="shortstr">
-    <assert check="notnull"/>
-    <assert check="length" value="127"/>
-  </domain>
-  <domain name="peer-properties" type="table"/>
-  <domain name="queue-name" type="shortstr">
-    <assert check="length" value="127"/>
-    <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
-  </domain>
-  <domain name="redelivered" type="bit"/>
-  <domain name="message-count" type="long"/>
-  <domain name="reply-code" type="short">
-    <assert check="notnull"/>
-  </domain>
-  <domain name="reply-text" type="shortstr">
-    <assert check="notnull"/>
-  </domain>
-  <domain name="bit" type="bit"/>
-  <domain name="octet" type="octet"/>
-  <domain name="short" type="short"/>
-  <domain name="long" type="long"/>
-  <domain name="longlong" type="longlong"/>
-  <domain name="shortstr" type="shortstr"/>
-  <domain name="longstr" type="longstr"/>
-  <domain name="timestamp" type="timestamp"/>
-  <domain name="table" type="table"/>
-  <class name="connection" handler="connection" index="10">
-    <chassis name="server" implement="MUST"/>
-    <chassis name="client" implement="MUST"/>
-    <method name="start" synchronous="1" index="10">
-      <chassis name="client" implement="MUST"/>
-      <response name="start-ok"/>
-      <field name="version-major" domain="octet"/>
-      <field name="version-minor" domain="octet"/>
-      <field name="server-properties" domain="peer-properties"/>
-      <field name="mechanisms" domain="longstr">
-        <assert check="notnull"/>
-      </field>
-      <field name="locales" domain="longstr">
-        <assert check="notnull"/>
-      </field>
-    </method>
-    <method name="start-ok" synchronous="1" index="11">
-      <chassis name="server" implement="MUST"/>
-      <field name="client-properties" domain="peer-properties"/>
-      <field name="mechanism" domain="shortstr">
-        <assert check="notnull"/>
-      </field>
-      <field name="response" domain="longstr">
-        <assert check="notnull"/>
-      </field>
-      <field name="locale" domain="shortstr">
-        <assert check="notnull"/>
-      </field>
-    </method>
-    <method name="secure" synchronous="1" index="20">
-      <chassis name="client" implement="MUST"/>
-      <response name="secure-ok"/>
-      <field name="challenge" domain="longstr"/>
-    </method>
-    <method name="secure-ok" synchronous="1" index="21">
-      <chassis name="server" implement="MUST"/>
-      <field name="response" domain="longstr">
-        <assert check="notnull"/>
-      </field>
-    </method>
-    <method name="tune" synchronous="1" index="30">
-      <chassis name="client" implement="MUST"/>
-      <response name="tune-ok"/>
-      <field name="channel-max" domain="short"/>
-      <field name="frame-max" domain="long"/>
-      <field name="heartbeat" domain="short"/>
-    </method>
-    <method name="tune-ok" synchronous="1" index="31">
-      <chassis name="server" implement="MUST"/>
-      <field name="channel-max" domain="short">
-        <assert check="notnull"/>
-        <assert check="le" method="tune" field="channel-max"/>
-      </field>
-      <field name="frame-max" domain="long"/>
-      <field name="heartbeat" domain="short"/>
-    </method>
-    <method name="open" synchronous="1" index="40">
-      <chassis name="server" implement="MUST"/>
-      <response name="open-ok"/>
-      <field name="virtual-host" domain="path"/>
-      <field name="reserved-1" type="shortstr" reserved="1"/>
-      <field name="reserved-2" type="bit" reserved="1"/>
-    </method>
-    <method name="open-ok" synchronous="1" index="41">
-      <chassis name="client" implement="MUST"/>
-      <field name="reserved-1" type="shortstr" reserved="1"/>
-    </method>
-    <method name="close" synchronous="1" index="50">
-      <chassis name="client" implement="MUST"/>
-      <chassis name="server" implement="MUST"/>
-      <response name="close-ok"/>
-      <field name="reply-code" domain="reply-code"/>
-      <field name="reply-text" domain="reply-text"/>
-      <field name="class-id" domain="class-id"/>
-      <field name="method-id" domain="method-id"/>
-    </method>
-    <method name="close-ok" synchronous="1" index="51">
-      <chassis name="client" implement="MUST"/>
-      <chassis name="server" implement="MUST"/>
-    </method>
-    <method name="blocked" index="60">
-      <chassis name="server" implement="MAY"/>
-      <field name="reason" type="shortstr"/>
-    </method>
-    <method name="unblocked" index="61">
-      <chassis name="server" implement="MAY"/>
-    </method>
-  </class>
-  <class name="channel" handler="channel" index="20">
-    <chassis name="server" implement="MUST"/>
-    <chassis name="client" implement="MUST"/>
-    <method name="open" synchronous="1" index="10">
-      <chassis name="server" implement="MUST"/>
-      <response name="open-ok"/>
-      <field name="reserved-1" type="shortstr" reserved="1"/>
-    </method>
-    <method name="open-ok" synchronous="1" index="11">
-      <chassis name="client" implement="MUST"/>
-      <field name="reserved-1" type="longstr" reserved="1"/>
-    </method>
-    <method name="flow" synchronous="1" index="20">
-      <chassis name="server" implement="MUST"/>
-      <chassis name="client" implement="MUST"/>
-      <response name="flow-ok"/>
-      <field name="active" domain="bit"/>
-    </method>
-    <method name="flow-ok" index="21">
-      <chassis name="server" implement="MUST"/>
-      <chassis name="client" implement="MUST"/>
-      <field name="active" domain="bit"/>
-    </method>
-    <method name="close" synchronous="1" index="40">
-      <chassis name="client" implement="MUST"/>
-      <chassis name="server" implement="MUST"/>
-      <response name="close-ok"/>
-      <field name="reply-code" domain="reply-code"/>
-      <field name="reply-text" domain="reply-text"/>
-      <field name="class-id" domain="class-id"/>
-      <field name="method-id" domain="method-id"/>
-    </method>
-    <method name="close-ok" synchronous="1" index="41">
-      <chassis name="client" implement="MUST"/>
-      <chassis name="server" implement="MUST"/>
-    </method>
-  </class>
-  <class name="exchange" handler="channel" index="40">
-    <chassis name="server" implement="MUST"/>
-    <chassis name="client" implement="MUST"/>
-    <method name="declare" synchronous="1" index="10">
-      <chassis name="server" implement="MUST"/>
-      <response name="declare-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="exchange" domain="exchange-name">
-        <assert check="notnull"/>
-      </field>
-      <field name="type" domain="shortstr"/>
-      <field name="passive" domain="bit"/>
-      <field name="durable" domain="bit"/>
-      <field name="auto-delete" domain="bit"/>
-      <field name="internal" domain="bit"/>
-      <field name="no-wait" domain="no-wait"/>
-      <field name="arguments" domain="table"/>
-    </method>
-    <method name="declare-ok" synchronous="1" index="11">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="delete" synchronous="1" index="20">
-      <chassis name="server" implement="MUST"/>
-      <response name="delete-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="exchange" domain="exchange-name">
-        <assert check="notnull"/>
-      </field>
-      <field name="if-unused" domain="bit"/>
-      <field name="no-wait" domain="no-wait"/>
-    </method>
-    <method name="delete-ok" synchronous="1" index="21">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="bind" synchronous="1" index="30">
-      <chassis name="server" implement="MUST"/>
-      <response name="bind-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="destination" domain="exchange-name"/>
-      <field name="source" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-      <field name="no-wait" domain="no-wait"/>
-      <field name="arguments" domain="table"/>
-    </method>
-    <method name="bind-ok" synchronous="1" index="31">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="unbind" synchronous="1" index="40">
-      <chassis name="server" implement="MUST"/>
-      <response name="unbind-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="destination" domain="exchange-name"/>
-      <field name="source" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-      <field name="no-wait" domain="no-wait"/>
-      <field name="arguments" domain="table"/>
-    </method>
-    <method name="unbind-ok" synchronous="1" index="51">
-      <chassis name="client" implement="MUST"/>
-    </method>
-  </class>
-  <class name="queue" handler="channel" index="50">
-    <chassis name="server" implement="MUST"/>
-    <chassis name="client" implement="MUST"/>
-    <method name="declare" synchronous="1" index="10">
-      <chassis name="server" implement="MUST"/>
-      <response name="declare-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="queue" domain="queue-name"/>
-      <field name="passive" domain="bit"/>
-      <field name="durable" domain="bit"/>
-      <field name="exclusive" domain="bit"/>
-      <field name="auto-delete" domain="bit"/>
-      <field name="no-wait" domain="no-wait"/>
-      <field name="arguments" domain="table"/>
-    </method>
-    <method name="declare-ok" synchronous="1" index="11">
-      <chassis name="client" implement="MUST"/>
-      <field name="queue" domain="queue-name">
-        <assert check="notnull"/>
-      </field>
-      <field name="message-count" domain="message-count"/>
-      <field name="consumer-count" domain="long"/>
-    </method>
-    <method name="bind" synchronous="1" index="20">
-      <chassis name="server" implement="MUST"/>
-      <response name="bind-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="queue" domain="queue-name"/>
-      <field name="exchange" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-      <field name="no-wait" domain="no-wait"/>
-      <field name="arguments" domain="table"/>
-    </method>
-    <method name="bind-ok" synchronous="1" index="21">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="unbind" synchronous="1" index="50">
-      <chassis name="server" implement="MUST"/>
-      <response name="unbind-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="queue" domain="queue-name"/>
-      <field name="exchange" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-      <field name="arguments" domain="table"/>
-    </method>
-    <method name="unbind-ok" synchronous="1" index="51">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="purge" synchronous="1" index="30">
-      <chassis name="server" implement="MUST"/>
-      <response name="purge-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="queue" domain="queue-name"/>
-      <field name="no-wait" domain="no-wait"/>
-    </method>
-    <method name="purge-ok" synchronous="1" index="31">
-      <chassis name="client" implement="MUST"/>
-      <field name="message-count" domain="message-count"/>
-    </method>
-    <method name="delete" synchronous="1" index="40">
-      <chassis name="server" implement="MUST"/>
-      <response name="delete-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="queue" domain="queue-name"/>
-      <field name="if-unused" domain="bit"/>
-      <field name="if-empty" domain="bit"/>
-      <field name="no-wait" domain="no-wait"/>
-    </method>
-    <method name="delete-ok" synchronous="1" index="41">
-      <chassis name="client" implement="MUST"/>
-      <field name="message-count" domain="message-count"/>
-    </method>
-  </class>
-  <class name="basic" handler="channel" index="60">
-    <chassis name="server" implement="MUST"/>
-    <chassis name="client" implement="MAY"/>
-    <field name="content-type" domain="shortstr"/>
-    <field name="content-encoding" domain="shortstr"/>
-    <field name="headers" domain="table"/>
-    <field name="delivery-mode" domain="octet"/>
-    <field name="priority" domain="octet"/>
-    <field name="correlation-id" domain="shortstr"/>
-    <field name="reply-to" domain="shortstr"/>
-    <field name="expiration" domain="shortstr"/>
-    <field name="message-id" domain="shortstr"/>
-    <field name="timestamp" domain="timestamp"/>
-    <field name="type" domain="shortstr"/>
-    <field name="user-id" domain="shortstr"/>
-    <field name="app-id" domain="shortstr"/>
-    <field name="reserved" domain="shortstr"/>
-    <method name="qos" synchronous="1" index="10">
-      <chassis name="server" implement="MUST"/>
-      <response name="qos-ok"/>
-      <field name="prefetch-size" domain="long"/>
-      <field name="prefetch-count" domain="short"/>
-      <field name="global" domain="bit"/>
-    </method>
-    <method name="qos-ok" synchronous="1" index="11">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="consume" synchronous="1" index="20">
-      <chassis name="server" implement="MUST"/>
-      <response name="consume-ok"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="queue" domain="queue-name"/>
-      <field name="consumer-tag" domain="consumer-tag"/>
-      <field name="no-local" domain="no-local"/>
-      <field name="no-ack" domain="no-ack"/>
-      <field name="exclusive" domain="bit"/>
-      <field name="no-wait" domain="no-wait"/>
-      <field name="arguments" domain="table"/>
-    </method>
-    <method name="consume-ok" synchronous="1" index="21">
-      <chassis name="client" implement="MUST"/>
-      <field name="consumer-tag" domain="consumer-tag"/>
-    </method>
-    <method name="cancel" synchronous="1" index="30">
-      <chassis name="server" implement="MUST"/>
-      <chassis name="client" implement="SHOULD"/>
-      <response name="cancel-ok"/>
-      <field name="consumer-tag" domain="consumer-tag"/>
-      <field name="no-wait" domain="no-wait"/>
-    </method>
-    <method name="cancel-ok" synchronous="1" index="31">
-      <chassis name="client" implement="MUST"/>
-      <chassis name="server" implement="MAY"/>
-      <field name="consumer-tag" domain="consumer-tag"/>
-    </method>
-    <method name="publish" content="1" index="40">
-      <chassis name="server" implement="MUST"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="exchange" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-      <field name="mandatory" domain="bit"/>
-      <field name="immediate" domain="bit"/>
-    </method>
-    <method name="return" content="1" index="50">
-      <chassis name="client" implement="MUST"/>
-      <field name="reply-code" domain="reply-code"/>
-      <field name="reply-text" domain="reply-text"/>
-      <field name="exchange" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-    </method>
-    <method name="deliver" content="1" index="60">
-      <chassis name="client" implement="MUST"/>
-      <field name="consumer-tag" domain="consumer-tag"/>
-      <field name="delivery-tag" domain="delivery-tag"/>
-      <field name="redelivered" domain="redelivered"/>
-      <field name="exchange" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-    </method>
-    <method name="get" synchronous="1" index="70">
-      <response name="get-ok"/>
-      <response name="get-empty"/>
-      <chassis name="server" implement="MUST"/>
-      <field name="reserved-1" type="short" reserved="1"/>
-      <field name="queue" domain="queue-name"/>
-      <field name="no-ack" domain="no-ack"/>
-    </method>
-    <method name="get-ok" synchronous="1" content="1" index="71">
-      <chassis name="client" implement="MAY"/>
-      <field name="delivery-tag" domain="delivery-tag"/>
-      <field name="redelivered" domain="redelivered"/>
-      <field name="exchange" domain="exchange-name"/>
-      <field name="routing-key" domain="shortstr"/>
-      <field name="message-count" domain="message-count"/>
-    </method>
-    <method name="get-empty" synchronous="1" index="72">
-      <chassis name="client" implement="MAY"/>
-      <field name="reserved-1" type="shortstr" reserved="1"/>
-    </method>
-    <method name="ack" index="80">
-      <chassis name="server" implement="MUST"/>
-      <chassis name="client" implement="MUST"/>
-      <field name="delivery-tag" domain="delivery-tag"/>
-      <field name="multiple" domain="bit"/>
-    </method>
-    <method name="reject" index="90">
-      <chassis name="server" implement="MUST"/>
-      <field name="delivery-tag" domain="delivery-tag"/>
-      <field name="requeue" domain="bit"/>
-    </method>
-    <method name="recover-async" index="100" deprecated="1">
-      <chassis name="server" implement="MAY"/>
-      <field name="requeue" domain="bit"/>
-    </method>
-    <method name="recover" synchronous="1" index="110">
-      <chassis name="server" implement="MUST"/>
-      <field name="requeue" domain="bit"/>
-    </method>
-    <method name="recover-ok" synchronous="1" index="111">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="nack" index="120">
-      <chassis name="server" implement="MUST"/>
-      <chassis name="client" implement="MUST"/>
-      <field name="delivery-tag" domain="delivery-tag"/>
-      <field name="multiple" domain="bit"/>
-      <field name="requeue" domain="bit"/>
-    </method>
-  </class>
-  <class name="tx" handler="channel" index="90">
-    <chassis name="server" implement="SHOULD"/>
-    <chassis name="client" implement="MAY"/>
-    <method name="select" synchronous="1" index="10">
-      <chassis name="server" implement="MUST"/>
-      <response name="select-ok"/>
-    </method>
-    <method name="select-ok" synchronous="1" index="11">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="commit" synchronous="1" index="20">
-      <chassis name="server" implement="MUST"/>
-      <response name="commit-ok"/>
-    </method>
-    <method name="commit-ok" synchronous="1" index="21">
-      <chassis name="client" implement="MUST"/>
-    </method>
-    <method name="rollback" synchronous="1" index="30">
-      <chassis name="server" implement="MUST"/>
-      <response name="rollback-ok"/>
-    </method>
-    <method name="rollback-ok" synchronous="1" index="31">
-      <chassis name="client" implement="MUST"/>
-    </method>
-  </class>
-  <class name="confirm" handler="channel" index="85">
-    <chassis name="server" implement="SHOULD"/>
-    <chassis name="client" implement="MAY"/>
-    <method name="select" synchronous="1" index="10">
-      <chassis name="server" implement="MUST"/>
-      <response name="select-ok"/>
-      <field name="nowait" type="bit"/>
-    </method>
-    <method name="select-ok" synchronous="1" index="11">
-      <chassis name="client" implement="MUST"/>
-    </method>
-  </class>
-</amqp>

+ 0 - 536
vendor/github.com/streadway/amqp/spec/gen.go

@@ -1,536 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-// +build ignore
-
-package main
-
-import (
-	"bytes"
-	"encoding/xml"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"os"
-	"regexp"
-	"strings"
-	"text/template"
-)
-
-var (
-	ErrUnknownType   = errors.New("Unknown field type in gen")
-	ErrUnknownDomain = errors.New("Unknown domain type in gen")
-)
-
-var amqpTypeToNative = map[string]string{
-	"bit":        "bool",
-	"octet":      "byte",
-	"shortshort": "uint8",
-	"short":      "uint16",
-	"long":       "uint32",
-	"longlong":   "uint64",
-	"timestamp":  "time.Time",
-	"table":      "Table",
-	"shortstr":   "string",
-	"longstr":    "string",
-}
-
-type Rule struct {
-	Name string   `xml:"name,attr"`
-	Docs []string `xml:"doc"`
-}
-
-type Doc struct {
-	Type string `xml:"type,attr"`
-	Body string `xml:",innerxml"`
-}
-
-type Chassis struct {
-	Name      string `xml:"name,attr"`
-	Implement string `xml:"implement,attr"`
-}
-
-type Assert struct {
-	Check  string `xml:"check,attr"`
-	Value  string `xml:"value,attr"`
-	Method string `xml:"method,attr"`
-}
-
-type Field struct {
-	Name     string   `xml:"name,attr"`
-	Domain   string   `xml:"domain,attr"`
-	Type     string   `xml:"type,attr"`
-	Label    string   `xml:"label,attr"`
-	Reserved bool     `xml:"reserved,attr"`
-	Docs     []Doc    `xml:"doc"`
-	Asserts  []Assert `xml:"assert"`
-}
-
-type Response struct {
-	Name string `xml:"name,attr"`
-}
-
-type Method struct {
-	Name        string    `xml:"name,attr"`
-	Response    Response  `xml:"response"`
-	Synchronous bool      `xml:"synchronous,attr"`
-	Content     bool      `xml:"content,attr"`
-	Index       string    `xml:"index,attr"`
-	Label       string    `xml:"label,attr"`
-	Docs        []Doc     `xml:"doc"`
-	Rules       []Rule    `xml:"rule"`
-	Fields      []Field   `xml:"field"`
-	Chassis     []Chassis `xml:"chassis"`
-}
-
-type Class struct {
-	Name    string    `xml:"name,attr"`
-	Handler string    `xml:"handler,attr"`
-	Index   string    `xml:"index,attr"`
-	Label   string    `xml:"label,attr"`
-	Docs    []Doc     `xml:"doc"`
-	Methods []Method  `xml:"method"`
-	Chassis []Chassis `xml:"chassis"`
-}
-
-type Domain struct {
-	Name  string `xml:"name,attr"`
-	Type  string `xml:"type,attr"`
-	Label string `xml:"label,attr"`
-	Rules []Rule `xml:"rule"`
-	Docs  []Doc  `xml:"doc"`
-}
-
-type Constant struct {
-	Name  string `xml:"name,attr"`
-	Value int    `xml:"value,attr"`
-	Class string `xml:"class,attr"`
-	Doc   string `xml:"doc"`
-}
-
-type Amqp struct {
-	Major   int    `xml:"major,attr"`
-	Minor   int    `xml:"minor,attr"`
-	Port    int    `xml:"port,attr"`
-	Comment string `xml:"comment,attr"`
-
-	Constants []Constant `xml:"constant"`
-	Domains   []Domain   `xml:"domain"`
-	Classes   []Class    `xml:"class"`
-}
-
-type renderer struct {
-	Root       Amqp
-	bitcounter int
-}
-
-type fieldset struct {
-	AmqpType   string
-	NativeType string
-	Fields     []Field
-	*renderer
-}
-
-var (
-	helpers = template.FuncMap{
-		"public":  public,
-		"private": private,
-		"clean":   clean,
-	}
-
-	packageTemplate = template.Must(template.New("package").Funcs(helpers).Parse(`
-	// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-	// Use of this source code is governed by a BSD-style
-	// license that can be found in the LICENSE file.
-	// Source code and contact info at http://github.com/streadway/amqp
-
-  /* GENERATED FILE - DO NOT EDIT */
-  /* Rebuild from the spec/gen.go tool */
-
-  {{with .Root}}
-  package amqp
-
-  import (
-    "fmt"
-    "encoding/binary"
-    "io"
-  )
-
-	// Error codes that can be sent from the server during a connection or
-	// channel exception or used by the client to indicate a class of error like
-	// ErrCredentials.  The text of the error is likely more interesting than
-	// these constants.
-	const (
-	{{range $c := .Constants}}
-	{{if $c.IsError}}{{.Name | public}}{{else}}{{.Name | private}}{{end}} = {{.Value}}{{end}}
-  )
-
-	func isSoftExceptionCode(code int) bool {
-		switch code {
-		{{range $c := .Constants}} {{if $c.IsSoftError}} case {{$c.Value}}:
-			return true
-		{{end}}{{end}}
-		}
-		return false
-	}
-
-  {{range .Classes}}
-    {{$class := .}}
-    {{range .Methods}}
-      {{$method := .}}
-			{{$struct := $.StructName $class.Name $method.Name}}
-      {{if .Docs}}/* {{range .Docs}} {{.Body | clean}} {{end}} */{{end}}
-      type {{$struct}} struct {
-        {{range .Fields}}
-        {{$.FieldName .}} {{$.FieldType . | $.NativeType}} {{if .Label}}// {{.Label}}{{end}}{{end}}
-				{{if .Content}}Properties properties
-				Body []byte{{end}}
-      }
-
-			func (me *{{$struct}}) id() (uint16, uint16) {
-				return {{$class.Index}}, {{$method.Index}}
-			}
-
-			func (me *{{$struct}}) wait() (bool) {
-				return {{.Synchronous}}{{if $.HasField "NoWait" .}} && !me.NoWait{{end}}
-			}
-
-			{{if .Content}}
-      func (me *{{$struct}}) getContent() (properties, []byte) {
-        return me.Properties, me.Body
-      }
-
-      func (me *{{$struct}}) setContent(props properties, body []byte) {
-        me.Properties, me.Body = props, body
-      }
-			{{end}}
-      func (me *{{$struct}}) write(w io.Writer) (err error) {
-				{{if $.HasType "bit" $method}}var bits byte{{end}}
-        {{.Fields | $.Fieldsets | $.Partial "enc-"}}
-        return
-      }
-
-      func (me *{{$struct}}) read(r io.Reader) (err error) {
-				{{if $.HasType "bit" $method}}var bits byte{{end}}
-        {{.Fields | $.Fieldsets | $.Partial "dec-"}}
-        return
-      }
-    {{end}}
-  {{end}}
-
-  func (me *reader) parseMethodFrame(channel uint16, size uint32) (f frame, err error) {
-    mf := &methodFrame {
-      ChannelId: channel,
-    }
-
-    if err = binary.Read(me.r, binary.BigEndian, &mf.ClassId); err != nil {
-      return
-    }
-
-    if err = binary.Read(me.r, binary.BigEndian, &mf.MethodId); err != nil {
-      return
-    }
-
-    switch mf.ClassId {
-    {{range .Classes}}
-    {{$class := .}}
-    case {{.Index}}: // {{.Name}}
-      switch mf.MethodId {
-      {{range .Methods}}
-      case {{.Index}}: // {{$class.Name}} {{.Name}}
-        //fmt.Println("NextMethod: class:{{$class.Index}} method:{{.Index}}")
-        method := &{{$.StructName $class.Name .Name}}{}
-        if err = method.read(me.r); err != nil {
-          return
-        }
-        mf.Method = method
-      {{end}}
-      default:
-        return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-      }
-    {{end}}
-    default:
-      return nil, fmt.Errorf("Bad method frame, unknown class %d", mf.ClassId)
-    }
-
-    return mf, nil
-  }
-  {{end}}
-
-  {{define "enc-bit"}}
-    {{range $off, $field := .Fields}}
-    if me.{{$field | $.FieldName}} { bits |= 1 << {{$off}} }
-    {{end}}
-    if err = binary.Write(w, binary.BigEndian, bits); err != nil { return }
-  {{end}}
-  {{define "enc-octet"}}
-    {{range .Fields}} if err = binary.Write(w, binary.BigEndian, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-shortshort"}}
-    {{range .Fields}} if err = binary.Write(w, binary.BigEndian, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-short"}}
-    {{range .Fields}} if err = binary.Write(w, binary.BigEndian, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-long"}}
-    {{range .Fields}} if err = binary.Write(w, binary.BigEndian, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-longlong"}}
-    {{range .Fields}} if err = binary.Write(w, binary.BigEndian, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-timestamp"}}
-    {{range .Fields}} if err = writeTimestamp(w, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-shortstr"}}
-    {{range .Fields}} if err = writeShortstr(w, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-longstr"}}
-    {{range .Fields}} if err = writeLongstr(w, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "enc-table"}}
-    {{range .Fields}} if err = writeTable(w, me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-
-  {{define "dec-bit"}}
-    if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-      return
-    }
-    {{range $off, $field := .Fields}} me.{{$field | $.FieldName}} = (bits & (1 << {{$off}}) > 0)
-    {{end}}
-  {{end}}
-  {{define "dec-octet"}}
-    {{range .Fields}} if err = binary.Read(r, binary.BigEndian, &me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-shortshort"}}
-    {{range .Fields}} if err = binary.Read(r, binary.BigEndian, &me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-short"}}
-    {{range .Fields}} if err = binary.Read(r, binary.BigEndian, &me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-long"}}
-    {{range .Fields}} if err = binary.Read(r, binary.BigEndian, &me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-longlong"}}
-    {{range .Fields}} if err = binary.Read(r, binary.BigEndian, &me.{{. | $.FieldName}}); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-timestamp"}}
-    {{range .Fields}} if me.{{. | $.FieldName}}, err = readTimestamp(r); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-shortstr"}}
-    {{range .Fields}} if me.{{. | $.FieldName}}, err = readShortstr(r); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-longstr"}}
-    {{range .Fields}} if me.{{. | $.FieldName}}, err = readLongstr(r); err != nil { return }
-    {{end}}
-  {{end}}
-  {{define "dec-table"}}
-    {{range .Fields}} if me.{{. | $.FieldName}}, err = readTable(r); err != nil { return }
-    {{end}}
-  {{end}}
-
-  `))
-)
-
-func (me *Constant) IsError() bool {
-	return strings.Contains(me.Class, "error")
-}
-
-func (me *Constant) IsSoftError() bool {
-	return me.Class == "soft-error"
-}
-
-func (me *renderer) Partial(prefix string, fields []fieldset) (s string, err error) {
-	var buf bytes.Buffer
-	for _, set := range fields {
-		name := prefix + set.AmqpType
-		t := packageTemplate.Lookup(name)
-		if t == nil {
-			return "", errors.New(fmt.Sprintf("Missing template: %s", name))
-		}
-		if err = t.Execute(&buf, set); err != nil {
-			return
-		}
-	}
-	return string(buf.Bytes()), nil
-}
-
-// Groups the fields so that the right encoder/decoder can be called
-func (me *renderer) Fieldsets(fields []Field) (f []fieldset, err error) {
-	if len(fields) > 0 {
-		for _, field := range fields {
-			cur := fieldset{}
-			cur.AmqpType, err = me.FieldType(field)
-			if err != nil {
-				return
-			}
-
-			cur.NativeType, err = me.NativeType(cur.AmqpType)
-			if err != nil {
-				return
-			}
-			cur.Fields = append(cur.Fields, field)
-			f = append(f, cur)
-		}
-
-		i, j := 0, 1
-		for j < len(f) {
-			if f[i].AmqpType == f[j].AmqpType {
-				f[i].Fields = append(f[i].Fields, f[j].Fields...)
-			} else {
-				i++
-				f[i] = f[j]
-			}
-			j++
-		}
-		return f[:i+1], nil
-	}
-
-	return
-}
-
-func (me *renderer) HasType(typ string, method Method) bool {
-	for _, f := range method.Fields {
-		name, _ := me.FieldType(f)
-		if name == typ {
-			return true
-		}
-	}
-	return false
-}
-
-func (me *renderer) HasField(field string, method Method) bool {
-	for _, f := range method.Fields {
-		name := me.FieldName(f)
-		if name == field {
-			return true
-		}
-	}
-	return false
-}
-
-func (me *renderer) Domain(field Field) (domain Domain, err error) {
-	for _, domain = range me.Root.Domains {
-		if field.Domain == domain.Name {
-			return
-		}
-	}
-	return domain, nil
-	//return domain, ErrUnknownDomain
-}
-
-func (me *renderer) FieldName(field Field) (t string) {
-	t = public(field.Name)
-
-	if field.Reserved {
-		t = strings.ToLower(t)
-	}
-
-	return
-}
-
-func (me *renderer) FieldType(field Field) (t string, err error) {
-	t = field.Type
-
-	if t == "" {
-		var domain Domain
-		domain, err = me.Domain(field)
-		if err != nil {
-			return "", err
-		}
-		t = domain.Type
-	}
-
-	return
-}
-
-func (me *renderer) NativeType(amqpType string) (t string, err error) {
-	if t, ok := amqpTypeToNative[amqpType]; ok {
-		return t, nil
-	}
-	return "", ErrUnknownType
-}
-
-func (me *renderer) Tag(d Domain) string {
-	label := "`"
-
-	label += `domain:"` + d.Name + `"`
-
-	if len(d.Type) > 0 {
-		label += `,type:"` + d.Type + `"`
-	}
-
-	label += "`"
-
-	return label
-}
-
-func (me *renderer) StructName(parts ...string) string {
-	return parts[0] + public(parts[1:]...)
-}
-
-func clean(body string) (res string) {
-	return strings.Replace(body, "\r", "", -1)
-}
-
-func private(parts ...string) string {
-	return export(regexp.MustCompile(`[-_]\w`), parts...)
-}
-
-func public(parts ...string) string {
-	return export(regexp.MustCompile(`^\w|[-_]\w`), parts...)
-}
-
-func export(delim *regexp.Regexp, parts ...string) (res string) {
-	for _, in := range parts {
-
-		res += delim.ReplaceAllStringFunc(in, func(match string) string {
-			switch len(match) {
-			case 1:
-				return strings.ToUpper(match)
-			case 2:
-				return strings.ToUpper(match[1:])
-			}
-			panic("unreachable")
-		})
-	}
-
-	return
-}
-
-func main() {
-	var r renderer
-
-	spec, err := ioutil.ReadAll(os.Stdin)
-	if err != nil {
-		log.Fatalln("Please pass spec on stdin", err)
-	}
-
-	err = xml.Unmarshal(spec, &r.Root)
-
-	if err != nil {
-		log.Fatalln("Could not parse XML:", err)
-	}
-
-	if err = packageTemplate.Execute(os.Stdout, &r); err != nil {
-		log.Fatalln("Generate error: ", err)
-	}
-}

+ 0 - 3306
vendor/github.com/streadway/amqp/spec091.go

@@ -1,3306 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-/* GENERATED FILE - DO NOT EDIT */
-/* Rebuild from the spec/gen.go tool */
-
-package amqp
-
-import (
-	"encoding/binary"
-	"fmt"
-	"io"
-)
-
-// Error codes that can be sent from the server during a connection or
-// channel exception or used by the client to indicate a class of error like
-// ErrCredentials.  The text of the error is likely more interesting than
-// these constants.
-const (
-	frameMethod        = 1
-	frameHeader        = 2
-	frameBody          = 3
-	frameHeartbeat     = 8
-	frameMinSize       = 4096
-	frameEnd           = 206
-	replySuccess       = 200
-	ContentTooLarge    = 311
-	NoRoute            = 312
-	NoConsumers        = 313
-	ConnectionForced   = 320
-	InvalidPath        = 402
-	AccessRefused      = 403
-	NotFound           = 404
-	ResourceLocked     = 405
-	PreconditionFailed = 406
-	FrameError         = 501
-	SyntaxError        = 502
-	CommandInvalid     = 503
-	ChannelError       = 504
-	UnexpectedFrame    = 505
-	ResourceError      = 506
-	NotAllowed         = 530
-	NotImplemented     = 540
-	InternalError      = 541
-)
-
-func isSoftExceptionCode(code int) bool {
-	switch code {
-	case 311:
-		return true
-	case 312:
-		return true
-	case 313:
-		return true
-	case 403:
-		return true
-	case 404:
-		return true
-	case 405:
-		return true
-	case 406:
-		return true
-
-	}
-	return false
-}
-
-type connectionStart struct {
-	VersionMajor     byte
-	VersionMinor     byte
-	ServerProperties Table
-	Mechanisms       string
-	Locales          string
-}
-
-func (me *connectionStart) id() (uint16, uint16) {
-	return 10, 10
-}
-
-func (me *connectionStart) wait() bool {
-	return true
-}
-
-func (me *connectionStart) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.VersionMajor); err != nil {
-		return
-	}
-	if err = binary.Write(w, binary.BigEndian, me.VersionMinor); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.ServerProperties); err != nil {
-		return
-	}
-
-	if err = writeLongstr(w, me.Mechanisms); err != nil {
-		return
-	}
-	if err = writeLongstr(w, me.Locales); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionStart) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.VersionMajor); err != nil {
-		return
-	}
-	if err = binary.Read(r, binary.BigEndian, &me.VersionMinor); err != nil {
-		return
-	}
-
-	if me.ServerProperties, err = readTable(r); err != nil {
-		return
-	}
-
-	if me.Mechanisms, err = readLongstr(r); err != nil {
-		return
-	}
-	if me.Locales, err = readLongstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionStartOk struct {
-	ClientProperties Table
-	Mechanism        string
-	Response         string
-	Locale           string
-}
-
-func (me *connectionStartOk) id() (uint16, uint16) {
-	return 10, 11
-}
-
-func (me *connectionStartOk) wait() bool {
-	return true
-}
-
-func (me *connectionStartOk) write(w io.Writer) (err error) {
-
-	if err = writeTable(w, me.ClientProperties); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Mechanism); err != nil {
-		return
-	}
-
-	if err = writeLongstr(w, me.Response); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Locale); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionStartOk) read(r io.Reader) (err error) {
-
-	if me.ClientProperties, err = readTable(r); err != nil {
-		return
-	}
-
-	if me.Mechanism, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if me.Response, err = readLongstr(r); err != nil {
-		return
-	}
-
-	if me.Locale, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionSecure struct {
-	Challenge string
-}
-
-func (me *connectionSecure) id() (uint16, uint16) {
-	return 10, 20
-}
-
-func (me *connectionSecure) wait() bool {
-	return true
-}
-
-func (me *connectionSecure) write(w io.Writer) (err error) {
-
-	if err = writeLongstr(w, me.Challenge); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionSecure) read(r io.Reader) (err error) {
-
-	if me.Challenge, err = readLongstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionSecureOk struct {
-	Response string
-}
-
-func (me *connectionSecureOk) id() (uint16, uint16) {
-	return 10, 21
-}
-
-func (me *connectionSecureOk) wait() bool {
-	return true
-}
-
-func (me *connectionSecureOk) write(w io.Writer) (err error) {
-
-	if err = writeLongstr(w, me.Response); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionSecureOk) read(r io.Reader) (err error) {
-
-	if me.Response, err = readLongstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionTune struct {
-	ChannelMax uint16
-	FrameMax   uint32
-	Heartbeat  uint16
-}
-
-func (me *connectionTune) id() (uint16, uint16) {
-	return 10, 30
-}
-
-func (me *connectionTune) wait() bool {
-	return true
-}
-
-func (me *connectionTune) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.ChannelMax); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.FrameMax); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.Heartbeat); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionTune) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.ChannelMax); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.FrameMax); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.Heartbeat); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionTuneOk struct {
-	ChannelMax uint16
-	FrameMax   uint32
-	Heartbeat  uint16
-}
-
-func (me *connectionTuneOk) id() (uint16, uint16) {
-	return 10, 31
-}
-
-func (me *connectionTuneOk) wait() bool {
-	return true
-}
-
-func (me *connectionTuneOk) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.ChannelMax); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.FrameMax); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.Heartbeat); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionTuneOk) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.ChannelMax); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.FrameMax); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.Heartbeat); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionOpen struct {
-	VirtualHost string
-	reserved1   string
-	reserved2   bool
-}
-
-func (me *connectionOpen) id() (uint16, uint16) {
-	return 10, 40
-}
-
-func (me *connectionOpen) wait() bool {
-	return true
-}
-
-func (me *connectionOpen) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = writeShortstr(w, me.VirtualHost); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.reserved1); err != nil {
-		return
-	}
-
-	if me.reserved2 {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionOpen) read(r io.Reader) (err error) {
-	var bits byte
-
-	if me.VirtualHost, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.reserved1, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.reserved2 = (bits&(1<<0) > 0)
-
-	return
-}
-
-type connectionOpenOk struct {
-	reserved1 string
-}
-
-func (me *connectionOpenOk) id() (uint16, uint16) {
-	return 10, 41
-}
-
-func (me *connectionOpenOk) wait() bool {
-	return true
-}
-
-func (me *connectionOpenOk) write(w io.Writer) (err error) {
-
-	if err = writeShortstr(w, me.reserved1); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionOpenOk) read(r io.Reader) (err error) {
-
-	if me.reserved1, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionClose struct {
-	ReplyCode uint16
-	ReplyText string
-	ClassId   uint16
-	MethodId  uint16
-}
-
-func (me *connectionClose) id() (uint16, uint16) {
-	return 10, 50
-}
-
-func (me *connectionClose) wait() bool {
-	return true
-}
-
-func (me *connectionClose) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.ReplyCode); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.ReplyText); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.ClassId); err != nil {
-		return
-	}
-	if err = binary.Write(w, binary.BigEndian, me.MethodId); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionClose) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.ReplyCode); err != nil {
-		return
-	}
-
-	if me.ReplyText, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.ClassId); err != nil {
-		return
-	}
-	if err = binary.Read(r, binary.BigEndian, &me.MethodId); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionCloseOk struct {
-}
-
-func (me *connectionCloseOk) id() (uint16, uint16) {
-	return 10, 51
-}
-
-func (me *connectionCloseOk) wait() bool {
-	return true
-}
-
-func (me *connectionCloseOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *connectionCloseOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type connectionBlocked struct {
-	Reason string
-}
-
-func (me *connectionBlocked) id() (uint16, uint16) {
-	return 10, 60
-}
-
-func (me *connectionBlocked) wait() bool {
-	return false
-}
-
-func (me *connectionBlocked) write(w io.Writer) (err error) {
-
-	if err = writeShortstr(w, me.Reason); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *connectionBlocked) read(r io.Reader) (err error) {
-
-	if me.Reason, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type connectionUnblocked struct {
-}
-
-func (me *connectionUnblocked) id() (uint16, uint16) {
-	return 10, 61
-}
-
-func (me *connectionUnblocked) wait() bool {
-	return false
-}
-
-func (me *connectionUnblocked) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *connectionUnblocked) read(r io.Reader) (err error) {
-
-	return
-}
-
-type channelOpen struct {
-	reserved1 string
-}
-
-func (me *channelOpen) id() (uint16, uint16) {
-	return 20, 10
-}
-
-func (me *channelOpen) wait() bool {
-	return true
-}
-
-func (me *channelOpen) write(w io.Writer) (err error) {
-
-	if err = writeShortstr(w, me.reserved1); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *channelOpen) read(r io.Reader) (err error) {
-
-	if me.reserved1, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type channelOpenOk struct {
-	reserved1 string
-}
-
-func (me *channelOpenOk) id() (uint16, uint16) {
-	return 20, 11
-}
-
-func (me *channelOpenOk) wait() bool {
-	return true
-}
-
-func (me *channelOpenOk) write(w io.Writer) (err error) {
-
-	if err = writeLongstr(w, me.reserved1); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *channelOpenOk) read(r io.Reader) (err error) {
-
-	if me.reserved1, err = readLongstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type channelFlow struct {
-	Active bool
-}
-
-func (me *channelFlow) id() (uint16, uint16) {
-	return 20, 20
-}
-
-func (me *channelFlow) wait() bool {
-	return true
-}
-
-func (me *channelFlow) write(w io.Writer) (err error) {
-	var bits byte
-
-	if me.Active {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *channelFlow) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Active = (bits&(1<<0) > 0)
-
-	return
-}
-
-type channelFlowOk struct {
-	Active bool
-}
-
-func (me *channelFlowOk) id() (uint16, uint16) {
-	return 20, 21
-}
-
-func (me *channelFlowOk) wait() bool {
-	return false
-}
-
-func (me *channelFlowOk) write(w io.Writer) (err error) {
-	var bits byte
-
-	if me.Active {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *channelFlowOk) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Active = (bits&(1<<0) > 0)
-
-	return
-}
-
-type channelClose struct {
-	ReplyCode uint16
-	ReplyText string
-	ClassId   uint16
-	MethodId  uint16
-}
-
-func (me *channelClose) id() (uint16, uint16) {
-	return 20, 40
-}
-
-func (me *channelClose) wait() bool {
-	return true
-}
-
-func (me *channelClose) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.ReplyCode); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.ReplyText); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.ClassId); err != nil {
-		return
-	}
-	if err = binary.Write(w, binary.BigEndian, me.MethodId); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *channelClose) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.ReplyCode); err != nil {
-		return
-	}
-
-	if me.ReplyText, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.ClassId); err != nil {
-		return
-	}
-	if err = binary.Read(r, binary.BigEndian, &me.MethodId); err != nil {
-		return
-	}
-
-	return
-}
-
-type channelCloseOk struct {
-}
-
-func (me *channelCloseOk) id() (uint16, uint16) {
-	return 20, 41
-}
-
-func (me *channelCloseOk) wait() bool {
-	return true
-}
-
-func (me *channelCloseOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *channelCloseOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type exchangeDeclare struct {
-	reserved1  uint16
-	Exchange   string
-	Type       string
-	Passive    bool
-	Durable    bool
-	AutoDelete bool
-	Internal   bool
-	NoWait     bool
-	Arguments  Table
-}
-
-func (me *exchangeDeclare) id() (uint16, uint16) {
-	return 40, 10
-}
-
-func (me *exchangeDeclare) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *exchangeDeclare) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.Type); err != nil {
-		return
-	}
-
-	if me.Passive {
-		bits |= 1 << 0
-	}
-
-	if me.Durable {
-		bits |= 1 << 1
-	}
-
-	if me.AutoDelete {
-		bits |= 1 << 2
-	}
-
-	if me.Internal {
-		bits |= 1 << 3
-	}
-
-	if me.NoWait {
-		bits |= 1 << 4
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.Arguments); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *exchangeDeclare) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.Type, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Passive = (bits&(1<<0) > 0)
-	me.Durable = (bits&(1<<1) > 0)
-	me.AutoDelete = (bits&(1<<2) > 0)
-	me.Internal = (bits&(1<<3) > 0)
-	me.NoWait = (bits&(1<<4) > 0)
-
-	if me.Arguments, err = readTable(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type exchangeDeclareOk struct {
-}
-
-func (me *exchangeDeclareOk) id() (uint16, uint16) {
-	return 40, 11
-}
-
-func (me *exchangeDeclareOk) wait() bool {
-	return true
-}
-
-func (me *exchangeDeclareOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *exchangeDeclareOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type exchangeDelete struct {
-	reserved1 uint16
-	Exchange  string
-	IfUnused  bool
-	NoWait    bool
-}
-
-func (me *exchangeDelete) id() (uint16, uint16) {
-	return 40, 20
-}
-
-func (me *exchangeDelete) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *exchangeDelete) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-
-	if me.IfUnused {
-		bits |= 1 << 0
-	}
-
-	if me.NoWait {
-		bits |= 1 << 1
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *exchangeDelete) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.IfUnused = (bits&(1<<0) > 0)
-	me.NoWait = (bits&(1<<1) > 0)
-
-	return
-}
-
-type exchangeDeleteOk struct {
-}
-
-func (me *exchangeDeleteOk) id() (uint16, uint16) {
-	return 40, 21
-}
-
-func (me *exchangeDeleteOk) wait() bool {
-	return true
-}
-
-func (me *exchangeDeleteOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *exchangeDeleteOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type exchangeBind struct {
-	reserved1   uint16
-	Destination string
-	Source      string
-	RoutingKey  string
-	NoWait      bool
-	Arguments   Table
-}
-
-func (me *exchangeBind) id() (uint16, uint16) {
-	return 40, 30
-}
-
-func (me *exchangeBind) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *exchangeBind) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Destination); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.Source); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	if me.NoWait {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.Arguments); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *exchangeBind) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Destination, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.Source, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.NoWait = (bits&(1<<0) > 0)
-
-	if me.Arguments, err = readTable(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type exchangeBindOk struct {
-}
-
-func (me *exchangeBindOk) id() (uint16, uint16) {
-	return 40, 31
-}
-
-func (me *exchangeBindOk) wait() bool {
-	return true
-}
-
-func (me *exchangeBindOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *exchangeBindOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type exchangeUnbind struct {
-	reserved1   uint16
-	Destination string
-	Source      string
-	RoutingKey  string
-	NoWait      bool
-	Arguments   Table
-}
-
-func (me *exchangeUnbind) id() (uint16, uint16) {
-	return 40, 40
-}
-
-func (me *exchangeUnbind) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *exchangeUnbind) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Destination); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.Source); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	if me.NoWait {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.Arguments); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *exchangeUnbind) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Destination, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.Source, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.NoWait = (bits&(1<<0) > 0)
-
-	if me.Arguments, err = readTable(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type exchangeUnbindOk struct {
-}
-
-func (me *exchangeUnbindOk) id() (uint16, uint16) {
-	return 40, 51
-}
-
-func (me *exchangeUnbindOk) wait() bool {
-	return true
-}
-
-func (me *exchangeUnbindOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *exchangeUnbindOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type queueDeclare struct {
-	reserved1  uint16
-	Queue      string
-	Passive    bool
-	Durable    bool
-	Exclusive  bool
-	AutoDelete bool
-	NoWait     bool
-	Arguments  Table
-}
-
-func (me *queueDeclare) id() (uint16, uint16) {
-	return 50, 10
-}
-
-func (me *queueDeclare) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *queueDeclare) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-
-	if me.Passive {
-		bits |= 1 << 0
-	}
-
-	if me.Durable {
-		bits |= 1 << 1
-	}
-
-	if me.Exclusive {
-		bits |= 1 << 2
-	}
-
-	if me.AutoDelete {
-		bits |= 1 << 3
-	}
-
-	if me.NoWait {
-		bits |= 1 << 4
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.Arguments); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queueDeclare) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Passive = (bits&(1<<0) > 0)
-	me.Durable = (bits&(1<<1) > 0)
-	me.Exclusive = (bits&(1<<2) > 0)
-	me.AutoDelete = (bits&(1<<3) > 0)
-	me.NoWait = (bits&(1<<4) > 0)
-
-	if me.Arguments, err = readTable(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type queueDeclareOk struct {
-	Queue         string
-	MessageCount  uint32
-	ConsumerCount uint32
-}
-
-func (me *queueDeclareOk) id() (uint16, uint16) {
-	return 50, 11
-}
-
-func (me *queueDeclareOk) wait() bool {
-	return true
-}
-
-func (me *queueDeclareOk) write(w io.Writer) (err error) {
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.MessageCount); err != nil {
-		return
-	}
-	if err = binary.Write(w, binary.BigEndian, me.ConsumerCount); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queueDeclareOk) read(r io.Reader) (err error) {
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.MessageCount); err != nil {
-		return
-	}
-	if err = binary.Read(r, binary.BigEndian, &me.ConsumerCount); err != nil {
-		return
-	}
-
-	return
-}
-
-type queueBind struct {
-	reserved1  uint16
-	Queue      string
-	Exchange   string
-	RoutingKey string
-	NoWait     bool
-	Arguments  Table
-}
-
-func (me *queueBind) id() (uint16, uint16) {
-	return 50, 20
-}
-
-func (me *queueBind) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *queueBind) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	if me.NoWait {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.Arguments); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queueBind) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.NoWait = (bits&(1<<0) > 0)
-
-	if me.Arguments, err = readTable(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type queueBindOk struct {
-}
-
-func (me *queueBindOk) id() (uint16, uint16) {
-	return 50, 21
-}
-
-func (me *queueBindOk) wait() bool {
-	return true
-}
-
-func (me *queueBindOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *queueBindOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type queueUnbind struct {
-	reserved1  uint16
-	Queue      string
-	Exchange   string
-	RoutingKey string
-	Arguments  Table
-}
-
-func (me *queueUnbind) id() (uint16, uint16) {
-	return 50, 50
-}
-
-func (me *queueUnbind) wait() bool {
-	return true
-}
-
-func (me *queueUnbind) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.Arguments); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queueUnbind) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if me.Arguments, err = readTable(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type queueUnbindOk struct {
-}
-
-func (me *queueUnbindOk) id() (uint16, uint16) {
-	return 50, 51
-}
-
-func (me *queueUnbindOk) wait() bool {
-	return true
-}
-
-func (me *queueUnbindOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *queueUnbindOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type queuePurge struct {
-	reserved1 uint16
-	Queue     string
-	NoWait    bool
-}
-
-func (me *queuePurge) id() (uint16, uint16) {
-	return 50, 30
-}
-
-func (me *queuePurge) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *queuePurge) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-
-	if me.NoWait {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queuePurge) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.NoWait = (bits&(1<<0) > 0)
-
-	return
-}
-
-type queuePurgeOk struct {
-	MessageCount uint32
-}
-
-func (me *queuePurgeOk) id() (uint16, uint16) {
-	return 50, 31
-}
-
-func (me *queuePurgeOk) wait() bool {
-	return true
-}
-
-func (me *queuePurgeOk) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.MessageCount); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queuePurgeOk) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.MessageCount); err != nil {
-		return
-	}
-
-	return
-}
-
-type queueDelete struct {
-	reserved1 uint16
-	Queue     string
-	IfUnused  bool
-	IfEmpty   bool
-	NoWait    bool
-}
-
-func (me *queueDelete) id() (uint16, uint16) {
-	return 50, 40
-}
-
-func (me *queueDelete) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *queueDelete) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-
-	if me.IfUnused {
-		bits |= 1 << 0
-	}
-
-	if me.IfEmpty {
-		bits |= 1 << 1
-	}
-
-	if me.NoWait {
-		bits |= 1 << 2
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queueDelete) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.IfUnused = (bits&(1<<0) > 0)
-	me.IfEmpty = (bits&(1<<1) > 0)
-	me.NoWait = (bits&(1<<2) > 0)
-
-	return
-}
-
-type queueDeleteOk struct {
-	MessageCount uint32
-}
-
-func (me *queueDeleteOk) id() (uint16, uint16) {
-	return 50, 41
-}
-
-func (me *queueDeleteOk) wait() bool {
-	return true
-}
-
-func (me *queueDeleteOk) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.MessageCount); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *queueDeleteOk) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.MessageCount); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicQos struct {
-	PrefetchSize  uint32
-	PrefetchCount uint16
-	Global        bool
-}
-
-func (me *basicQos) id() (uint16, uint16) {
-	return 60, 10
-}
-
-func (me *basicQos) wait() bool {
-	return true
-}
-
-func (me *basicQos) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.PrefetchSize); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.PrefetchCount); err != nil {
-		return
-	}
-
-	if me.Global {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicQos) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.PrefetchSize); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.PrefetchCount); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Global = (bits&(1<<0) > 0)
-
-	return
-}
-
-type basicQosOk struct {
-}
-
-func (me *basicQosOk) id() (uint16, uint16) {
-	return 60, 11
-}
-
-func (me *basicQosOk) wait() bool {
-	return true
-}
-
-func (me *basicQosOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *basicQosOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type basicConsume struct {
-	reserved1   uint16
-	Queue       string
-	ConsumerTag string
-	NoLocal     bool
-	NoAck       bool
-	Exclusive   bool
-	NoWait      bool
-	Arguments   Table
-}
-
-func (me *basicConsume) id() (uint16, uint16) {
-	return 60, 20
-}
-
-func (me *basicConsume) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *basicConsume) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.ConsumerTag); err != nil {
-		return
-	}
-
-	if me.NoLocal {
-		bits |= 1 << 0
-	}
-
-	if me.NoAck {
-		bits |= 1 << 1
-	}
-
-	if me.Exclusive {
-		bits |= 1 << 2
-	}
-
-	if me.NoWait {
-		bits |= 1 << 3
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeTable(w, me.Arguments); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicConsume) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.ConsumerTag, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.NoLocal = (bits&(1<<0) > 0)
-	me.NoAck = (bits&(1<<1) > 0)
-	me.Exclusive = (bits&(1<<2) > 0)
-	me.NoWait = (bits&(1<<3) > 0)
-
-	if me.Arguments, err = readTable(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicConsumeOk struct {
-	ConsumerTag string
-}
-
-func (me *basicConsumeOk) id() (uint16, uint16) {
-	return 60, 21
-}
-
-func (me *basicConsumeOk) wait() bool {
-	return true
-}
-
-func (me *basicConsumeOk) write(w io.Writer) (err error) {
-
-	if err = writeShortstr(w, me.ConsumerTag); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicConsumeOk) read(r io.Reader) (err error) {
-
-	if me.ConsumerTag, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicCancel struct {
-	ConsumerTag string
-	NoWait      bool
-}
-
-func (me *basicCancel) id() (uint16, uint16) {
-	return 60, 30
-}
-
-func (me *basicCancel) wait() bool {
-	return true && !me.NoWait
-}
-
-func (me *basicCancel) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = writeShortstr(w, me.ConsumerTag); err != nil {
-		return
-	}
-
-	if me.NoWait {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicCancel) read(r io.Reader) (err error) {
-	var bits byte
-
-	if me.ConsumerTag, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.NoWait = (bits&(1<<0) > 0)
-
-	return
-}
-
-type basicCancelOk struct {
-	ConsumerTag string
-}
-
-func (me *basicCancelOk) id() (uint16, uint16) {
-	return 60, 31
-}
-
-func (me *basicCancelOk) wait() bool {
-	return true
-}
-
-func (me *basicCancelOk) write(w io.Writer) (err error) {
-
-	if err = writeShortstr(w, me.ConsumerTag); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicCancelOk) read(r io.Reader) (err error) {
-
-	if me.ConsumerTag, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicPublish struct {
-	reserved1  uint16
-	Exchange   string
-	RoutingKey string
-	Mandatory  bool
-	Immediate  bool
-	Properties properties
-	Body       []byte
-}
-
-func (me *basicPublish) id() (uint16, uint16) {
-	return 60, 40
-}
-
-func (me *basicPublish) wait() bool {
-	return false
-}
-
-func (me *basicPublish) getContent() (properties, []byte) {
-	return me.Properties, me.Body
-}
-
-func (me *basicPublish) setContent(props properties, body []byte) {
-	me.Properties, me.Body = props, body
-}
-
-func (me *basicPublish) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	if me.Mandatory {
-		bits |= 1 << 0
-	}
-
-	if me.Immediate {
-		bits |= 1 << 1
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicPublish) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Mandatory = (bits&(1<<0) > 0)
-	me.Immediate = (bits&(1<<1) > 0)
-
-	return
-}
-
-type basicReturn struct {
-	ReplyCode  uint16
-	ReplyText  string
-	Exchange   string
-	RoutingKey string
-	Properties properties
-	Body       []byte
-}
-
-func (me *basicReturn) id() (uint16, uint16) {
-	return 60, 50
-}
-
-func (me *basicReturn) wait() bool {
-	return false
-}
-
-func (me *basicReturn) getContent() (properties, []byte) {
-	return me.Properties, me.Body
-}
-
-func (me *basicReturn) setContent(props properties, body []byte) {
-	me.Properties, me.Body = props, body
-}
-
-func (me *basicReturn) write(w io.Writer) (err error) {
-
-	if err = binary.Write(w, binary.BigEndian, me.ReplyCode); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.ReplyText); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicReturn) read(r io.Reader) (err error) {
-
-	if err = binary.Read(r, binary.BigEndian, &me.ReplyCode); err != nil {
-		return
-	}
-
-	if me.ReplyText, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicDeliver struct {
-	ConsumerTag string
-	DeliveryTag uint64
-	Redelivered bool
-	Exchange    string
-	RoutingKey  string
-	Properties  properties
-	Body        []byte
-}
-
-func (me *basicDeliver) id() (uint16, uint16) {
-	return 60, 60
-}
-
-func (me *basicDeliver) wait() bool {
-	return false
-}
-
-func (me *basicDeliver) getContent() (properties, []byte) {
-	return me.Properties, me.Body
-}
-
-func (me *basicDeliver) setContent(props properties, body []byte) {
-	me.Properties, me.Body = props, body
-}
-
-func (me *basicDeliver) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = writeShortstr(w, me.ConsumerTag); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.DeliveryTag); err != nil {
-		return
-	}
-
-	if me.Redelivered {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicDeliver) read(r io.Reader) (err error) {
-	var bits byte
-
-	if me.ConsumerTag, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.DeliveryTag); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Redelivered = (bits&(1<<0) > 0)
-
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicGet struct {
-	reserved1 uint16
-	Queue     string
-	NoAck     bool
-}
-
-func (me *basicGet) id() (uint16, uint16) {
-	return 60, 70
-}
-
-func (me *basicGet) wait() bool {
-	return true
-}
-
-func (me *basicGet) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.reserved1); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Queue); err != nil {
-		return
-	}
-
-	if me.NoAck {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicGet) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.reserved1); err != nil {
-		return
-	}
-
-	if me.Queue, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.NoAck = (bits&(1<<0) > 0)
-
-	return
-}
-
-type basicGetOk struct {
-	DeliveryTag  uint64
-	Redelivered  bool
-	Exchange     string
-	RoutingKey   string
-	MessageCount uint32
-	Properties   properties
-	Body         []byte
-}
-
-func (me *basicGetOk) id() (uint16, uint16) {
-	return 60, 71
-}
-
-func (me *basicGetOk) wait() bool {
-	return true
-}
-
-func (me *basicGetOk) getContent() (properties, []byte) {
-	return me.Properties, me.Body
-}
-
-func (me *basicGetOk) setContent(props properties, body []byte) {
-	me.Properties, me.Body = props, body
-}
-
-func (me *basicGetOk) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.DeliveryTag); err != nil {
-		return
-	}
-
-	if me.Redelivered {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	if err = writeShortstr(w, me.Exchange); err != nil {
-		return
-	}
-	if err = writeShortstr(w, me.RoutingKey); err != nil {
-		return
-	}
-
-	if err = binary.Write(w, binary.BigEndian, me.MessageCount); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicGetOk) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.DeliveryTag); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Redelivered = (bits&(1<<0) > 0)
-
-	if me.Exchange, err = readShortstr(r); err != nil {
-		return
-	}
-	if me.RoutingKey, err = readShortstr(r); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &me.MessageCount); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicGetEmpty struct {
-	reserved1 string
-}
-
-func (me *basicGetEmpty) id() (uint16, uint16) {
-	return 60, 72
-}
-
-func (me *basicGetEmpty) wait() bool {
-	return true
-}
-
-func (me *basicGetEmpty) write(w io.Writer) (err error) {
-
-	if err = writeShortstr(w, me.reserved1); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicGetEmpty) read(r io.Reader) (err error) {
-
-	if me.reserved1, err = readShortstr(r); err != nil {
-		return
-	}
-
-	return
-}
-
-type basicAck struct {
-	DeliveryTag uint64
-	Multiple    bool
-}
-
-func (me *basicAck) id() (uint16, uint16) {
-	return 60, 80
-}
-
-func (me *basicAck) wait() bool {
-	return false
-}
-
-func (me *basicAck) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.DeliveryTag); err != nil {
-		return
-	}
-
-	if me.Multiple {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicAck) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.DeliveryTag); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Multiple = (bits&(1<<0) > 0)
-
-	return
-}
-
-type basicReject struct {
-	DeliveryTag uint64
-	Requeue     bool
-}
-
-func (me *basicReject) id() (uint16, uint16) {
-	return 60, 90
-}
-
-func (me *basicReject) wait() bool {
-	return false
-}
-
-func (me *basicReject) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.DeliveryTag); err != nil {
-		return
-	}
-
-	if me.Requeue {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicReject) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.DeliveryTag); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Requeue = (bits&(1<<0) > 0)
-
-	return
-}
-
-type basicRecoverAsync struct {
-	Requeue bool
-}
-
-func (me *basicRecoverAsync) id() (uint16, uint16) {
-	return 60, 100
-}
-
-func (me *basicRecoverAsync) wait() bool {
-	return false
-}
-
-func (me *basicRecoverAsync) write(w io.Writer) (err error) {
-	var bits byte
-
-	if me.Requeue {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicRecoverAsync) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Requeue = (bits&(1<<0) > 0)
-
-	return
-}
-
-type basicRecover struct {
-	Requeue bool
-}
-
-func (me *basicRecover) id() (uint16, uint16) {
-	return 60, 110
-}
-
-func (me *basicRecover) wait() bool {
-	return true
-}
-
-func (me *basicRecover) write(w io.Writer) (err error) {
-	var bits byte
-
-	if me.Requeue {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicRecover) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Requeue = (bits&(1<<0) > 0)
-
-	return
-}
-
-type basicRecoverOk struct {
-}
-
-func (me *basicRecoverOk) id() (uint16, uint16) {
-	return 60, 111
-}
-
-func (me *basicRecoverOk) wait() bool {
-	return true
-}
-
-func (me *basicRecoverOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *basicRecoverOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type basicNack struct {
-	DeliveryTag uint64
-	Multiple    bool
-	Requeue     bool
-}
-
-func (me *basicNack) id() (uint16, uint16) {
-	return 60, 120
-}
-
-func (me *basicNack) wait() bool {
-	return false
-}
-
-func (me *basicNack) write(w io.Writer) (err error) {
-	var bits byte
-
-	if err = binary.Write(w, binary.BigEndian, me.DeliveryTag); err != nil {
-		return
-	}
-
-	if me.Multiple {
-		bits |= 1 << 0
-	}
-
-	if me.Requeue {
-		bits |= 1 << 1
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *basicNack) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &me.DeliveryTag); err != nil {
-		return
-	}
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Multiple = (bits&(1<<0) > 0)
-	me.Requeue = (bits&(1<<1) > 0)
-
-	return
-}
-
-type txSelect struct {
-}
-
-func (me *txSelect) id() (uint16, uint16) {
-	return 90, 10
-}
-
-func (me *txSelect) wait() bool {
-	return true
-}
-
-func (me *txSelect) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *txSelect) read(r io.Reader) (err error) {
-
-	return
-}
-
-type txSelectOk struct {
-}
-
-func (me *txSelectOk) id() (uint16, uint16) {
-	return 90, 11
-}
-
-func (me *txSelectOk) wait() bool {
-	return true
-}
-
-func (me *txSelectOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *txSelectOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type txCommit struct {
-}
-
-func (me *txCommit) id() (uint16, uint16) {
-	return 90, 20
-}
-
-func (me *txCommit) wait() bool {
-	return true
-}
-
-func (me *txCommit) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *txCommit) read(r io.Reader) (err error) {
-
-	return
-}
-
-type txCommitOk struct {
-}
-
-func (me *txCommitOk) id() (uint16, uint16) {
-	return 90, 21
-}
-
-func (me *txCommitOk) wait() bool {
-	return true
-}
-
-func (me *txCommitOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *txCommitOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type txRollback struct {
-}
-
-func (me *txRollback) id() (uint16, uint16) {
-	return 90, 30
-}
-
-func (me *txRollback) wait() bool {
-	return true
-}
-
-func (me *txRollback) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *txRollback) read(r io.Reader) (err error) {
-
-	return
-}
-
-type txRollbackOk struct {
-}
-
-func (me *txRollbackOk) id() (uint16, uint16) {
-	return 90, 31
-}
-
-func (me *txRollbackOk) wait() bool {
-	return true
-}
-
-func (me *txRollbackOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *txRollbackOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-type confirmSelect struct {
-	Nowait bool
-}
-
-func (me *confirmSelect) id() (uint16, uint16) {
-	return 85, 10
-}
-
-func (me *confirmSelect) wait() bool {
-	return true
-}
-
-func (me *confirmSelect) write(w io.Writer) (err error) {
-	var bits byte
-
-	if me.Nowait {
-		bits |= 1 << 0
-	}
-
-	if err = binary.Write(w, binary.BigEndian, bits); err != nil {
-		return
-	}
-
-	return
-}
-
-func (me *confirmSelect) read(r io.Reader) (err error) {
-	var bits byte
-
-	if err = binary.Read(r, binary.BigEndian, &bits); err != nil {
-		return
-	}
-	me.Nowait = (bits&(1<<0) > 0)
-
-	return
-}
-
-type confirmSelectOk struct {
-}
-
-func (me *confirmSelectOk) id() (uint16, uint16) {
-	return 85, 11
-}
-
-func (me *confirmSelectOk) wait() bool {
-	return true
-}
-
-func (me *confirmSelectOk) write(w io.Writer) (err error) {
-
-	return
-}
-
-func (me *confirmSelectOk) read(r io.Reader) (err error) {
-
-	return
-}
-
-func (me *reader) parseMethodFrame(channel uint16, size uint32) (f frame, err error) {
-	mf := &methodFrame{
-		ChannelId: channel,
-	}
-
-	if err = binary.Read(me.r, binary.BigEndian, &mf.ClassId); err != nil {
-		return
-	}
-
-	if err = binary.Read(me.r, binary.BigEndian, &mf.MethodId); err != nil {
-		return
-	}
-
-	switch mf.ClassId {
-
-	case 10: // connection
-		switch mf.MethodId {
-
-		case 10: // connection start
-			//fmt.Println("NextMethod: class:10 method:10")
-			method := &connectionStart{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 11: // connection start-ok
-			//fmt.Println("NextMethod: class:10 method:11")
-			method := &connectionStartOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 20: // connection secure
-			//fmt.Println("NextMethod: class:10 method:20")
-			method := &connectionSecure{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 21: // connection secure-ok
-			//fmt.Println("NextMethod: class:10 method:21")
-			method := &connectionSecureOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 30: // connection tune
-			//fmt.Println("NextMethod: class:10 method:30")
-			method := &connectionTune{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 31: // connection tune-ok
-			//fmt.Println("NextMethod: class:10 method:31")
-			method := &connectionTuneOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 40: // connection open
-			//fmt.Println("NextMethod: class:10 method:40")
-			method := &connectionOpen{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 41: // connection open-ok
-			//fmt.Println("NextMethod: class:10 method:41")
-			method := &connectionOpenOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 50: // connection close
-			//fmt.Println("NextMethod: class:10 method:50")
-			method := &connectionClose{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 51: // connection close-ok
-			//fmt.Println("NextMethod: class:10 method:51")
-			method := &connectionCloseOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 60: // connection blocked
-			//fmt.Println("NextMethod: class:10 method:60")
-			method := &connectionBlocked{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 61: // connection unblocked
-			//fmt.Println("NextMethod: class:10 method:61")
-			method := &connectionUnblocked{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		default:
-			return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-		}
-
-	case 20: // channel
-		switch mf.MethodId {
-
-		case 10: // channel open
-			//fmt.Println("NextMethod: class:20 method:10")
-			method := &channelOpen{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 11: // channel open-ok
-			//fmt.Println("NextMethod: class:20 method:11")
-			method := &channelOpenOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 20: // channel flow
-			//fmt.Println("NextMethod: class:20 method:20")
-			method := &channelFlow{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 21: // channel flow-ok
-			//fmt.Println("NextMethod: class:20 method:21")
-			method := &channelFlowOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 40: // channel close
-			//fmt.Println("NextMethod: class:20 method:40")
-			method := &channelClose{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 41: // channel close-ok
-			//fmt.Println("NextMethod: class:20 method:41")
-			method := &channelCloseOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		default:
-			return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-		}
-
-	case 40: // exchange
-		switch mf.MethodId {
-
-		case 10: // exchange declare
-			//fmt.Println("NextMethod: class:40 method:10")
-			method := &exchangeDeclare{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 11: // exchange declare-ok
-			//fmt.Println("NextMethod: class:40 method:11")
-			method := &exchangeDeclareOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 20: // exchange delete
-			//fmt.Println("NextMethod: class:40 method:20")
-			method := &exchangeDelete{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 21: // exchange delete-ok
-			//fmt.Println("NextMethod: class:40 method:21")
-			method := &exchangeDeleteOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 30: // exchange bind
-			//fmt.Println("NextMethod: class:40 method:30")
-			method := &exchangeBind{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 31: // exchange bind-ok
-			//fmt.Println("NextMethod: class:40 method:31")
-			method := &exchangeBindOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 40: // exchange unbind
-			//fmt.Println("NextMethod: class:40 method:40")
-			method := &exchangeUnbind{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 51: // exchange unbind-ok
-			//fmt.Println("NextMethod: class:40 method:51")
-			method := &exchangeUnbindOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		default:
-			return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-		}
-
-	case 50: // queue
-		switch mf.MethodId {
-
-		case 10: // queue declare
-			//fmt.Println("NextMethod: class:50 method:10")
-			method := &queueDeclare{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 11: // queue declare-ok
-			//fmt.Println("NextMethod: class:50 method:11")
-			method := &queueDeclareOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 20: // queue bind
-			//fmt.Println("NextMethod: class:50 method:20")
-			method := &queueBind{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 21: // queue bind-ok
-			//fmt.Println("NextMethod: class:50 method:21")
-			method := &queueBindOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 50: // queue unbind
-			//fmt.Println("NextMethod: class:50 method:50")
-			method := &queueUnbind{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 51: // queue unbind-ok
-			//fmt.Println("NextMethod: class:50 method:51")
-			method := &queueUnbindOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 30: // queue purge
-			//fmt.Println("NextMethod: class:50 method:30")
-			method := &queuePurge{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 31: // queue purge-ok
-			//fmt.Println("NextMethod: class:50 method:31")
-			method := &queuePurgeOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 40: // queue delete
-			//fmt.Println("NextMethod: class:50 method:40")
-			method := &queueDelete{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 41: // queue delete-ok
-			//fmt.Println("NextMethod: class:50 method:41")
-			method := &queueDeleteOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		default:
-			return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-		}
-
-	case 60: // basic
-		switch mf.MethodId {
-
-		case 10: // basic qos
-			//fmt.Println("NextMethod: class:60 method:10")
-			method := &basicQos{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 11: // basic qos-ok
-			//fmt.Println("NextMethod: class:60 method:11")
-			method := &basicQosOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 20: // basic consume
-			//fmt.Println("NextMethod: class:60 method:20")
-			method := &basicConsume{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 21: // basic consume-ok
-			//fmt.Println("NextMethod: class:60 method:21")
-			method := &basicConsumeOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 30: // basic cancel
-			//fmt.Println("NextMethod: class:60 method:30")
-			method := &basicCancel{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 31: // basic cancel-ok
-			//fmt.Println("NextMethod: class:60 method:31")
-			method := &basicCancelOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 40: // basic publish
-			//fmt.Println("NextMethod: class:60 method:40")
-			method := &basicPublish{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 50: // basic return
-			//fmt.Println("NextMethod: class:60 method:50")
-			method := &basicReturn{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 60: // basic deliver
-			//fmt.Println("NextMethod: class:60 method:60")
-			method := &basicDeliver{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 70: // basic get
-			//fmt.Println("NextMethod: class:60 method:70")
-			method := &basicGet{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 71: // basic get-ok
-			//fmt.Println("NextMethod: class:60 method:71")
-			method := &basicGetOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 72: // basic get-empty
-			//fmt.Println("NextMethod: class:60 method:72")
-			method := &basicGetEmpty{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 80: // basic ack
-			//fmt.Println("NextMethod: class:60 method:80")
-			method := &basicAck{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 90: // basic reject
-			//fmt.Println("NextMethod: class:60 method:90")
-			method := &basicReject{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 100: // basic recover-async
-			//fmt.Println("NextMethod: class:60 method:100")
-			method := &basicRecoverAsync{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 110: // basic recover
-			//fmt.Println("NextMethod: class:60 method:110")
-			method := &basicRecover{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 111: // basic recover-ok
-			//fmt.Println("NextMethod: class:60 method:111")
-			method := &basicRecoverOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 120: // basic nack
-			//fmt.Println("NextMethod: class:60 method:120")
-			method := &basicNack{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		default:
-			return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-		}
-
-	case 90: // tx
-		switch mf.MethodId {
-
-		case 10: // tx select
-			//fmt.Println("NextMethod: class:90 method:10")
-			method := &txSelect{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 11: // tx select-ok
-			//fmt.Println("NextMethod: class:90 method:11")
-			method := &txSelectOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 20: // tx commit
-			//fmt.Println("NextMethod: class:90 method:20")
-			method := &txCommit{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 21: // tx commit-ok
-			//fmt.Println("NextMethod: class:90 method:21")
-			method := &txCommitOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 30: // tx rollback
-			//fmt.Println("NextMethod: class:90 method:30")
-			method := &txRollback{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 31: // tx rollback-ok
-			//fmt.Println("NextMethod: class:90 method:31")
-			method := &txRollbackOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		default:
-			return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-		}
-
-	case 85: // confirm
-		switch mf.MethodId {
-
-		case 10: // confirm select
-			//fmt.Println("NextMethod: class:85 method:10")
-			method := &confirmSelect{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		case 11: // confirm select-ok
-			//fmt.Println("NextMethod: class:85 method:11")
-			method := &confirmSelectOk{}
-			if err = method.read(me.r); err != nil {
-				return
-			}
-			mf.Method = method
-
-		default:
-			return nil, fmt.Errorf("Bad method frame, unknown method %d for class %d", mf.MethodId, mf.ClassId)
-		}
-
-	default:
-		return nil, fmt.Errorf("Bad method frame, unknown class %d", mf.ClassId)
-	}
-
-	return mf, nil
-}

+ 0 - 218
vendor/github.com/streadway/amqp/tls_test.go

@@ -1,218 +0,0 @@
-package amqp_test
-
-import (
-	"crypto/tls"
-	"crypto/x509"
-	"fmt"
-	"github.com/streadway/amqp"
-	"io"
-	"net"
-	"testing"
-	"time"
-)
-
-type tlsServer struct {
-	net.Listener
-	URL    string
-	Config *tls.Config
-	Header chan []byte
-}
-
-// Captures the header for each accepted connection
-func (s *tlsServer) Serve() {
-	for {
-		c, err := s.Accept()
-		if err != nil {
-			return
-		}
-
-		header := make([]byte, 4)
-		io.ReadFull(c, header)
-		s.Header <- header
-		c.Write([]byte{'A', 'M', 'Q', 'P', 0, 0, 0, 0})
-		c.Close()
-	}
-}
-
-func tlsConfig() *tls.Config {
-	cfg := new(tls.Config)
-
-	cfg.ClientCAs = x509.NewCertPool()
-	cfg.ClientCAs.AppendCertsFromPEM([]byte(caCert))
-
-	cert, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey))
-	if err != nil {
-		panic(err)
-	}
-
-	cfg.Certificates = append(cfg.Certificates, cert)
-	cfg.ClientAuth = tls.RequireAndVerifyClientCert
-
-	return cfg
-}
-
-func startTlsServer() tlsServer {
-	cfg := tlsConfig()
-
-	l, err := tls.Listen("tcp", "127.0.0.1:0", cfg)
-	if err != nil {
-		panic(err)
-	}
-
-	s := tlsServer{
-		Listener: l,
-		Config:   cfg,
-		URL:      fmt.Sprintf("amqps://%s/", l.Addr().String()),
-		Header:   make(chan []byte, 1),
-	}
-
-	go s.Serve()
-	return s
-}
-
-// Tests that the server has handshaked the connection and seen the client
-// protocol announcement.  Does not nest that the connection.open is successful.
-func TestTLSHandshake(t *testing.T) {
-	srv := startTlsServer()
-	defer srv.Close()
-
-	cfg := new(tls.Config)
-	cfg.RootCAs = x509.NewCertPool()
-	cfg.RootCAs.AppendCertsFromPEM([]byte(caCert))
-
-	cert, _ := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
-	cfg.Certificates = append(cfg.Certificates, cert)
-
-	_, err := amqp.DialTLS(srv.URL, cfg)
-
-	select {
-	case <-time.After(10 * time.Millisecond):
-		t.Fatalf("did not succeed to handshake the TLS connection after 10ms")
-	case header := <-srv.Header:
-		if string(header) != "AMQP" {
-			t.Fatalf("expected to handshake a TLS connection, got err: %v", err)
-		}
-	}
-}
-
-const caCert = `
------BEGIN CERTIFICATE-----
-MIICxjCCAa6gAwIBAgIJANWuMWMQSxvdMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
-BAMTCE15VGVzdENBMB4XDTE0MDEyNzE5NTIyMloXDTI0MDEyNTE5NTIyMlowEzER
-MA8GA1UEAxMITXlUZXN0Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQDBsIrkW4ob9Z/gzR2/Maa2stbutry6/vvz8eiJwIKIbaHGwqtFOUGiWeKw7H76
-IH3SjTAhNQY2hoKPyH41D36sDJkYBRyHFJTK/6ffvOhpyLnuXJAnoS62eKPSNUAx
-5i/lkHj42ESutYAH9qbHCI/gBm9G4WmhGAyA16xzC1n07JObl6KFoY1PqHKl823z
-mvF47I24DzemEfjdwC9nAAX/pGYOg9FA9nQv7NnhlsJMxueCx55RNU1ADRoqsbfE
-T0CQTOT4ryugGrUp9J4Cwen6YbXZrS6+Kff5SQCAns0Qu8/bwj0DKkuBGLF+Mnwe
-mq9bMzyZPUrPM3Gu48ao8YAfAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0P
-BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCBwXGblRxIEOlEP6ANZ1C8AHWyG8lR
-CQduFclc0tmyCCz5fnyLK0aGu9LhXXe6/HSKqgs4mJqeqYOojdjkfOme/YdwDzjK
-WIf0kRYQHcB6NeyEZwW8C7subTP1Xw6zbAmjvQrtCGvRM+fi3/cs1sSSkd/EoRk4
-7GM9qQl/JIIoCOGncninf2NQm5YSpbit6/mOQD7EhqXsw+bX+IRh3DHC1Apv/PoA
-HlDNeM4vjWaBxsmvRSndrIvew1czboFM18oRSSIqAkU7dKZ0SbC11grzmNxMG2aD
-f9y8FIG6RK/SEaOZuc+uBGXx7tj7dczpE/2puqYcaVGwcv4kkrC/ZuRm
------END CERTIFICATE-----
-`
-
-const serverCert = `
------BEGIN CERTIFICATE-----
-MIIC8zCCAdugAwIBAgIBATANBgkqhkiG9w0BAQUFADATMREwDwYDVQQDEwhNeVRl
-c3RDQTAeFw0xNDAxMjcxOTUyMjNaFw0yNDAxMjUxOTUyMjNaMCUxEjAQBgNVBAMT
-CTEyNy4wLjAuMTEPMA0GA1UEChMGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAxYAKbeGyg0gP0xwVsZsufzk/SUCtD44Gp3lQYQ9QumQ1IVZu
-PmZWwPWrzI93a1Abruz6ZhXaB3jcL5QPAy1N44IiFgVN45CZXBsqkpJe/abzRFOV
-DRnHxattPDHdgwML5d3nURKGUM/7+ACj5E4pZEDlM3RIjIKVd+doJsL7n6myO8FE
-tIpt4vTz1MFp3F+ntPnHU3BZ/VZ1UjSlFWnCjT0CR0tnXsPmlIaC98HThS8x5zNB
-fvvSN+Zln8RWdNLnEVHVdqYtOQ828QbCx8s1HfClGgaVoSDrzz+qQgtZFO4wW264
-2CWkNd8DSJUJ/HlPNXmbXsrRMgvGaL7YUz2yRQIDAQABo0AwPjAJBgNVHRMEAjAA
-MAsGA1UdDwQEAwIFIDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHREECDAGhwR/
-AAABMA0GCSqGSIb3DQEBBQUAA4IBAQAE2g+wAFf9Xg5svcnb7+mfseYV16k9l5WG
-onrmR3FLsbTxfbr4PZJMHrswPbi2NRk0+ETPUpcv1RP7pUB7wSEvuS1NPGcU92iP
-58ycP3dYtLzmuu6BkgToZqwsCU8fC2zM0wt3+ifzPpDMffWWOioVuA3zdM9WPQYz
-+Ofajd0XaZwFZS8uTI5WXgObz7Xqfmln4tF3Sq1CTyuJ44qK4p83XOKFq+L04aD0
-d0c8w3YQNUENny/vMP9mDu3FQ3SnDz2GKl1LSjGe2TUnkoMkDfdk4wSzndTz/ecb
-QiCPKijwVPWNOWV3NDE2edMxDPxDoKoEm5F4UGfGjxSRnYCIoZLh
------END CERTIFICATE-----
-`
-
-const serverKey = `
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAxYAKbeGyg0gP0xwVsZsufzk/SUCtD44Gp3lQYQ9QumQ1IVZu
-PmZWwPWrzI93a1Abruz6ZhXaB3jcL5QPAy1N44IiFgVN45CZXBsqkpJe/abzRFOV
-DRnHxattPDHdgwML5d3nURKGUM/7+ACj5E4pZEDlM3RIjIKVd+doJsL7n6myO8FE
-tIpt4vTz1MFp3F+ntPnHU3BZ/VZ1UjSlFWnCjT0CR0tnXsPmlIaC98HThS8x5zNB
-fvvSN+Zln8RWdNLnEVHVdqYtOQ828QbCx8s1HfClGgaVoSDrzz+qQgtZFO4wW264
-2CWkNd8DSJUJ/HlPNXmbXsrRMgvGaL7YUz2yRQIDAQABAoIBAGsyEvcPAGg3DbfE
-z5WFp9gPx2TIAOanbL8rnlAAEw4H47qDgfTGcSHsdeHioKuTYGMyZrpP8/YISGJe
-l0NfLJ5mfH+9Q0hXrJWMfS/u2DYOjo0wXH8u1fpZEEISwqsgVS3fonSjfFmSea1j
-E5GQRvEONBkYbWQuYFgjNqmLPS2r5lKbWCQvc1MB/vvVBwOTiO0ON7m/EkM5RKt9
-cDT5ZhhVjBpdmd9HpVbKTdBj8Q0l5/ZHZUEgZA6FDZEwYxTd9l87Z4YT+5SR0z9t
-k8/Z0CHd3x3Rv891t7m66ZJkaOda8NC65/432MQEQwJltmrKnc22dS8yI26rrmpp
-g3tcbSUCgYEA5nMXdQKS4vF+Kp10l/HqvGz2sU8qQaWYZQIg7Th3QJPo6N52po/s
-nn3UF0P5mT1laeZ5ZQJKx4gnmuPnIZ2ZtJQDyFhIbRPcZ+2hSNSuLYVcrumOC3EP
-3OZyFtFE1THO73aFe5e1jEdtoOne3Bds/Hq6NF45fkVdL+M9e8pfXIsCgYEA22W8
-zGjbWyrFOYvKknMQVtHnMx8BJEtsvWRknP6CWAv/8WyeZpE128Pve1m441AQnopS
-CuOF5wFK0iUXBFbS3Pe1/1j3em6yfVznuUHqJ7Qc+dNzxVvkTK8jGB6x+vm+M9Hg
-muHUM726IUxckoSNXbPNAVPIZab1NdSxam7F9m8CgYEAx55QZmIJXJ41XLKxqWC7
-peZ5NpPNlbncrTpPzUzJN94ntXfmrVckbxGt401VayEctMQYyZ9XqUlOjUP3FU5Q
-M3S3Zhba/eljVX8o406fZf0MkNLs4QpZ5E6V6x/xEP+pMhKng6yhbVb+JpIPIvUD
-yhyBKRWplbB+DRo5Sv685gsCgYA7l5m9h+m1DJv/cnn2Z2yTuHXtC8namuYRV1iA
-0ByFX9UINXGc+GpBpCnDPm6ax5+MAJQiQwSW52H0TIDA+/hQbrQvhHHL/o9av8Zt
-Kns4h5KrRQUYIUqUjamhnozHV9iS6LnyN87Usv8AlmY6oehoADN53dD702qdUYVT
-HH2G3wKBgCdvqyw78FR/n8cUWesTPnxx5HCeWJ1J+2BESnUnPmKZ71CV1H7uweja
-vPUxuuuGLKfNx84OKCfRDbtOgMOeyh9T1RmXry6Srz/7/udjlF0qmFiRXfBNAgoR
-tNb0+Ri/vY0AHrQ7UnCbl12qPVaqhEXLr+kCGNEPFqpMJPPEeMK0
------END RSA PRIVATE KEY-----
-`
-
-const clientCert = `
------BEGIN CERTIFICATE-----
-MIIC4jCCAcqgAwIBAgIBAjANBgkqhkiG9w0BAQUFADATMREwDwYDVQQDEwhNeVRl
-c3RDQTAeFw0xNDAxMjcxOTUyMjNaFw0yNDAxMjUxOTUyMjNaMCUxEjAQBgNVBAMT
-CTEyNy4wLjAuMTEPMA0GA1UEChMGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAu7LMqd+agoH168Bsi0WJ36ulYqDypq+GZPF7uWOo2pE0raKH
-B++31/hjnkt6yC5kLKVZZ0EfolBa9q4Cy6swfGaEMafy44ZCRneLnt1azL1N6Kfz
-+U0KsOqyQDoMxYJG1gVTEZN19/U/ew2eazcxKyERI3oGCQ4SbpkxBTbfxtAFk49e
-xIB3obsuMVUrmtXE4FkUkvG7NgpPUgrhp0yxYpj9zruZGzGGT1zNhcarbQ/4i7It
-ZMbnv6pqQWtYDgnGX2TDRcEiXGeO+KrzhfpTRLfO3K4np8e8cmTyXM+4lMlWUgma
-KrRdu1QXozGqRs47u2prGKGdSQWITpqNVCY8fQIDAQABoy8wLTAJBgNVHRMEAjAA
-MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQUF
-AAOCAQEAhCuBCLznPc4O96hT3P8Fx19L3ltrWbc/pWrx8JjxUaGk8kNmjMjY+/Mt
-JBbjUBx2kJwaY0EHMAfw7D1f1wcCeNycx/0dyb0E6xzhmPw5fY15GGNg8rzWwqSY
-+i/1iqU0IRkmRHV7XCF+trd2H0Ec+V1Fd/61E2ccJfOL5aSAyWbMCUtWxS3QMnqH
-FBfKdVEiY9WNht5hnvsXQBRaNhowJ6Cwa7/1/LZjmhcXiJ0xrc1Hggj3cvS+4vll
-Ew+20a0tPKjD/v/2oSQL+qkeYKV4fhCGkaBHCpPlSJrqorb7B6NmPy3nS26ETKE/
-o2UCfZc5g2MU1ENa31kT1iuhKZapsA==
------END CERTIFICATE-----
-`
-
-const clientKey = `
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAu7LMqd+agoH168Bsi0WJ36ulYqDypq+GZPF7uWOo2pE0raKH
-B++31/hjnkt6yC5kLKVZZ0EfolBa9q4Cy6swfGaEMafy44ZCRneLnt1azL1N6Kfz
-+U0KsOqyQDoMxYJG1gVTEZN19/U/ew2eazcxKyERI3oGCQ4SbpkxBTbfxtAFk49e
-xIB3obsuMVUrmtXE4FkUkvG7NgpPUgrhp0yxYpj9zruZGzGGT1zNhcarbQ/4i7It
-ZMbnv6pqQWtYDgnGX2TDRcEiXGeO+KrzhfpTRLfO3K4np8e8cmTyXM+4lMlWUgma
-KrRdu1QXozGqRs47u2prGKGdSQWITpqNVCY8fQIDAQABAoIBAGSEn3hFyEAmCyYi
-2b5IEksXaC2GlgxQKb/7Vs/0oCPU6YonZPsKFMFzQx4tu+ZiecEzF8rlJGTPdbdv
-fw3FcuTcHeVd1QSmDO4h7UK5tnu40XVMJKsY6CXQun8M13QajYbmORNLjjypOULU
-C0fNueYoAj6mhX7p61MRdSAev/5+0+bVQQG/tSVDQzdngvKpaCunOphiB2VW2Aa0
-7aYPOFCoPB2uo0DwUmBB0yfx9x4hXX9ovQI0YFou7bq6iYJ0vlZBvYQ9YrVdxjKL
-avcz1N5xM3WFAkZJSVT/Ho5+uTbZx4RrJ8b5T+t2spOKmXyAjwS2rL/XMAh8YRZ1
-u44duoECgYEA4jpK2qshgQ0t49rjVHEDKX5x7ElEZefl0rHZ/2X/uHUDKpKj2fTq
-3TQzHquiQ4Aof7OEB9UE3DGrtpvo/j/PYxL5Luu5VR4AIEJm+CA8GYuE96+uIL0Z
-M2r3Lux6Bp30Z47Eit2KiY4fhrWs59WB3NHHoFxgzHSVbnuA02gcX2ECgYEA1GZw
-iXIVYaK07ED+q/0ObyS5hD1cMhJ7ifSN9BxuG0qUpSigbkTGj09fUDS4Fqsz9dvz
-F0P93fZvyia242TIfDUwJEsDQCgHk7SGa4Rx/p/3x/obIEERk7K76Hdg93U5NXhV
-NvczvgL0HYxnb+qtumwMgGPzncB4lGcTnRyOfp0CgYBTIsDnYwRI/KLknUf1fCKB
-WSpcfwBXwsS+jQVjygQTsUyclI8KResZp1kx6DkVPT+kzj+y8SF8GfTUgq844BJC
-gnJ4P8A3+3JoaH6WqKHtcUxICZOgDF36e1CjOdwOGnX6qIipz4hdzJDhXFpSSDAV
-CjKmR8x61k0j8NcC2buzgQKBgFr7eo9VwBTvpoJhIPY5UvqHB7S+uAR26FZi3H/J
-wdyM6PmKWpaBfXCb9l8cBhMnyP0y94FqzY9L5fz48nSbkkmqWvHg9AaCXySFOuNJ
-e68vhOszlnUNimLzOAzPPkkh/JyL7Cy8XXyyNTGHGDPXmg12BTDmH8/eR4iCUuOE
-/QD9AoGBALQ/SkvfO3D5+k9e/aTHRuMJ0+PWdLUMTZ39oJQxUx+qj7/xpjDvWTBn
-eDmF/wjnIAg+020oXyBYo6plEZfDz3EYJQZ+3kLLEU+O/A7VxCakPYPwCr7N/InL
-Ccg/TVSIXxw/6uJnojoAjMIEU45NoP6RMp0mWYYb2OlteEv08Ovp
------END RSA PRIVATE KEY-----
-`

+ 0 - 382
vendor/github.com/streadway/amqp/types.go

@@ -1,382 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"fmt"
-	"io"
-	"time"
-)
-
-var (
-	// Errors that this library could return/emit from a channel or connection
-	ErrClosed          = &Error{Code: ChannelError, Reason: "channel/connection is not open"}
-	ErrChannelMax      = &Error{Code: ChannelError, Reason: "channel id space exhausted"}
-	ErrSASL            = &Error{Code: AccessRefused, Reason: "SASL could not negotiate a shared mechanism"}
-	ErrCredentials     = &Error{Code: AccessRefused, Reason: "username or password not allowed"}
-	ErrVhost           = &Error{Code: AccessRefused, Reason: "no access to this vhost"}
-	ErrSyntax          = &Error{Code: SyntaxError, Reason: "invalid field or value inside of a frame"}
-	ErrFrame           = &Error{Code: FrameError, Reason: "frame could not be parsed"}
-	ErrCommandInvalid  = &Error{Code: CommandInvalid, Reason: "unexpected command received"}
-	ErrUnexpectedFrame = &Error{Code: UnexpectedFrame, Reason: "unexpected frame received"}
-	ErrFieldType       = &Error{Code: SyntaxError, Reason: "unsupported table field type"}
-)
-
-// Error captures the code and reason a channel or connection has been closed
-// by the server.
-type Error struct {
-	Code    int    // constant code from the specification
-	Reason  string // description of the error
-	Server  bool   // true when initiated from the server, false when from this library
-	Recover bool   // true when this error can be recovered by retrying later or with differnet parameters
-}
-
-func newError(code uint16, text string) *Error {
-	return &Error{
-		Code:    int(code),
-		Reason:  text,
-		Recover: isSoftExceptionCode(int(code)),
-		Server:  true,
-	}
-}
-
-func (me Error) Error() string {
-	return fmt.Sprintf("Exception (%d) Reason: %q", me.Code, me.Reason)
-}
-
-// Used by header frames to capture routing and header information
-type properties struct {
-	ContentType     string    // MIME content type
-	ContentEncoding string    // MIME content encoding
-	Headers         Table     // Application or header exchange table
-	DeliveryMode    uint8     // queue implemention use - Transient (1) or Persistent (2)
-	Priority        uint8     // queue implementation use - 0 to 9
-	CorrelationId   string    // application use - correlation identifier
-	ReplyTo         string    // application use - address to to reply to (ex: RPC)
-	Expiration      string    // implementation use - message expiration spec
-	MessageId       string    // application use - message identifier
-	Timestamp       time.Time // application use - message timestamp
-	Type            string    // application use - message type name
-	UserId          string    // application use - creating user id
-	AppId           string    // application use - creating application
-	reserved1       string    // was cluster-id - process for buffer consumption
-}
-
-// DeliveryMode.  Transient means higher throughput but messages will not be
-// restored on broker restart.  The delivery mode of publishings is unrelated
-// to the durability of the queues they reside on.  Transient messages will
-// not be restored to durable queues, persistent messages will be restored to
-// durable queues and lost on non-durable queues during server restart.
-//
-// This remains typed as uint8 to match Publishing.DeliveryMode.  Other
-// delivery modes specific to custom queue implementations are not enumerated
-// here.
-const (
-	Transient  uint8 = 1
-	Persistent uint8 = 2
-)
-
-// The property flags are an array of bits that indicate the presence or
-// absence of each property value in sequence.  The bits are ordered from most
-// high to low - bit 15 indicates the first property.
-const (
-	flagContentType     = 0x8000
-	flagContentEncoding = 0x4000
-	flagHeaders         = 0x2000
-	flagDeliveryMode    = 0x1000
-	flagPriority        = 0x0800
-	flagCorrelationId   = 0x0400
-	flagReplyTo         = 0x0200
-	flagExpiration      = 0x0100
-	flagMessageId       = 0x0080
-	flagTimestamp       = 0x0040
-	flagType            = 0x0020
-	flagUserId          = 0x0010
-	flagAppId           = 0x0008
-	flagReserved1       = 0x0004
-)
-
-// Queue captures the current server state of the queue on the server returned
-// from Channel.QueueDeclare or Channel.QueueInspect.
-type Queue struct {
-	Name      string // server confirmed or generated name
-	Messages  int    // count of messages not awaiting acknowledgment
-	Consumers int    // number of consumers receiving deliveries
-}
-
-// Publishing captures the client message sent to the server.  The fields
-// outside of the Headers table included in this struct mirror the underlying
-// fields in the content frame.  They use native types for convenience and
-// efficiency.
-type Publishing struct {
-	// Application or exchange specific fields,
-	// the headers exchange will inspect this field.
-	Headers Table
-
-	// Properties
-	ContentType     string    // MIME content type
-	ContentEncoding string    // MIME content encoding
-	DeliveryMode    uint8     // Transient (0 or 1) or Persistent (2)
-	Priority        uint8     // 0 to 9
-	CorrelationId   string    // correlation identifier
-	ReplyTo         string    // address to to reply to (ex: RPC)
-	Expiration      string    // message expiration spec
-	MessageId       string    // message identifier
-	Timestamp       time.Time // message timestamp
-	Type            string    // message type name
-	UserId          string    // creating user id - ex: "guest"
-	AppId           string    // creating application id
-
-	// The application specific payload of the message
-	Body []byte
-}
-
-// Blocking notifies the server's TCP flow control of the Connection.  When a
-// server hits a memory or disk alarm it will block all connections until the
-// resources are reclaimed.  Use NotifyBlock on the Connection to receive these
-// events.
-type Blocking struct {
-	Active bool   // TCP pushback active/inactive on server
-	Reason string // Server reason for activation
-}
-
-// Decimal matches the AMQP decimal type.  Scale is the number of decimal
-// digits Scale == 2, Value == 12345, Decimal == 123.45
-type Decimal struct {
-	Scale uint8
-	Value int32
-}
-
-// Table stores user supplied fields of the following types:
-//
-//   bool
-//   byte
-//   float32
-//   float64
-//   int16
-//   int32
-//   int64
-//   nil
-//   string
-//   time.Time
-//   amqp.Decimal
-//   amqp.Table
-//   []byte
-//   []interface{} - containing above types
-//
-// Functions taking a table will immediately fail when the table contains a
-// value of an unsupported type.
-//
-// The caller must be specific in which precision of integer it wishes to
-// encode.
-//
-// Use a type assertion when reading values from a table for type converstion.
-//
-// RabbitMQ expects int32 for integer values.
-//
-type Table map[string]interface{}
-
-func validateField(f interface{}) error {
-	switch fv := f.(type) {
-	case nil, bool, byte, int16, int32, int64, float32, float64, string, []byte, Decimal, time.Time:
-		return nil
-
-	case []interface{}:
-		for _, v := range fv {
-			if err := validateField(v); err != nil {
-				return fmt.Errorf("in array %s", err)
-			}
-		}
-		return nil
-
-	case Table:
-		for k, v := range fv {
-			if err := validateField(v); err != nil {
-				return fmt.Errorf("table field %q %s", k, err)
-			}
-		}
-		return nil
-	}
-
-	return fmt.Errorf("value %t not supported", f)
-}
-
-func (t Table) Validate() error {
-	return validateField(t)
-}
-
-// Heap interface for maintaining delivery tags
-type tagSet []uint64
-
-func (me tagSet) Len() int              { return len(me) }
-func (me tagSet) Less(i, j int) bool    { return (me)[i] < (me)[j] }
-func (me tagSet) Swap(i, j int)         { (me)[i], (me)[j] = (me)[j], (me)[i] }
-func (me *tagSet) Push(tag interface{}) { *me = append(*me, tag.(uint64)) }
-func (me *tagSet) Pop() interface{} {
-	val := (*me)[len(*me)-1]
-	*me = (*me)[:len(*me)-1]
-	return val
-}
-
-type message interface {
-	id() (uint16, uint16)
-	wait() bool
-	read(io.Reader) error
-	write(io.Writer) error
-}
-
-type messageWithContent interface {
-	message
-	getContent() (properties, []byte)
-	setContent(properties, []byte)
-}
-
-/*
-The base interface implemented as:
-
-2.3.5  frame Details
-
-All frames consist of a header (7 octets), a payload of arbitrary size, and a 'frame-end' octet that detects
-malformed frames:
-
-  0      1         3             7                  size+7 size+8
-  +------+---------+-------------+  +------------+  +-----------+
-  | type | channel |     size    |  |  payload   |  | frame-end |
-  +------+---------+-------------+  +------------+  +-----------+
-   octet   short         long         size octets       octet
-
-To read a frame, we:
-
- 1. Read the header and check the frame type and channel.
- 2. Depending on the frame type, we read the payload and process it.
- 3. Read the frame end octet.
-
-In realistic implementations where performance is a concern, we would use
-“read-ahead buffering” or “gathering reads” to avoid doing three separate
-system calls to read a frame.
-
-*/
-type frame interface {
-	write(io.Writer) error
-	channel() uint16
-}
-
-type reader struct {
-	r io.Reader
-}
-
-type writer struct {
-	w io.Writer
-}
-
-// Implements the frame interface for Connection RPC
-type protocolHeader struct{}
-
-func (protocolHeader) write(w io.Writer) error {
-	_, err := w.Write([]byte{'A', 'M', 'Q', 'P', 0, 0, 9, 1})
-	return err
-}
-
-func (protocolHeader) channel() uint16 {
-	panic("only valid as initial handshake")
-}
-
-/*
-Method frames carry the high-level protocol commands (which we call "methods").
-One method frame carries one command.  The method frame payload has this format:
-
-  0          2           4
-  +----------+-----------+-------------- - -
-  | class-id | method-id | arguments...
-  +----------+-----------+-------------- - -
-     short      short    ...
-
-To process a method frame, we:
- 1. Read the method frame payload.
- 2. Unpack it into a structure.  A given method always has the same structure,
- so we can unpack the method rapidly.  3. Check that the method is allowed in
- the current context.
- 4. Check that the method arguments are valid.
- 5. Execute the method.
-
-Method frame bodies are constructed as a list of AMQP data fields (bits,
-integers, strings and string tables).  The marshalling code is trivially
-generated directly from the protocol specifications, and can be very rapid.
-*/
-type methodFrame struct {
-	ChannelId uint16
-	ClassId   uint16
-	MethodId  uint16
-	Method    message
-}
-
-func (me *methodFrame) channel() uint16 { return me.ChannelId }
-
-/*
-Heartbeating is a technique designed to undo one of TCP/IP's features, namely
-its ability to recover from a broken physical connection by closing only after
-a quite long time-out.  In some scenarios we need to know very rapidly if a
-peer is disconnected or not responding for other reasons (e.g. it is looping).
-Since heartbeating can be done at a low level, we implement this as a special
-type of frame that peers exchange at the transport level, rather than as a
-class method.
-*/
-type heartbeatFrame struct {
-	ChannelId uint16
-}
-
-func (me *heartbeatFrame) channel() uint16 { return me.ChannelId }
-
-/*
-Certain methods (such as Basic.Publish, Basic.Deliver, etc.) are formally
-defined as carrying content.  When a peer sends such a method frame, it always
-follows it with a content header and zero or more content body frames.
-
-A content header frame has this format:
-
-    0          2        4           12               14
-    +----------+--------+-----------+----------------+------------- - -
-    | class-id | weight | body size | property flags | property list...
-    +----------+--------+-----------+----------------+------------- - -
-      short     short    long long       short        remainder...
-
-We place content body in distinct frames (rather than including it in the
-method) so that AMQP may support "zero copy" techniques in which content is
-never marshalled or encoded.  We place the content properties in their own
-frame so that recipients can selectively discard contents they do not want to
-process
-*/
-type headerFrame struct {
-	ChannelId  uint16
-	ClassId    uint16
-	weight     uint16
-	Size       uint64
-	Properties properties
-}
-
-func (me *headerFrame) channel() uint16 { return me.ChannelId }
-
-/*
-Content is the application data we carry from client-to-client via the AMQP
-server.  Content is, roughly speaking, a set of properties plus a binary data
-part.  The set of allowed properties are defined by the Basic class, and these
-form the "content header frame".  The data can be any size, and MAY be broken
-into several (or many) chunks, each forming a "content body frame".
-
-Looking at the frames for a specific channel, as they pass on the wire, we
-might see something like this:
-
-		[method]
-		[method] [header] [body] [body]
-		[method]
-		...
-*/
-type bodyFrame struct {
-	ChannelId uint16
-	Body      []byte
-}
-
-func (me *bodyFrame) channel() uint16 { return me.ChannelId }

+ 0 - 170
vendor/github.com/streadway/amqp/uri.go

@@ -1,170 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"errors"
-	"fmt"
-	"net/url"
-	"strconv"
-	"strings"
-)
-
-var errURIScheme = errors.New("AMQP scheme must be either 'amqp://' or 'amqps://'")
-
-var schemePorts = map[string]int{
-	"amqp":  5672,
-	"amqps": 5671,
-}
-
-var defaultURI = URI{
-	Scheme:   "amqp",
-	Host:     "localhost",
-	Port:     5672,
-	Username: "guest",
-	Password: "guest",
-	Vhost:    "/",
-}
-
-// URI represents a parsed AMQP URI string.
-type URI struct {
-	Scheme   string
-	Host     string
-	Port     int
-	Username string
-	Password string
-	Vhost    string
-}
-
-// ParseURI attempts to parse the given AMQP URI according to the spec.
-// See http://www.rabbitmq.com/uri-spec.html.
-//
-// Default values for the fields are:
-//
-//   Scheme: amqp
-//   Host: localhost
-//   Port: 5672
-//   Username: guest
-//   Password: guest
-//   Vhost: /
-//
-func ParseURI(uri string) (URI, error) {
-	me := defaultURI
-
-	u, err := url.Parse(uri)
-	if err != nil {
-		return me, err
-	}
-
-	defaultPort, okScheme := schemePorts[u.Scheme]
-
-	if okScheme {
-		me.Scheme = u.Scheme
-	} else {
-		return me, errURIScheme
-	}
-
-	host, port := splitHostPort(u.Host)
-
-	if host != "" {
-		me.Host = host
-	}
-
-	if port != "" {
-		port32, err := strconv.ParseInt(port, 10, 32)
-		if err != nil {
-			return me, err
-		}
-		me.Port = int(port32)
-	} else {
-		me.Port = defaultPort
-	}
-
-	if u.User != nil {
-		me.Username = u.User.Username()
-		if password, ok := u.User.Password(); ok {
-			me.Password = password
-		}
-	}
-
-	if u.Path != "" {
-		if strings.HasPrefix(u.Path, "/") {
-			if u.Host == "" && strings.HasPrefix(u.Path, "///") {
-				// net/url doesn't handle local context authorities and leaves that up
-				// to the scheme handler.  In our case, we translate amqp:/// into the
-				// default host and whatever the vhost should be
-				if len(u.Path) > 3 {
-					me.Vhost = u.Path[3:]
-				}
-			} else if len(u.Path) > 1 {
-				me.Vhost = u.Path[1:]
-			}
-		} else {
-			me.Vhost = u.Path
-		}
-	}
-
-	return me, nil
-}
-
-// Splits host:port, host, [ho:st]:port, or [ho:st].  Unlike net.SplitHostPort
-// which splits :port, host:port or [host]:port
-//
-// Handles hosts that have colons that are in brackets like [::1]:http
-func splitHostPort(addr string) (host, port string) {
-	i := strings.LastIndex(addr, ":")
-
-	if i >= 0 {
-		host, port = addr[:i], addr[i+1:]
-
-		if len(port) > 0 && port[len(port)-1] == ']' && addr[0] == '[' {
-			// we've split on an inner colon, the port was missing outside of the
-			// brackets so use the full addr.  We could assert that host should not
-			// contain any colons here
-			host, port = addr, ""
-		}
-	} else {
-		host = addr
-	}
-
-	return
-}
-
-// PlainAuth returns a PlainAuth structure based on the parsed URI's
-// Username and Password fields.
-func (me URI) PlainAuth() *PlainAuth {
-	return &PlainAuth{
-		Username: me.Username,
-		Password: me.Password,
-	}
-}
-
-func (me URI) String() string {
-	var authority string
-
-	if me.Username != defaultURI.Username || me.Password != defaultURI.Password {
-		authority += me.Username
-
-		if me.Password != defaultURI.Password {
-			authority += ":" + me.Password
-		}
-
-		authority += "@"
-	}
-
-	authority += me.Host
-
-	if defaultPort, found := schemePorts[me.Scheme]; !found || defaultPort != me.Port {
-		authority += ":" + strconv.FormatInt(int64(me.Port), 10)
-	}
-
-	var vhost string
-	if me.Vhost != defaultURI.Vhost {
-		vhost = me.Vhost
-	}
-
-	return fmt.Sprintf("%s://%s/%s", me.Scheme, authority, url.QueryEscape(vhost))
-}

+ 0 - 328
vendor/github.com/streadway/amqp/uri_test.go

@@ -1,328 +0,0 @@
-package amqp
-
-import (
-	"testing"
-)
-
-// Test matrix defined on http://www.rabbitmq.com/uri-spec.html
-type testURI struct {
-	url      string
-	username string
-	password string
-	host     string
-	port     int
-	vhost    string
-	canon    string
-}
-
-var uriTests = []testURI{
-	{
-		url:      "amqp://user:pass@host:10000/vhost",
-		username: "user",
-		password: "pass",
-		host:     "host",
-		port:     10000,
-		vhost:    "vhost",
-		canon:    "amqp://user:pass@host:10000/vhost",
-	},
-
-	// this fails due to net/url not parsing pct-encoding in host
-	// testURI{url: "amqp://user%61:%61pass@ho%61st:10000/v%2Fhost",
-	//	username: "usera",
-	//	password: "apass",
-	//	host:     "hoast",
-	//	port:     10000,
-	//	vhost:    "v/host",
-	// },
-
-	{
-		url:      "amqp://",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     defaultURI.Host,
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://localhost/",
-	},
-
-	{
-		url:      "amqp://:@/",
-		username: "",
-		password: "",
-		host:     defaultURI.Host,
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://:@localhost/",
-	},
-
-	{
-		url:      "amqp://user@",
-		username: "user",
-		password: defaultURI.Password,
-		host:     defaultURI.Host,
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://user@localhost/",
-	},
-
-	{
-		url:      "amqp://user:pass@",
-		username: "user",
-		password: "pass",
-		host:     defaultURI.Host,
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://user:pass@localhost/",
-	},
-
-	{
-		url:      "amqp://guest:pass@",
-		username: "guest",
-		password: "pass",
-		host:     defaultURI.Host,
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://guest:pass@localhost/",
-	},
-
-	{
-		url:      "amqp://host",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "host",
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://host/",
-	},
-
-	{
-		url:      "amqp://:10000",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     defaultURI.Host,
-		port:     10000,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://localhost:10000/",
-	},
-
-	{
-		url:      "amqp:///vhost",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     defaultURI.Host,
-		port:     defaultURI.Port,
-		vhost:    "vhost",
-		canon:    "amqp://localhost/vhost",
-	},
-
-	{
-		url:      "amqp://host/",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "host",
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://host/",
-	},
-
-	{
-		url:      "amqp://host/%2F",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "host",
-		port:     defaultURI.Port,
-		vhost:    "/",
-		canon:    "amqp://host/",
-	},
-
-	{
-		url:      "amqp://host/%2F%2F",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "host",
-		port:     defaultURI.Port,
-		vhost:    "//",
-		canon:    "amqp://host/%2F%2F",
-	},
-
-	{
-		url:      "amqp://host/%2Fslash%2F",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "host",
-		port:     defaultURI.Port,
-		vhost:    "/slash/",
-		canon:    "amqp://host/%2Fslash%2F",
-	},
-
-	{
-		url:      "amqp://192.168.1.1:1000/",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "192.168.1.1",
-		port:     1000,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://192.168.1.1:1000/",
-	},
-
-	{
-		url:      "amqp://[::1]",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "[::1]",
-		port:     defaultURI.Port,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://[::1]/",
-	},
-
-	{
-		url:      "amqp://[::1]:1000",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "[::1]",
-		port:     1000,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqp://[::1]:1000/",
-	},
-
-	{
-		url:      "amqps:///",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     defaultURI.Host,
-		port:     schemePorts["amqps"],
-		vhost:    defaultURI.Vhost,
-		canon:    "amqps://localhost/",
-	},
-
-	{
-		url:      "amqps://host:1000/",
-		username: defaultURI.Username,
-		password: defaultURI.Password,
-		host:     "host",
-		port:     1000,
-		vhost:    defaultURI.Vhost,
-		canon:    "amqps://host:1000/",
-	},
-}
-
-func TestURISpec(t *testing.T) {
-	for _, test := range uriTests {
-		u, err := ParseURI(test.url)
-		if err != nil {
-			t.Fatal("Could not parse spec URI: ", test.url, " err: ", err)
-		}
-
-		if test.username != u.Username {
-			t.Error("For: ", test.url, " usernames do not match. want: ", test.username, " got: ", u.Username)
-		}
-
-		if test.password != u.Password {
-			t.Error("For: ", test.url, " passwords do not match. want: ", test.password, " got: ", u.Password)
-		}
-
-		if test.host != u.Host {
-			t.Error("For: ", test.url, " hosts do not match. want: ", test.host, " got: ", u.Host)
-		}
-
-		if test.port != u.Port {
-			t.Error("For: ", test.url, " ports do not match. want: ", test.port, " got: ", u.Port)
-		}
-
-		if test.vhost != u.Vhost {
-			t.Error("For: ", test.url, " vhosts do not match. want: ", test.vhost, " got: ", u.Vhost)
-		}
-
-		if test.canon != u.String() {
-			t.Error("For: ", test.url, " canonical string does not match. want: ", test.canon, " got: ", u.String())
-		}
-	}
-}
-
-func TestURIUnknownScheme(t *testing.T) {
-	if _, err := ParseURI("http://example.com/"); err == nil {
-		t.Fatal("Expected error when parsing non-amqp scheme")
-	}
-}
-
-func TestURIScheme(t *testing.T) {
-	if _, err := ParseURI("amqp://example.com/"); err != nil {
-		t.Fatalf("Expected to parse amqp scheme, got %v", err)
-	}
-
-	if _, err := ParseURI("amqps://example.com/"); err != nil {
-		t.Fatalf("Expected to parse amqps scheme, got %v", err)
-	}
-}
-
-func TestURIDefaults(t *testing.T) {
-	url := "amqp://"
-	uri, err := ParseURI(url)
-	if err != nil {
-		t.Fatal("Could not parse")
-	}
-
-	if uri.String() != "amqp://localhost/" {
-		t.Fatal("Defaults not encoded properly got:", uri.String())
-	}
-}
-
-func TestURIComplete(t *testing.T) {
-	url := "amqp://bob:dobbs@foo.bar:5678/private"
-	uri, err := ParseURI(url)
-	if err != nil {
-		t.Fatal("Could not parse")
-	}
-
-	if uri.String() != url {
-		t.Fatal("Defaults not encoded properly want:", url, " got:", uri.String())
-	}
-}
-
-func TestURIDefaultPortAmqpNotIncluded(t *testing.T) {
-	url := "amqp://foo.bar:5672/"
-	uri, err := ParseURI(url)
-	if err != nil {
-		t.Fatal("Could not parse")
-	}
-
-	if uri.String() != "amqp://foo.bar/" {
-		t.Fatal("Defaults not encoded properly got:", uri.String())
-	}
-}
-
-func TestURIDefaultPortAmqp(t *testing.T) {
-	url := "amqp://foo.bar/"
-	uri, err := ParseURI(url)
-	if err != nil {
-		t.Fatal("Could not parse")
-	}
-
-	if uri.Port != 5672 {
-		t.Fatal("Default port not correct for amqp, got:", uri.Port)
-	}
-}
-
-func TestURIDefaultPortAmqpsNotIncludedInString(t *testing.T) {
-	url := "amqps://foo.bar:5671/"
-	uri, err := ParseURI(url)
-	if err != nil {
-		t.Fatal("Could not parse")
-	}
-
-	if uri.String() != "amqps://foo.bar/" {
-		t.Fatal("Defaults not encoded properly got:", uri.String())
-	}
-}
-
-func TestURIDefaultPortAmqps(t *testing.T) {
-	url := "amqps://foo.bar/"
-	uri, err := ParseURI(url)
-	if err != nil {
-		t.Fatal("Could not parse")
-	}
-
-	if uri.Port != 5671 {
-		t.Fatal("Default port not correct for amqps, got:", uri.Port)
-	}
-}

+ 0 - 411
vendor/github.com/streadway/amqp/write.go

@@ -1,411 +0,0 @@
-// Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Source code and contact info at http://github.com/streadway/amqp
-
-package amqp
-
-import (
-	"bufio"
-	"bytes"
-	"encoding/binary"
-	"errors"
-	"io"
-	"math"
-	"time"
-)
-
-func (me *writer) WriteFrame(frame frame) (err error) {
-	if err = frame.write(me.w); err != nil {
-		return
-	}
-
-	if buf, ok := me.w.(*bufio.Writer); ok {
-		err = buf.Flush()
-	}
-
-	return
-}
-
-func (me *methodFrame) write(w io.Writer) (err error) {
-	var payload bytes.Buffer
-
-	if me.Method == nil {
-		return errors.New("malformed frame: missing method")
-	}
-
-	class, method := me.Method.id()
-
-	if err = binary.Write(&payload, binary.BigEndian, class); err != nil {
-		return
-	}
-
-	if err = binary.Write(&payload, binary.BigEndian, method); err != nil {
-		return
-	}
-
-	if err = me.Method.write(&payload); err != nil {
-		return
-	}
-
-	return writeFrame(w, frameMethod, me.ChannelId, payload.Bytes())
-}
-
-// Heartbeat
-//
-// Payload is empty
-func (me *heartbeatFrame) write(w io.Writer) (err error) {
-	return writeFrame(w, frameHeartbeat, me.ChannelId, []byte{})
-}
-
-// CONTENT HEADER
-// 0          2        4           12               14
-// +----------+--------+-----------+----------------+------------- - -
-// | class-id | weight | body size | property flags | property list...
-// +----------+--------+-----------+----------------+------------- - -
-//    short     short    long long       short        remainder...
-//
-func (me *headerFrame) write(w io.Writer) (err error) {
-	var payload bytes.Buffer
-	var zeroTime time.Time
-
-	if err = binary.Write(&payload, binary.BigEndian, me.ClassId); err != nil {
-		return
-	}
-
-	if err = binary.Write(&payload, binary.BigEndian, me.weight); err != nil {
-		return
-	}
-
-	if err = binary.Write(&payload, binary.BigEndian, me.Size); err != nil {
-		return
-	}
-
-	// First pass will build the mask to be serialized, second pass will serialize
-	// each of the fields that appear in the mask.
-
-	var mask uint16
-
-	if len(me.Properties.ContentType) > 0 {
-		mask = mask | flagContentType
-	}
-	if len(me.Properties.ContentEncoding) > 0 {
-		mask = mask | flagContentEncoding
-	}
-	if me.Properties.Headers != nil && len(me.Properties.Headers) > 0 {
-		mask = mask | flagHeaders
-	}
-	if me.Properties.DeliveryMode > 0 {
-		mask = mask | flagDeliveryMode
-	}
-	if me.Properties.Priority > 0 {
-		mask = mask | flagPriority
-	}
-	if len(me.Properties.CorrelationId) > 0 {
-		mask = mask | flagCorrelationId
-	}
-	if len(me.Properties.ReplyTo) > 0 {
-		mask = mask | flagReplyTo
-	}
-	if len(me.Properties.Expiration) > 0 {
-		mask = mask | flagExpiration
-	}
-	if len(me.Properties.MessageId) > 0 {
-		mask = mask | flagMessageId
-	}
-	if me.Properties.Timestamp != zeroTime {
-		mask = mask | flagTimestamp
-	}
-	if len(me.Properties.Type) > 0 {
-		mask = mask | flagType
-	}
-	if len(me.Properties.UserId) > 0 {
-		mask = mask | flagUserId
-	}
-	if len(me.Properties.AppId) > 0 {
-		mask = mask | flagAppId
-	}
-
-	if err = binary.Write(&payload, binary.BigEndian, mask); err != nil {
-		return
-	}
-
-	if hasProperty(mask, flagContentType) {
-		if err = writeShortstr(&payload, me.Properties.ContentType); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagContentEncoding) {
-		if err = writeShortstr(&payload, me.Properties.ContentEncoding); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagHeaders) {
-		if err = writeTable(&payload, me.Properties.Headers); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagDeliveryMode) {
-		if err = binary.Write(&payload, binary.BigEndian, me.Properties.DeliveryMode); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagPriority) {
-		if err = binary.Write(&payload, binary.BigEndian, me.Properties.Priority); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagCorrelationId) {
-		if err = writeShortstr(&payload, me.Properties.CorrelationId); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagReplyTo) {
-		if err = writeShortstr(&payload, me.Properties.ReplyTo); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagExpiration) {
-		if err = writeShortstr(&payload, me.Properties.Expiration); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagMessageId) {
-		if err = writeShortstr(&payload, me.Properties.MessageId); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagTimestamp) {
-		if err = binary.Write(&payload, binary.BigEndian, uint64(me.Properties.Timestamp.Unix())); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagType) {
-		if err = writeShortstr(&payload, me.Properties.Type); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagUserId) {
-		if err = writeShortstr(&payload, me.Properties.UserId); err != nil {
-			return
-		}
-	}
-	if hasProperty(mask, flagAppId) {
-		if err = writeShortstr(&payload, me.Properties.AppId); err != nil {
-			return
-		}
-	}
-
-	return writeFrame(w, frameHeader, me.ChannelId, payload.Bytes())
-}
-
-// Body
-//
-// Payload is one byterange from the full body who's size is declared in the
-// Header frame
-func (me *bodyFrame) write(w io.Writer) (err error) {
-	return writeFrame(w, frameBody, me.ChannelId, me.Body)
-}
-
-func writeFrame(w io.Writer, typ uint8, channel uint16, payload []byte) (err error) {
-	end := []byte{frameEnd}
-	size := uint(len(payload))
-
-	_, err = w.Write([]byte{
-		byte(typ),
-		byte((channel & 0xff00) >> 8),
-		byte((channel & 0x00ff) >> 0),
-		byte((size & 0xff000000) >> 24),
-		byte((size & 0x00ff0000) >> 16),
-		byte((size & 0x0000ff00) >> 8),
-		byte((size & 0x000000ff) >> 0),
-	})
-
-	if err != nil {
-		return
-	}
-
-	if _, err = w.Write(payload); err != nil {
-		return
-	}
-
-	if _, err = w.Write(end); err != nil {
-		return
-	}
-
-	return
-}
-
-func writeShortstr(w io.Writer, s string) (err error) {
-	b := []byte(s)
-
-	var length uint8 = uint8(len(b))
-
-	if err = binary.Write(w, binary.BigEndian, length); err != nil {
-		return
-	}
-
-	if _, err = w.Write(b[:length]); err != nil {
-		return
-	}
-
-	return
-}
-
-func writeLongstr(w io.Writer, s string) (err error) {
-	b := []byte(s)
-
-	var length uint32 = uint32(len(b))
-
-	if err = binary.Write(w, binary.BigEndian, length); err != nil {
-		return
-	}
-
-	if _, err = w.Write(b[:length]); err != nil {
-		return
-	}
-
-	return
-}
-
-/*
-'A': []interface{}
-'D': Decimal
-'F': Table
-'I': int32
-'S': string
-'T': time.Time
-'V': nil
-'b': byte
-'d': float64
-'f': float32
-'l': int64
-'s': int16
-'t': bool
-'x': []byte
-*/
-func writeField(w io.Writer, value interface{}) (err error) {
-	var buf [9]byte
-	var enc []byte
-
-	switch v := value.(type) {
-	case bool:
-		buf[0] = 't'
-		if v {
-			buf[1] = byte(1)
-		} else {
-			buf[1] = byte(0)
-		}
-		enc = buf[:2]
-
-	case byte:
-		buf[0] = 'b'
-		buf[1] = byte(v)
-		enc = buf[:2]
-
-	case int16:
-		buf[0] = 's'
-		binary.BigEndian.PutUint16(buf[1:3], uint16(v))
-		enc = buf[:3]
-
-	case int32:
-		buf[0] = 'I'
-		binary.BigEndian.PutUint32(buf[1:5], uint32(v))
-		enc = buf[:5]
-
-	case int64:
-		buf[0] = 'l'
-		binary.BigEndian.PutUint64(buf[1:9], uint64(v))
-		enc = buf[:9]
-
-	case float32:
-		buf[0] = 'f'
-		binary.BigEndian.PutUint32(buf[1:5], math.Float32bits(v))
-		enc = buf[:5]
-
-	case float64:
-		buf[0] = 'd'
-		binary.BigEndian.PutUint64(buf[1:9], math.Float64bits(v))
-		enc = buf[:9]
-
-	case Decimal:
-		buf[0] = 'D'
-		buf[1] = byte(v.Scale)
-		binary.BigEndian.PutUint32(buf[2:6], uint32(v.Value))
-		enc = buf[:6]
-
-	case string:
-		buf[0] = 'S'
-		binary.BigEndian.PutUint32(buf[1:5], uint32(len(v)))
-		enc = append(buf[:5], []byte(v)...)
-
-	case []interface{}: // field-array
-		buf[0] = 'A'
-
-		sec := new(bytes.Buffer)
-		for _, val := range v {
-			if err = writeField(sec, val); err != nil {
-				return
-			}
-		}
-
-		binary.BigEndian.PutUint32(buf[1:5], uint32(sec.Len()))
-		if _, err = w.Write(buf[:5]); err != nil {
-			return
-		}
-
-		if _, err = w.Write(sec.Bytes()); err != nil {
-			return
-		}
-
-		return
-
-	case time.Time:
-		buf[0] = 'T'
-		binary.BigEndian.PutUint64(buf[1:9], uint64(v.Unix()))
-		enc = buf[:9]
-
-	case Table:
-		if _, err = w.Write([]byte{'F'}); err != nil {
-			return
-		}
-		return writeTable(w, v)
-
-	case []byte:
-		buf[0] = 'x'
-		binary.BigEndian.PutUint32(buf[1:5], uint32(len(v)))
-		if _, err = w.Write(buf[0:5]); err != nil {
-			return
-		}
-		if _, err = w.Write(v); err != nil {
-			return
-		}
-		return
-
-	case nil:
-		buf[0] = 'V'
-		enc = buf[:1]
-
-	default:
-		return ErrFieldType
-	}
-
-	_, err = w.Write(enc)
-
-	return
-}
-
-func writeTable(w io.Writer, table Table) (err error) {
-	var buf bytes.Buffer
-
-	for key, val := range table {
-		if err = writeShortstr(&buf, key); err != nil {
-			return
-		}
-		if err = writeField(&buf, val); err != nil {
-			return
-		}
-	}
-
-	return writeLongstr(w, string(buf.Bytes()))
-}