├── .gitignore
├── .travis.yml
├── Dockerfile
├── Godeps
├── Godeps.json
├── Readme
└── _workspace
│ ├── .gitignore
│ └── src
│ ├── git.eclipse.org
│ └── gitroot
│ │ └── paho
│ │ └── org.eclipse.paho.mqtt.golang.git
│ │ ├── .gitignore
│ │ ├── CONTRIBUTING.md
│ │ ├── DISTRIBUTION
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── about.html
│ │ ├── client.go
│ │ ├── components.go
│ │ ├── edl-v10
│ │ ├── epl-v10
│ │ ├── filestore.go
│ │ ├── fvt
│ │ ├── README.md
│ │ ├── mosquitto.cfg
│ │ ├── rsmb.cfg
│ │ └── setup_IMA.sh
│ │ ├── memstore.go
│ │ ├── message.go
│ │ ├── messageids.go
│ │ ├── net.go
│ │ ├── notice.html
│ │ ├── oops.go
│ │ ├── options.go
│ │ ├── packets
│ │ ├── connack.go
│ │ ├── connect.go
│ │ ├── disconnect.go
│ │ ├── packets.go
│ │ ├── pingreq.go
│ │ ├── pingresp.go
│ │ ├── puback.go
│ │ ├── pubcomp.go
│ │ ├── publish.go
│ │ ├── pubrec.go
│ │ ├── pubrel.go
│ │ ├── suback.go
│ │ ├── subscribe.go
│ │ ├── unsuback.go
│ │ └── unsubscribe.go
│ │ ├── ping.go
│ │ ├── router.go
│ │ ├── samples
│ │ ├── build.sh
│ │ ├── custom_store.go
│ │ ├── routing.go
│ │ ├── sample.go
│ │ ├── samplecerts
│ │ │ ├── CAfile.pem
│ │ │ ├── README
│ │ │ ├── client-crt.pem
│ │ │ ├── client-key.pem
│ │ │ ├── intermediateCA-crt.pem
│ │ │ ├── intermediateCA-key.pem
│ │ │ ├── mosquitto.org.crt
│ │ │ ├── rootCA-crt.pem
│ │ │ ├── rootCA-key.pem
│ │ │ ├── server-crt.pem
│ │ │ └── server-key.pem
│ │ ├── simple.go
│ │ ├── ssl.go
│ │ ├── stdinpub.go
│ │ └── stdoutsub.go
│ │ ├── store.go
│ │ ├── token.go
│ │ ├── topic.go
│ │ └── trace.go
│ ├── github.com
│ ├── Sirupsen
│ │ └── logrus
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── CHANGELOG.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── doc.go
│ │ │ ├── entry.go
│ │ │ ├── examples
│ │ │ ├── basic
│ │ │ │ └── basic.go
│ │ │ └── hook
│ │ │ │ └── hook.go
│ │ │ ├── exported.go
│ │ │ ├── formatter.go
│ │ │ ├── formatters
│ │ │ └── logstash
│ │ │ │ └── logstash.go
│ │ │ ├── hooks.go
│ │ │ ├── hooks
│ │ │ └── syslog
│ │ │ │ ├── README.md
│ │ │ │ └── syslog.go
│ │ │ ├── json_formatter.go
│ │ │ ├── logger.go
│ │ │ ├── logrus.go
│ │ │ ├── terminal_bsd.go
│ │ │ ├── terminal_linux.go
│ │ │ ├── terminal_notwindows.go
│ │ │ ├── terminal_solaris.go
│ │ │ ├── terminal_windows.go
│ │ │ ├── text_formatter.go
│ │ │ └── writer.go
│ ├── codegangsta
│ │ └── inject
│ │ │ ├── .gitignore
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── inject.go
│ │ │ ├── translations
│ │ │ └── README_zh_cn.md
│ │ │ └── update_readme.sh
│ ├── coreos
│ │ └── etcd
│ │ │ ├── client
│ │ │ ├── README.md
│ │ │ ├── auth_role.go
│ │ │ ├── auth_user.go
│ │ │ ├── cancelreq.go
│ │ │ ├── client.go
│ │ │ ├── cluster_error.go
│ │ │ ├── curl.go
│ │ │ ├── discover.go
│ │ │ ├── doc.go
│ │ │ ├── keys.generated.go
│ │ │ ├── keys.go
│ │ │ ├── members.go
│ │ │ ├── srv.go
│ │ │ └── util.go
│ │ │ └── pkg
│ │ │ ├── pathutil
│ │ │ └── path.go
│ │ │ └── types
│ │ │ ├── doc.go
│ │ │ ├── id.go
│ │ │ ├── set.go
│ │ │ ├── slice.go
│ │ │ ├── urls.go
│ │ │ └── urlsmap.go
│ ├── garyburd
│ │ └── redigo
│ │ │ ├── internal
│ │ │ ├── commandinfo.go
│ │ │ └── redistest
│ │ │ │ └── testdb.go
│ │ │ └── redis
│ │ │ ├── conn.go
│ │ │ ├── doc.go
│ │ │ ├── log.go
│ │ │ ├── pool.go
│ │ │ ├── pubsub.go
│ │ │ ├── redis.go
│ │ │ ├── reply.go
│ │ │ ├── scan.go
│ │ │ └── script.go
│ ├── go-martini
│ │ └── martini
│ │ │ ├── .gitignore
│ │ │ ├── Godeps
│ │ │ └── Godeps.json
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── env.go
│ │ │ ├── go_version.go
│ │ │ ├── logger.go
│ │ │ ├── martini.go
│ │ │ ├── recovery.go
│ │ │ ├── response_writer.go
│ │ │ ├── return_handler.go
│ │ │ ├── router.go
│ │ │ ├── static.go
│ │ │ ├── translations
│ │ │ ├── README_de_DE.md
│ │ │ ├── README_es_ES.md
│ │ │ ├── README_fr_FR.md
│ │ │ ├── README_ja_JP.md
│ │ │ ├── README_ko_kr.md
│ │ │ ├── README_pl_PL.md
│ │ │ ├── README_pt_br.md
│ │ │ ├── README_ru_RU.md
│ │ │ ├── README_tr_TR.md
│ │ │ ├── README_zh_cn.md
│ │ │ └── README_zh_tw.md
│ │ │ └── wercker.yml
│ ├── go-sql-driver
│ │ └── mysql
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── AUTHORS
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── appengine.go
│ │ │ ├── buffer.go
│ │ │ ├── collations.go
│ │ │ ├── connection.go
│ │ │ ├── const.go
│ │ │ ├── driver.go
│ │ │ ├── errors.go
│ │ │ ├── infile.go
│ │ │ ├── packets.go
│ │ │ ├── result.go
│ │ │ ├── rows.go
│ │ │ ├── statement.go
│ │ │ ├── transaction.go
│ │ │ └── utils.go
│ ├── jinzhu
│ │ ├── gorm
│ │ │ ├── .codeclimate.yml
│ │ │ ├── .gitignore
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── License
│ │ │ ├── README.md
│ │ │ ├── association.go
│ │ │ ├── callback.go
│ │ │ ├── callback_create.go
│ │ │ ├── callback_delete.go
│ │ │ ├── callback_query.go
│ │ │ ├── callback_query_preload.go
│ │ │ ├── callback_save.go
│ │ │ ├── callback_update.go
│ │ │ ├── dialect.go
│ │ │ ├── dialect_common.go
│ │ │ ├── dialect_mysql.go
│ │ │ ├── dialect_postgres.go
│ │ │ ├── dialect_sqlite3.go
│ │ │ ├── dialects
│ │ │ │ ├── mssql
│ │ │ │ │ └── mssql.go
│ │ │ │ ├── mysql
│ │ │ │ │ └── mysql.go
│ │ │ │ ├── postgres
│ │ │ │ │ └── postgres.go
│ │ │ │ └── sqlite
│ │ │ │ │ └── sqlite.go
│ │ │ ├── errors.go
│ │ │ ├── field.go
│ │ │ ├── interface.go
│ │ │ ├── join_table_handler.go
│ │ │ ├── logger.go
│ │ │ ├── main.go
│ │ │ ├── model.go
│ │ │ ├── model_struct.go
│ │ │ ├── scope.go
│ │ │ ├── search.go
│ │ │ ├── test_all.sh
│ │ │ └── utils.go
│ │ └── inflection
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ └── inflections.go
│ ├── martini-contrib
│ │ ├── binding
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── binding.go
│ │ │ ├── errors.go
│ │ │ └── wercker.yml
│ │ └── render
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── fixtures
│ │ │ ├── basic
│ │ │ │ ├── admin
│ │ │ │ │ └── index.tmpl
│ │ │ │ ├── another_layout.tmpl
│ │ │ │ ├── content.tmpl
│ │ │ │ ├── current_layout.tmpl
│ │ │ │ ├── delims.tmpl
│ │ │ │ ├── hello.tmpl
│ │ │ │ ├── hypertext.html
│ │ │ │ └── layout.tmpl
│ │ │ └── custom_funcs
│ │ │ │ └── index.tmpl
│ │ │ ├── render.go
│ │ │ └── wercker.yml
│ ├── oxtoacart
│ │ └── bpool
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── bpool.go
│ │ │ ├── bufferpool.go
│ │ │ ├── bytepool.go
│ │ │ └── sizedbufferpool.go
│ ├── pborman
│ │ └── uuid
│ │ │ ├── CONTRIBUTORS
│ │ │ ├── LICENSE
│ │ │ ├── dce.go
│ │ │ ├── doc.go
│ │ │ ├── hash.go
│ │ │ ├── json.go
│ │ │ ├── node.go
│ │ │ ├── sql.go
│ │ │ ├── time.go
│ │ │ ├── util.go
│ │ │ ├── uuid.go
│ │ │ ├── version1.go
│ │ │ └── version4.go
│ ├── robfig
│ │ └── cron
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── constantdelay.go
│ │ │ ├── cron.go
│ │ │ ├── doc.go
│ │ │ ├── parser.go
│ │ │ └── spec.go
│ ├── streadway
│ │ └── amqp
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── allocator.go
│ │ │ ├── auth.go
│ │ │ ├── certs.sh
│ │ │ ├── channel.go
│ │ │ ├── confirms.go
│ │ │ ├── connection.go
│ │ │ ├── consumers.go
│ │ │ ├── delivery.go
│ │ │ ├── doc.go
│ │ │ ├── fuzz.go
│ │ │ ├── gen.sh
│ │ │ ├── read.go
│ │ │ ├── return.go
│ │ │ ├── spec
│ │ │ ├── amqp0-9-1.stripped.extended.xml
│ │ │ └── gen.go
│ │ │ ├── spec091.go
│ │ │ ├── types.go
│ │ │ ├── uri.go
│ │ │ └── write.go
│ └── ugorji
│ │ └── go
│ │ └── codec
│ │ ├── 0doc.go
│ │ ├── README.md
│ │ ├── binc.go
│ │ ├── cbor.go
│ │ ├── codecgen
│ │ ├── README.md
│ │ ├── gen.go
│ │ └── z.go
│ │ ├── decode.go
│ │ ├── encode.go
│ │ ├── fast-path.generated.go
│ │ ├── fast-path.go.tmpl
│ │ ├── fast-path.not.go
│ │ ├── gen-dec-array.go.tmpl
│ │ ├── gen-dec-map.go.tmpl
│ │ ├── gen-helper.generated.go
│ │ ├── gen-helper.go.tmpl
│ │ ├── gen.generated.go
│ │ ├── gen.go
│ │ ├── helper.go
│ │ ├── helper_internal.go
│ │ ├── helper_not_unsafe.go
│ │ ├── helper_unsafe.go
│ │ ├── json.go
│ │ ├── msgpack.go
│ │ ├── noop.go
│ │ ├── prebuild.go
│ │ ├── prebuild.sh
│ │ ├── rpc.go
│ │ ├── simple.go
│ │ ├── test-cbor-goldens.json
│ │ ├── test.py
│ │ ├── tests.sh
│ │ └── time.go
│ ├── golang.org
│ └── x
│ │ └── net
│ │ ├── context
│ │ ├── context.go
│ │ └── ctxhttp
│ │ │ ├── cancelreq.go
│ │ │ ├── cancelreq_go14.go
│ │ │ └── ctxhttp.go
│ │ └── websocket
│ │ ├── client.go
│ │ ├── hybi.go
│ │ ├── server.go
│ │ └── websocket.go
│ └── labix.org
│ └── v2
│ └── mgo
│ ├── .bzrignore
│ ├── LICENSE
│ ├── Makefile
│ ├── auth.go
│ ├── bson
│ ├── LICENSE
│ ├── bson.go
│ ├── decode.go
│ └── encode.go
│ ├── cluster.go
│ ├── doc.go
│ ├── gridfs.go
│ ├── log.go
│ ├── queue.go
│ ├── sasl
│ ├── sasl.c
│ └── sasl.go
│ ├── saslimpl.go
│ ├── saslstub.go
│ ├── server.go
│ ├── session.go
│ ├── socket.go
│ ├── stats.go
│ ├── testdb
│ ├── dropall.js
│ ├── init.js
│ ├── setup.sh
│ ├── supervisord.conf
│ └── wait.js
│ └── txn
│ ├── chaos.go
│ ├── debug.go
│ ├── flusher.go
│ ├── tarjan.go
│ └── txn.go
├── LICENSE
├── README.md
├── build
└── local
│ ├── docker
│ ├── base.sh
│ └── run.sh
│ └── linux
│ ├── install.sh
│ └── run.sh
├── docs
├── en
│ └── README.md
├── img
│ └── architecture.jpeg
└── zh-cn
│ ├── api-doc
│ ├── application.md
│ └── device.md
│ ├── config
│ └── product-json-config.md
│ ├── contribution
│ ├── coding-standard.md
│ └── work-flow.md
│ ├── environment
│ └── golang.md
│ ├── quick-start
│ ├── README.md
│ ├── docker.md
│ └── ubuntu.md
│ ├── services
│ ├── README.md
│ ├── apiprovider.md
│ ├── controller.md
│ ├── devicemanager.md
│ ├── httpaccess.md
│ ├── mqttaccess.md
│ └── registry.md
│ └── tools
│ └── pdcfg.md
├── make_deps.sh
├── pkg
├── README.md
├── cache
│ ├── cache.go
│ ├── memcache.go
│ └── memcache_test.go
├── generator
│ ├── key_gen.go
│ ├── key_gen_test.go
│ ├── password_gen.go
│ ├── password_gen_test.go
│ ├── token_gen.go
│ └── token_gen_test.go
├── models
│ ├── application.go
│ ├── device.go
│ ├── product.go
│ ├── rule.go
│ └── vendor.go
├── mongo
│ ├── recorder.go
│ └── recorder_test.go
├── mqtt
│ ├── broker.go
│ ├── connection.go
│ ├── manager.go
│ ├── message.go
│ ├── payload.go
│ ├── provider.go
│ └── utils.go
├── mysql
│ ├── client.go
│ ├── migrate.go
│ └── migrate_test.go
├── online
│ ├── online.go
│ └── online_test.go
├── productconfig
│ ├── productconfig.go
│ └── productconfig_test.go
├── protocol
│ ├── protocol.go
│ ├── protocol_test.go
│ └── structure.go
├── queue
│ ├── queque_test.go
│ └── queue.go
├── redispool
│ ├── redispool.go
│ └── redispool_test.go
├── rpcs
│ ├── access.go
│ ├── common.go
│ ├── controller.go
│ ├── devicemanager.go
│ └── registry.go
├── rule
│ ├── ifttt.go
│ ├── rule_action.go
│ └── timer.go
├── serializer
│ ├── serializer.go
│ └── serializer_test.go
├── server
│ ├── README.md
│ ├── config.go
│ ├── errors.go
│ ├── http_server.go
│ ├── http_server_test.go
│ ├── log.go
│ ├── log_test.go
│ ├── netif.go
│ ├── netif_test.go
│ ├── rpc_client.go
│ ├── rpc_client_test.go
│ ├── rpc_server.go
│ ├── rpc_server_test.go
│ ├── server.go
│ ├── server_manager.go
│ ├── server_test.go
│ ├── tcp_server.go
│ ├── tcp_server_test.go
│ ├── testdata
│ │ ├── cert.pem
│ │ └── key.pem
│ ├── timer_task.go
│ ├── utils.go
│ └── utils_test.go
├── tlv
│ ├── tlv.go
│ └── tlv_test.go
├── token
│ ├── token.go
│ └── token_test.go
└── utils
│ ├── http.go
│ └── http_test.go
├── services
├── README.md
├── apiprovider
│ ├── actions.go
│ ├── flags.go
│ ├── main.go
│ ├── middleware.go
│ ├── middleware_test.go
│ ├── notifier.go
│ ├── request.go
│ ├── response.go
│ └── router.go
├── controller
│ ├── controller.go
│ ├── flags.go
│ └── main.go
├── devicemanager
│ ├── flags.go
│ ├── main.go
│ ├── manager.go
│ └── manager_test.go
├── httpaccess
│ ├── actions.go
│ ├── flags.go
│ ├── main.go
│ ├── response.go
│ └── router.go
├── mqttaccess
│ ├── access.go
│ ├── main.go
│ ├── mqtt_provider.go
│ └── status.go
└── registry
│ ├── cache.go
│ ├── db.go
│ ├── db_test.go
│ ├── main.go
│ ├── registry.go
│ ├── registry_test.go
│ ├── utils.go
│ └── utils_test.go
├── tests
└── device
│ ├── device.go
│ ├── main.go
│ └── utils.go
├── tools
└── pdcfg
│ ├── README.md
│ ├── application.go
│ ├── command_handlers.go
│ ├── main.go
│ ├── product.go
│ ├── utils.go
│ ├── utils_test.go
│ └── vendor.go
└── unit_test.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 | *.project
6 |
7 | # Folders
8 | _obj
9 | _test
10 |
11 | # Architecture specific extensions/prefixes
12 | *.[568vq]
13 | [568vq].out
14 |
15 | *.cgo1.go
16 | *.cgo2.c
17 | _cgo_defun.c
18 | _cgo_gotypes.go
19 | _cgo_export.*
20 |
21 | _testmain.go
22 |
23 | *.exe
24 | *.test
25 | *.prof
26 | *.out
27 |
28 | # ctag files
29 | .tags*
30 |
31 | # Test data output folder
32 | testoutput
33 |
34 | # coverage
35 | *.coverprofile
36 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | go:
3 | - 1.5
4 | services:
5 | - redis-server
6 | - mongodb
7 | - rabbitmq
8 | before_install:
9 | - go get github.com/modocache/gover
10 | - go get github.com/mattn/goveralls
11 | - curl -L https://github.com/coreos/etcd/releases/download/v2.3.1/etcd-v2.3.1-linux-amd64.tar.gz -o etcd-v2.3.1-linux-amd64.tar.gz
12 | - tar xzvf etcd-v2.3.1-linux-amd64.tar.gz
13 | - cp etcd-v2.3.1-linux-amd64/etcd $HOME/gopath/bin
14 | install:
15 | - go get ./...
16 | before_script:
17 | - $HOME/gopath/bin/etcd &
18 | - echo 'CREATE DATABASE PandoCloud' | mysql -uroot
19 | script:
20 | - cd $HOME/gopath/src/github.com/PandoCloud/pando-cloud/
21 | - ./unit_test.sh
22 | - $HOME/gopath/bin/goveralls -coverprofile=gover.coverprofile -service=travis-ci
23 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.5.2
2 |
3 | MAINTAINER razr razr.china@gmail.com
4 |
5 | ADD . /go/src/github.com/PandoCloud/pando-cloud
6 |
7 | RUN go get github.com/PandoCloud/pando-cloud/...
--------------------------------------------------------------------------------
/Godeps/Readme:
--------------------------------------------------------------------------------
1 | This directory tree is generated automatically by godep.
2 |
3 | Please do not edit.
4 |
5 | See https://github.com/tools/godep for more information.
6 |
--------------------------------------------------------------------------------
/Godeps/_workspace/.gitignore:
--------------------------------------------------------------------------------
1 | /pkg
2 | /bin
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 |
24 | *.msg
25 | *.lok
26 |
27 | samples/trivial
28 | samples/trivial2
29 | samples/sample
30 | samples/reconnect
31 | samples/ssl
32 | samples/custom_store
33 | samples/simple
34 | samples/stdinpub
35 | samples/stdoutsub
36 | samples/routing
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/DISTRIBUTION:
--------------------------------------------------------------------------------
1 |
2 |
3 | Eclipse Distribution License - v 1.0
4 |
5 | Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
6 |
7 | All rights reserved.
8 |
9 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
10 |
11 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
12 | 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.
13 | Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
14 |
15 | 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 OWNER 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.
16 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/components.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/epl-v10.html
8 | *
9 | * Contributors:
10 | * Seth Hoenig
11 | * Allan Stockdill-Mander
12 | * Mike Robertson
13 | */
14 |
15 | package mqtt
16 |
17 | type component string
18 |
19 | // Component names for debug output
20 | const (
21 | NET component = "[net] "
22 | PNG component = "[pinger] "
23 | CLI component = "[client] "
24 | DEC component = "[decode] "
25 | MES component = "[message] "
26 | STR component = "[store] "
27 | MID component = "[msgids] "
28 | TST component = "[test] "
29 | STA component = "[state] "
30 | ERR component = "[error] "
31 | )
32 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/edl-v10:
--------------------------------------------------------------------------------
1 |
2 | Eclipse Distribution License - v 1.0
3 |
4 | Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
5 |
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
9 |
10 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
11 | 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.
12 | Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
13 |
14 | 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 OWNER 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.
15 |
16 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/fvt/mosquitto.cfg:
--------------------------------------------------------------------------------
1 | allow_anonymous true
2 | allow_duplicate_messages false
3 | connection_messages true
4 | log_dest stdout
5 | log_timestamp true
6 | log_type all
7 | persistence false
8 | bind_address 127.0.0.1
9 |
10 | listener 17001
11 | listener 17002
12 | listener 17003
13 | listener 17004
14 |
15 | #capath ../samples/samplecerts
16 | #certfile ../samples/samplecerts/server-crt.pem
17 | #keyfile ../samples/samplecerts/server-key.pem
18 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/fvt/rsmb.cfg:
--------------------------------------------------------------------------------
1 | allow_anonymous false
2 | bind_address 127.0.0.1
3 | connection_messages true
4 | log_level detail
5 |
6 | listener 17001
7 | #listener 17003
8 | #listener 17004
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/messageids.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/epl-v10.html
8 | *
9 | * Contributors:
10 | * Seth Hoenig
11 | * Allan Stockdill-Mander
12 | * Mike Robertson
13 | */
14 |
15 | package mqtt
16 |
17 | import (
18 | "sync"
19 | )
20 |
21 | // MId is 16 bit message id as specified by the MQTT spec.
22 | // In general, these values should not be depended upon by
23 | // the client application.
24 | type MId uint16
25 |
26 | type messageIds struct {
27 | sync.RWMutex
28 | index map[uint16]Token
29 | }
30 |
31 | const (
32 | midMin uint16 = 1
33 | midMax uint16 = 65535
34 | )
35 |
36 | func (mids *messageIds) freeID(id uint16) {
37 | mids.Lock()
38 | defer mids.Unlock()
39 | delete(mids.index, id)
40 | }
41 |
42 | func (mids *messageIds) getID(t Token) uint16 {
43 | mids.Lock()
44 | defer mids.Unlock()
45 | for i := midMin; i < midMax; i++ {
46 | if _, ok := mids.index[i]; !ok {
47 | mids.index[i] = t
48 | return i
49 | }
50 | }
51 | return 0
52 | }
53 |
54 | func (mids *messageIds) getToken(id uint16) Token {
55 | mids.RLock()
56 | defer mids.RUnlock()
57 | if token, ok := mids.index[id]; ok {
58 | return token
59 | }
60 | return nil
61 | }
62 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/oops.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/epl-v10.html
8 | *
9 | * Contributors:
10 | * Seth Hoenig
11 | * Allan Stockdill-Mander
12 | * Mike Robertson
13 | */
14 |
15 | package mqtt
16 |
17 | func chkerr(e error) {
18 | if e != nil {
19 | panic(e)
20 | }
21 | }
22 |
23 | func chkcond(b bool) {
24 | if !b {
25 | panic("oops")
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/connack.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "github.com/pborman/uuid"
7 | "io"
8 | )
9 |
10 | //ConnackPacket is an internal representation of the fields of the
11 | //Connack MQTT packet
12 | type ConnackPacket struct {
13 | FixedHeader
14 | TopicNameCompression byte
15 | ReturnCode byte
16 | uuid uuid.UUID
17 | }
18 |
19 | func (ca *ConnackPacket) String() string {
20 | str := fmt.Sprintf("%s\n", ca.FixedHeader)
21 | str += fmt.Sprintf("returncode: %d", ca.ReturnCode)
22 | return str
23 | }
24 |
25 | func (ca *ConnackPacket) Write(w io.Writer) error {
26 | var body bytes.Buffer
27 | var err error
28 |
29 | body.WriteByte(ca.TopicNameCompression)
30 | body.WriteByte(ca.ReturnCode)
31 | ca.FixedHeader.RemainingLength = 2
32 | packet := ca.FixedHeader.pack()
33 | packet.Write(body.Bytes())
34 | _, err = packet.WriteTo(w)
35 |
36 | return err
37 | }
38 |
39 | //Unpack decodes the details of a ControlPacket after the fixed
40 | //header has been read
41 | func (ca *ConnackPacket) Unpack(b io.Reader) {
42 | ca.TopicNameCompression = decodeByte(b)
43 | ca.ReturnCode = decodeByte(b)
44 | }
45 |
46 | //Details returns a Details struct containing the Qos and
47 | //MessageID of this ControlPacket
48 | func (ca *ConnackPacket) Details() Details {
49 | return Details{Qos: 0, MessageID: 0}
50 | }
51 |
52 | //UUID returns the unique ID assigned to the ControlPacket when
53 | //it was originally received. Note: this is not related to the
54 | //MessageID field for MQTT packets
55 | func (ca *ConnackPacket) UUID() uuid.UUID {
56 | return ca.uuid
57 | }
58 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/disconnect.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //DisconnectPacket is an internal representation of the fields of the
10 | //Disconnect MQTT packet
11 | type DisconnectPacket struct {
12 | FixedHeader
13 | uuid uuid.UUID
14 | }
15 |
16 | func (d *DisconnectPacket) String() string {
17 | str := fmt.Sprintf("%s\n", d.FixedHeader)
18 | return str
19 | }
20 |
21 | func (d *DisconnectPacket) Write(w io.Writer) error {
22 | packet := d.FixedHeader.pack()
23 | _, err := packet.WriteTo(w)
24 |
25 | return err
26 | }
27 |
28 | //Unpack decodes the details of a ControlPacket after the fixed
29 | //header has been read
30 | func (d *DisconnectPacket) Unpack(b io.Reader) {
31 | }
32 |
33 | //Details returns a Details struct containing the Qos and
34 | //MessageID of this ControlPacket
35 | func (d *DisconnectPacket) Details() Details {
36 | return Details{Qos: 0, MessageID: 0}
37 | }
38 |
39 | //UUID returns the unique ID assigned to the ControlPacket when
40 | //it was originally received. Note: this is not related to the
41 | //MessageID field for MQTT packets
42 | func (d *DisconnectPacket) UUID() uuid.UUID {
43 | return d.uuid
44 | }
45 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/pingreq.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //PingreqPacket is an internal representation of the fields of the
10 | //Pingreq MQTT packet
11 | type PingreqPacket struct {
12 | FixedHeader
13 | uuid uuid.UUID
14 | }
15 |
16 | func (pr *PingreqPacket) String() string {
17 | str := fmt.Sprintf("%s", pr.FixedHeader)
18 | return str
19 | }
20 |
21 | func (pr *PingreqPacket) Write(w io.Writer) error {
22 | packet := pr.FixedHeader.pack()
23 | _, err := packet.WriteTo(w)
24 |
25 | return err
26 | }
27 |
28 | //Unpack decodes the details of a ControlPacket after the fixed
29 | //header has been read
30 | func (pr *PingreqPacket) Unpack(b io.Reader) {
31 | }
32 |
33 | //Details returns a Details struct containing the Qos and
34 | //MessageID of this ControlPacket
35 | func (pr *PingreqPacket) Details() Details {
36 | return Details{Qos: 0, MessageID: 0}
37 | }
38 |
39 | //UUID returns the unique ID assigned to the ControlPacket when
40 | //it was originally received. Note: this is not related to the
41 | //MessageID field for MQTT packets
42 | func (pr *PingreqPacket) UUID() uuid.UUID {
43 | return pr.uuid
44 | }
45 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/pingresp.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //PingrespPacket is an internal representation of the fields of the
10 | //Pingresp MQTT packet
11 | type PingrespPacket struct {
12 | FixedHeader
13 | uuid uuid.UUID
14 | }
15 |
16 | func (pr *PingrespPacket) String() string {
17 | str := fmt.Sprintf("%s", pr.FixedHeader)
18 | return str
19 | }
20 |
21 | func (pr *PingrespPacket) Write(w io.Writer) error {
22 | packet := pr.FixedHeader.pack()
23 | _, err := packet.WriteTo(w)
24 |
25 | return err
26 | }
27 |
28 | //Unpack decodes the details of a ControlPacket after the fixed
29 | //header has been read
30 | func (pr *PingrespPacket) Unpack(b io.Reader) {
31 | }
32 |
33 | //Details returns a Details struct containing the Qos and
34 | //MessageID of this ControlPacket
35 | func (pr *PingrespPacket) Details() Details {
36 | return Details{Qos: 0, MessageID: 0}
37 | }
38 |
39 | //UUID returns the unique ID assigned to the ControlPacket when
40 | //it was originally received. Note: this is not related to the
41 | //MessageID field for MQTT packets
42 | func (pr *PingrespPacket) UUID() uuid.UUID {
43 | return pr.uuid
44 | }
45 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/puback.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //PubackPacket is an internal representation of the fields of the
10 | //Puback MQTT packet
11 | type PubackPacket struct {
12 | FixedHeader
13 | MessageID uint16
14 | uuid uuid.UUID
15 | }
16 |
17 | func (pa *PubackPacket) String() string {
18 | str := fmt.Sprintf("%s\n", pa.FixedHeader)
19 | str += fmt.Sprintf("messageID: %d", pa.MessageID)
20 | return str
21 | }
22 |
23 | func (pa *PubackPacket) Write(w io.Writer) error {
24 | var err error
25 | pa.FixedHeader.RemainingLength = 2
26 | packet := pa.FixedHeader.pack()
27 | packet.Write(encodeUint16(pa.MessageID))
28 | _, err = packet.WriteTo(w)
29 |
30 | return err
31 | }
32 |
33 | //Unpack decodes the details of a ControlPacket after the fixed
34 | //header has been read
35 | func (pa *PubackPacket) Unpack(b io.Reader) {
36 | pa.MessageID = decodeUint16(b)
37 | }
38 |
39 | //Details returns a Details struct containing the Qos and
40 | //MessageID of this ControlPacket
41 | func (pa *PubackPacket) Details() Details {
42 | return Details{Qos: pa.Qos, MessageID: pa.MessageID}
43 | }
44 |
45 | //UUID returns the unique ID assigned to the ControlPacket when
46 | //it was originally received. Note: this is not related to the
47 | //MessageID field for MQTT packets
48 | func (pa *PubackPacket) UUID() uuid.UUID {
49 | return pa.uuid
50 | }
51 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/pubcomp.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //PubcompPacket is an internal representation of the fields of the
10 | //Pubcomp MQTT packet
11 | type PubcompPacket struct {
12 | FixedHeader
13 | MessageID uint16
14 | uuid uuid.UUID
15 | }
16 |
17 | func (pc *PubcompPacket) String() string {
18 | str := fmt.Sprintf("%s\n", pc.FixedHeader)
19 | str += fmt.Sprintf("MessageID: %d", pc.MessageID)
20 | return str
21 | }
22 |
23 | func (pc *PubcompPacket) Write(w io.Writer) error {
24 | var err error
25 | pc.FixedHeader.RemainingLength = 2
26 | packet := pc.FixedHeader.pack()
27 | packet.Write(encodeUint16(pc.MessageID))
28 | _, err = packet.WriteTo(w)
29 |
30 | return err
31 | }
32 |
33 | //Unpack decodes the details of a ControlPacket after the fixed
34 | //header has been read
35 | func (pc *PubcompPacket) Unpack(b io.Reader) {
36 | pc.MessageID = decodeUint16(b)
37 | }
38 |
39 | //Details returns a Details struct containing the Qos and
40 | //MessageID of this ControlPacket
41 | func (pc *PubcompPacket) Details() Details {
42 | return Details{Qos: pc.Qos, MessageID: pc.MessageID}
43 | }
44 |
45 | //UUID returns the unique ID assigned to the ControlPacket when
46 | //it was originally received. Note: this is not related to the
47 | //MessageID field for MQTT packets
48 | func (pc *PubcompPacket) UUID() uuid.UUID {
49 | return pc.uuid
50 | }
51 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/pubrec.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //PubrecPacket is an internal representation of the fields of the
10 | //Pubrec MQTT packet
11 | type PubrecPacket struct {
12 | FixedHeader
13 | MessageID uint16
14 | uuid uuid.UUID
15 | }
16 |
17 | func (pr *PubrecPacket) String() string {
18 | str := fmt.Sprintf("%s\n", pr.FixedHeader)
19 | str += fmt.Sprintf("MessageID: %d", pr.MessageID)
20 | return str
21 | }
22 |
23 | func (pr *PubrecPacket) Write(w io.Writer) error {
24 | var err error
25 | pr.FixedHeader.RemainingLength = 2
26 | packet := pr.FixedHeader.pack()
27 | packet.Write(encodeUint16(pr.MessageID))
28 | _, err = packet.WriteTo(w)
29 |
30 | return err
31 | }
32 |
33 | //Unpack decodes the details of a ControlPacket after the fixed
34 | //header has been read
35 | func (pr *PubrecPacket) Unpack(b io.Reader) {
36 | pr.MessageID = decodeUint16(b)
37 | }
38 |
39 | //Details returns a Details struct containing the Qos and
40 | //MessageID of this ControlPacket
41 | func (pr *PubrecPacket) Details() Details {
42 | return Details{Qos: pr.Qos, MessageID: pr.MessageID}
43 | }
44 |
45 | //UUID returns the unique ID assigned to the ControlPacket when
46 | //it was originally received. Note: this is not related to the
47 | //MessageID field for MQTT packets
48 | func (pr *PubrecPacket) UUID() uuid.UUID {
49 | return pr.uuid
50 | }
51 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/pubrel.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //PubrelPacket is an internal representation of the fields of the
10 | //Pubrel MQTT packet
11 | type PubrelPacket struct {
12 | FixedHeader
13 | MessageID uint16
14 | uuid uuid.UUID
15 | }
16 |
17 | func (pr *PubrelPacket) String() string {
18 | str := fmt.Sprintf("%s\n", pr.FixedHeader)
19 | str += fmt.Sprintf("MessageID: %d", pr.MessageID)
20 | return str
21 | }
22 |
23 | func (pr *PubrelPacket) Write(w io.Writer) error {
24 | var err error
25 | pr.FixedHeader.RemainingLength = 2
26 | packet := pr.FixedHeader.pack()
27 | packet.Write(encodeUint16(pr.MessageID))
28 | _, err = packet.WriteTo(w)
29 |
30 | return err
31 | }
32 |
33 | //Unpack decodes the details of a ControlPacket after the fixed
34 | //header has been read
35 | func (pr *PubrelPacket) Unpack(b io.Reader) {
36 | pr.MessageID = decodeUint16(b)
37 | }
38 |
39 | //Details returns a Details struct containing the Qos and
40 | //MessageID of this ControlPacket
41 | func (pr *PubrelPacket) Details() Details {
42 | return Details{Qos: pr.Qos, MessageID: pr.MessageID}
43 | }
44 |
45 | //UUID returns the unique ID assigned to the ControlPacket when
46 | //it was originally received. Note: this is not related to the
47 | //MessageID field for MQTT packets
48 | func (pr *PubrelPacket) UUID() uuid.UUID {
49 | return pr.uuid
50 | }
51 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/suback.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "github.com/pborman/uuid"
7 | "io"
8 | )
9 |
10 | //SubackPacket is an internal representation of the fields of the
11 | //Suback MQTT packet
12 | type SubackPacket struct {
13 | FixedHeader
14 | MessageID uint16
15 | GrantedQoss []byte
16 | uuid uuid.UUID
17 | }
18 |
19 | func (sa *SubackPacket) String() string {
20 | str := fmt.Sprintf("%s\n", sa.FixedHeader)
21 | str += fmt.Sprintf("MessageID: %d", sa.MessageID)
22 | return str
23 | }
24 |
25 | func (sa *SubackPacket) Write(w io.Writer) error {
26 | var body bytes.Buffer
27 | var err error
28 | body.Write(encodeUint16(sa.MessageID))
29 | body.Write(sa.GrantedQoss)
30 | sa.FixedHeader.RemainingLength = body.Len()
31 | packet := sa.FixedHeader.pack()
32 | packet.Write(body.Bytes())
33 | _, err = packet.WriteTo(w)
34 |
35 | return err
36 | }
37 |
38 | //Unpack decodes the details of a ControlPacket after the fixed
39 | //header has been read
40 | func (sa *SubackPacket) Unpack(b io.Reader) {
41 | var qosBuffer bytes.Buffer
42 | sa.MessageID = decodeUint16(b)
43 | qosBuffer.ReadFrom(b)
44 | sa.GrantedQoss = qosBuffer.Bytes()
45 | }
46 |
47 | //Details returns a Details struct containing the Qos and
48 | //MessageID of this ControlPacket
49 | func (sa *SubackPacket) Details() Details {
50 | return Details{Qos: 0, MessageID: sa.MessageID}
51 | }
52 |
53 | //UUID returns the unique ID assigned to the ControlPacket when
54 | //it was originally received. Note: this is not related to the
55 | //MessageID field for MQTT packets
56 | func (sa *SubackPacket) UUID() uuid.UUID {
57 | return sa.uuid
58 | }
59 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets/unsuback.go:
--------------------------------------------------------------------------------
1 | package packets
2 |
3 | import (
4 | "fmt"
5 | "github.com/pborman/uuid"
6 | "io"
7 | )
8 |
9 | //UnsubackPacket is an internal representation of the fields of the
10 | //Unsuback MQTT packet
11 | type UnsubackPacket struct {
12 | FixedHeader
13 | MessageID uint16
14 | uuid uuid.UUID
15 | }
16 |
17 | func (ua *UnsubackPacket) String() string {
18 | str := fmt.Sprintf("%s\n", ua.FixedHeader)
19 | str += fmt.Sprintf("MessageID: %d", ua.MessageID)
20 | return str
21 | }
22 |
23 | func (ua *UnsubackPacket) Write(w io.Writer) error {
24 | var err error
25 | ua.FixedHeader.RemainingLength = 2
26 | packet := ua.FixedHeader.pack()
27 | packet.Write(encodeUint16(ua.MessageID))
28 | _, err = packet.WriteTo(w)
29 |
30 | return err
31 | }
32 |
33 | //Unpack decodes the details of a ControlPacket after the fixed
34 | //header has been read
35 | func (ua *UnsubackPacket) Unpack(b io.Reader) {
36 | ua.MessageID = decodeUint16(b)
37 | }
38 |
39 | //Details returns a Details struct containing the Qos and
40 | //MessageID of this ControlPacket
41 | func (ua *UnsubackPacket) Details() Details {
42 | return Details{Qos: 0, MessageID: ua.MessageID}
43 | }
44 |
45 | //UUID returns the unique ID assigned to the ControlPacket when
46 | //it was originally received. Note: this is not related to the
47 | //MessageID field for MQTT packets
48 | func (ua *UnsubackPacket) UUID() uuid.UUID {
49 | return ua.uuid
50 | }
51 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | go clean
4 |
5 | for file in *.go
6 | do
7 | echo -n "Compiling $file ..."
8 | go build "$file"
9 | echo " done."
10 | done
11 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/samplecerts/README:
--------------------------------------------------------------------------------
1 | Certificate structure:
2 |
3 | Root CA
4 | |
5 | |-> Intermediate CA
6 | |
7 | |-> Server
8 | |
9 | |-> Client
10 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/samplecerts/client-crt.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDRzCCAi8CAQIwDQYJKoZIhvcNAQEFBQAwbTELMAkGA1UEBhMCVVMxDjAMBgNV
3 | BAgMBUR1bW15MQ4wDAYDVQQHDAVEdW1teTEOMAwGA1UECgwFRHVtbXkxDjAMBgNV
4 | BAsMBUR1bW15MR4wHAYDVQQDDBVEdW1teSBJbnRlcm1lZGlhdGUgQ0EwHhcNMTMx
5 | MDIxMTkyNDIzWhcNMTgwOTI1MTkyNDIzWjBmMQswCQYDVQQGEwJVUzEOMAwGA1UE
6 | CAwFRHVtbXkxDjAMBgNVBAcMBUR1bW15MQ4wDAYDVQQKDAVEdW1teTEOMAwGA1UE
7 | CwwFRHVtbXkxFzAVBgNVBAMMDkR1bW15IChjbGllbnQpMIIBIjANBgkqhkiG9w0B
8 | AQEFAAOCAQ8AMIIBCgKCAQEA4J/+eKqsjK0QS+cSDa5Fh4XM4THy812JkWMySA5r
9 | bFxHZ5ye36/IuwyRQ0Yn2DvhhsDR5K7yz8K+Yfp9A6WRBkyHK/sy/8vurQHeDH3y
10 | lLtHCLi5nfyt2fDxWOYwFrS1giGn2IxJIHBAWu4cBODCkqwqAp92+Lqp3Sn+D+Fb
11 | maHEU3LHua8OIJiSeAIHo/jPqfHFqZxK1bXhGCSQKvUZCaTftsqDtn+LZSElqj1y
12 | 5/cnc7XGsTf8ml/+FDMX1aSAHf+pu+UAp9JqOXOM60A5JIpYu3Lsejp1RppyPJYP
13 | zC4nSN8R2LOdDChP2MB7f1/sXRGlLM/X3Vi4X+c6xQ85TQIDAQABMA0GCSqGSIb3
14 | DQEBBQUAA4IBAQAMWt9qMUOY5z1uyYcjUnconPHLM9MADCZI2sRbfdBOBHEnTVKv
15 | Y63SWnCt8TRJb01LKLIEys6pW1NUlxr6b+FwicNmycR0L8b63cmNXg2NmSZsnK9C
16 | fGT6BbbDdVPYjvmghpSd3soBGBLPsJvaFc6UL5tunm+hT7PxWjDxHZEiE18PTs05
17 | Vpp/ytILzhoXvJeFOWQHIdf4DLR5izGMNTKdQzgg1eBq2vKgjJIlEZ3j/AyHkJLE
18 | qFip1tyc0PRzgKYFLWttaZzakCLJOGuxtvYB+GrixVM7U23p5LQbLE0KX7fe2Gql
19 | xKMfSID5NUDNf1SuSrrGLD3gfnJEKVB8TVBk
20 | -----END CERTIFICATE-----
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/samplecerts/intermediateCA-crt.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDWDCCAkCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEO
3 | MAwGA1UECAwFRHVtbXkxDjAMBgNVBAcMBUR1bW15MQ4wDAYDVQQKDAVEdW1teTEO
4 | MAwGA1UECwwFRHVtbXkxETAPBgNVBAMMCER1bW15IENBMB4XDTEzMTAyMTE5MjQy
5 | M1oXDTE4MDkyNTE5MjQyM1owbTELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBUR1bW15
6 | MQ4wDAYDVQQHDAVEdW1teTEOMAwGA1UECgwFRHVtbXkxDjAMBgNVBAsMBUR1bW15
7 | MR4wHAYDVQQDDBVEdW1teSBJbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEB
8 | AQUAA4IBDwAwggEKAoIBAQDPfZIHpVYbb0zzNMISwjRiO2mqpgzGcFuTvNxBmGGH
9 | YTa+jAjdMakzdtNmPndgHu2e4eXvvxeRrAxjBwGrMGe8FqYvefBhjHktPJhgdGHE
10 | X2BEhXGSncx7FDl0qkT5n672x43DAUdTJKx7ovbFfWU3QAsgyNQUzfj0V+ojcPTj
11 | mSscmmc37ZPHp3yGkPeu/G9LGNzV6/NoM9Z4FNHKpwZ9dTT2wNQVGyEreNl2JKXw
12 | xhPIHkrIync0Tvj6SV9s4WaoZfCMvEQgA6yvSmGlOUhRG8vYIilgJ0dC/L9qd2VY
13 | CSCCHNEWXloY6plhjpOUJzAg3UQDUEO07KMP7pFp17FbAgMBAAGjEDAOMAwGA1Ud
14 | EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADmgjS9oIh1PPtvxmykgdyP4ITQX
15 | hACIqD6hTYSUkJYC5mq0IFGgZiA4BRiqKj6aUGCv60pwrJtZMNUXFJy0kWobw0WK
16 | 3c0vxsWM/tB2IGOkl9vjKo7BPci2Bi1JetmK3hbqXV/7QXkNj9IjANm5b5NFu3QX
17 | 6mtyEwGG/o1+jydxdqk3bWyQWj/ZbU1spGR66oLJh+5q0G4wBX8ZHRkxqZrOIYTa
18 | R8egZhLofldpXZwk5UY8vzf2iMOxQt47ge31ruIjnsKJoedcHUkP7a5VYA5OTOmK
19 | ZOauxdGZp3BMfl1TrIgsDwshlBoy+aHMHmeYa7bpsblLRgKxZclJg4C9uXA=
20 | -----END CERTIFICATE-----
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/samplecerts/mosquitto.org.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC8DCCAlmgAwIBAgIJAOD63PlXjJi8MA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD
3 | VQQGEwJHQjEXMBUGA1UECAwOVW5pdGVkIEtpbmdkb20xDjAMBgNVBAcMBURlcmJ5
4 | MRIwEAYDVQQKDAlNb3NxdWl0dG8xCzAJBgNVBAsMAkNBMRYwFAYDVQQDDA1tb3Nx
5 | dWl0dG8ub3JnMR8wHQYJKoZIhvcNAQkBFhByb2dlckBhdGNob28ub3JnMB4XDTEy
6 | MDYyOTIyMTE1OVoXDTIyMDYyNzIyMTE1OVowgZAxCzAJBgNVBAYTAkdCMRcwFQYD
7 | VQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwGA1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1v
8 | c3F1aXR0bzELMAkGA1UECwwCQ0ExFjAUBgNVBAMMDW1vc3F1aXR0by5vcmcxHzAd
9 | BgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hvby5vcmcwgZ8wDQYJKoZIhvcNAQEBBQAD
10 | gY0AMIGJAoGBAMYkLmX7SqOT/jJCZoQ1NWdCrr/pq47m3xxyXcI+FLEmwbE3R9vM
11 | rE6sRbP2S89pfrCt7iuITXPKycpUcIU0mtcT1OqxGBV2lb6RaOT2gC5pxyGaFJ+h
12 | A+GIbdYKO3JprPxSBoRponZJvDGEZuM3N7p3S/lRoi7G5wG5mvUmaE5RAgMBAAGj
13 | UDBOMB0GA1UdDgQWBBTad2QneVztIPQzRRGj6ZHKqJTv5jAfBgNVHSMEGDAWgBTa
14 | d2QneVztIPQzRRGj6ZHKqJTv5jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
15 | A4GBAAqw1rK4NlRUCUBLhEFUQasjP7xfFqlVbE2cRy0Rs4o3KS0JwzQVBwG85xge
16 | REyPOFdGdhBY2P1FNRy0MDr6xr+D2ZOwxs63dG1nnAnWZg7qwoLgpZ4fESPD3PkA
17 | 1ZgKJc2zbSQ9fCPxt2W3mdVav66c6fsb7els2W2Iz7gERJSX
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/samplecerts/rootCA-crt.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDizCCAnOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzEO
3 | MAwGA1UECAwFRHVtbXkxDjAMBgNVBAcMBUR1bW15MQ4wDAYDVQQKDAVEdW1teTEO
4 | MAwGA1UECwwFRHVtbXkxETAPBgNVBAMMCER1bW15IENBMB4XDTEzMTAyMTE5MjQy
5 | M1oXDTE4MDkyNTE5MjQyM1owYDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBUR1bW15
6 | MQ4wDAYDVQQHDAVEdW1teTEOMAwGA1UECgwFRHVtbXkxDjAMBgNVBAsMBUR1bW15
7 | MREwDwYDVQQDDAhEdW1teSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
8 | ggEBAMLR0DHck8OtiA34k/7MqgQdharDu72HBPBCZxQ0SlaUK7/Qa3IwODk1IIzj
9 | fmWCsH4+HfEYgrfWGVlD7YG+61FE/HeeN63hoBi5S1l5kIGk5FIv/OL/mBBe1ROa
10 | FmIa4MurHa7a0UDUl7Hm4/GXLCpSc6vQohXzHpqwZ9BiZ0t0sLuP754yakwnToJ8
11 | FmbOBumj2TZP9D68gACTwcoxzwNo1OWLOEW2GzWwwOlKYnWDAaq5wQvA7pfAcyPN
12 | NOy7PJU1yC1p/4bYH8gEfhjeYsJLN8aqjgO/Kw2XICp1R+yYKTxkUu+Ri2MPavjC
13 | nQhqYWhvZJpWsgq8e1k9f/26EksCAwEAAaNQME4wHQYDVR0OBBYEFFu7Po4tkK2u
14 | WAf/UwAYmP9EhEy6MB8GA1UdIwQYMBaAFFu7Po4tkK2uWAf/UwAYmP9EhEy6MAwG
15 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADyJC71JEKYa9ipLXwI97vMZ
16 | T8kQeZwB74giPQNbGhRGtn+br6WZGtTUm9Zvwf6Wj5qeR0K07iFWasSSOGyBzY4x
17 | Q4Z8lxWQgNgh8Ea+Ki/ylgeFdKj6G3iPgMFevNkGwjOejvkI3UN7b1oiZ0Z4XftK
18 | TsLGKZQXU6bFqdZnBk8H79pbRSGDyzGy3NysExmYP5hfLLS02tRD16kabrbPvoWo
19 | gB+KwZWKg6Sv0iNKthiHTigxNgMsv+SetnX9xGjtTdWo+qWBExccQ2cCHNDmAG6L
20 | E+ZgH7pAeJMlyllaccxY1FJjHbM8zjfxiXj8E/qz6iKvF2iKoVlX9RpJbrn2X7M=
21 | -----END CERTIFICATE-----
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/samplecerts/server-crt.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDYTCCAkmgAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJVUzEO
3 | MAwGA1UECAwFRHVtbXkxDjAMBgNVBAcMBUR1bW15MQ4wDAYDVQQKDAVEdW1teTEO
4 | MAwGA1UECwwFRHVtbXkxHjAcBgNVBAMMFUR1bW15IEludGVybWVkaWF0ZSBDQTAe
5 | Fw0xMzEwMjExOTI0MjNaFw0xODA5MjUxOTI0MjNaMGYxCzAJBgNVBAYTAlVTMQ4w
6 | DAYDVQQIDAVEdW1teTEOMAwGA1UEBwwFRHVtbXkxDjAMBgNVBAoMBUR1bW15MQ4w
7 | DAYDVQQLDAVEdW1teTEXMBUGA1UEAwwORHVtbXkgKHNlcnZlcikwggEiMA0GCSqG
8 | SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0fQCRUWXt+i7JMR55Zuo6wBRxG7RnPutN
9 | 2L7J/18io52vxjm8AZDiC0JFkCHh72ZzvbgVA+e+WxAIYfioRis4JWw4jK8v5m8q
10 | cZzS0GJNTMROPiZQi7A81tAbrV00XN7d5PsmIJ2Bf4XbJWMy31CsmoFloeRMd7bR
11 | LxwDIb0qqRawhKsWdfZB/c9wGKmHlei50B7PXk+koKnVdsLwXxtCZDvc/3fNRHEK
12 | lZs4m0N05G38FdrnczPm/0pie87nK9rnklL7u1sYOukOznnOtW5h7+A4M+DxzME0
13 | HRU6k4d+6QvukxBlsE93gHhwRsejIuDGlqD+DRxk2PdmmgsmPH59AgMBAAGjEzAR
14 | MA8GA1UdEQQIMAaHBAoKBOQwDQYJKoZIhvcNAQEFBQADggEBAJ3bKs2b4cAJWTZj
15 | 69dMEfYZKcQIXs7euwtKlP7H8m5c+X5KmZPi1Puq4Z0gtvLu/z7J9UjZjG0CoylV
16 | q15Zp5svryJ7XzcsZs7rwyo1JtngW1z54wr9MezqIOF2w12dTwEAINFsW7TxAsH7
17 | bfqkzZjuCbbsww5q4eHuZp0yaMHc3hOGaUot27OTlxlIMhv7VBBqWAj0jmvAfTKf
18 | la0SiL/Mc8rD8D5C0SXGcCL6li/kqtinAxzhokuyyPf+hQX35kcZxEPu6WxtYVLv
19 | hMzrokOZP2FrGbCnhaNT8gw4Aa0RXV1JgonRWYSbkeaCzvr2bJ0OuJiDdwdRKvOo
20 | raKLlfY=
21 | -----END CERTIFICATE-----
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/samples/simple.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/epl-v10.html
8 | *
9 | * Contributors:
10 | * Seth Hoenig
11 | * Allan Stockdill-Mander
12 | * Mike Robertson
13 | */
14 |
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "os"
20 | "time"
21 |
22 | MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
23 | )
24 |
25 | var f MQTT.MessageHandler = func(client *MQTT.Client, msg MQTT.Message) {
26 | fmt.Printf("TOPIC: %s\n", msg.Topic())
27 | fmt.Printf("MSG: %s\n", msg.Payload())
28 | }
29 |
30 | func main() {
31 | opts := MQTT.NewClientOptions().AddBroker("tcp://iot.eclipse.org:1883").SetClientID("gotrivial")
32 | opts.SetDefaultPublishHandler(f)
33 |
34 | c := MQTT.NewClient(opts)
35 | if token := c.Connect(); token.Wait() && token.Error() != nil {
36 | panic(token.Error())
37 | }
38 |
39 | if token := c.Subscribe("/go-mqtt/sample", 0, nil); token.Wait() && token.Error() != nil {
40 | fmt.Println(token.Error())
41 | os.Exit(1)
42 | }
43 |
44 | for i := 0; i < 5; i++ {
45 | text := fmt.Sprintf("this is msg #%d!", i)
46 | token := c.Publish("/go-mqtt/sample", 0, false, text)
47 | token.Wait()
48 | }
49 |
50 | time.Sleep(3 * time.Second)
51 |
52 | if token := c.Unsubscribe("/go-mqtt/sample"); token.Wait() && token.Error() != nil {
53 | fmt.Println(token.Error())
54 | os.Exit(1)
55 | }
56 |
57 | c.Disconnect(250)
58 | }
59 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/trace.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * which accompanies this distribution, and is available at
7 | * http://www.eclipse.org/legal/epl-v10.html
8 | *
9 | * Contributors:
10 | * Seth Hoenig
11 | * Allan Stockdill-Mander
12 | * Mike Robertson
13 | */
14 |
15 | package mqtt
16 |
17 | import (
18 | "io/ioutil"
19 | "log"
20 | )
21 |
22 | // Internal levels of library output that are initialised to not print
23 | // anything but can be overridden by programmer
24 | var (
25 | ERROR *log.Logger
26 | CRITICAL *log.Logger
27 | WARN *log.Logger
28 | DEBUG *log.Logger
29 | )
30 |
31 | func init() {
32 | ERROR = log.New(ioutil.Discard, "", 0)
33 | CRITICAL = log.New(ioutil.Discard, "", 0)
34 | WARN = log.New(ioutil.Discard, "", 0)
35 | DEBUG = log.New(ioutil.Discard, "", 0)
36 | }
37 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore:
--------------------------------------------------------------------------------
1 | logrus
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | go:
3 | - 1.3
4 | - 1.4
5 | - tip
6 | install:
7 | - go get -t ./...
8 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 0.9.0 (Unreleased)
2 |
3 | * logrus/text_formatter: don't emit empty msg
4 | * logrus/hooks/airbrake: move out of main repository
5 | * logrus/hooks/sentry: move out of main repository
6 | * logrus/hooks/papertrail: move out of main repository
7 | * logrus/hooks/bugsnag: move out of main repository
8 |
9 | # 0.8.7
10 |
11 | * logrus/core: fix possible race (#216)
12 | * logrus/doc: small typo fixes and doc improvements
13 |
14 |
15 | # 0.8.6
16 |
17 | * hooks/raven: allow passing an initialized client
18 |
19 | # 0.8.5
20 |
21 | * logrus/core: revert #208
22 |
23 | # 0.8.4
24 |
25 | * formatter/text: fix data race (#218)
26 |
27 | # 0.8.3
28 |
29 | * logrus/core: fix entry log level (#208)
30 | * logrus/core: improve performance of text formatter by 40%
31 | * logrus/core: expose `LevelHooks` type
32 | * logrus/core: add support for DragonflyBSD and NetBSD
33 | * formatter/text: print structs more verbosely
34 |
35 | # 0.8.2
36 |
37 | * logrus: fix more Fatal family functions
38 |
39 | # 0.8.1
40 |
41 | * logrus: fix not exiting on `Fatalf` and `Fatalln`
42 |
43 | # 0.8.0
44 |
45 | * logrus: defaults to stderr instead of stdout
46 | * hooks/sentry: add special field for `*http.Request`
47 | * formatter/text: ignore Windows for colors
48 |
49 | # 0.7.3
50 |
51 | * formatter/\*: allow configuration of timestamp layout
52 |
53 | # 0.7.2
54 |
55 | * formatter/text: Add configuration option for time format (#158)
56 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Simon Eskildsen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
3 |
4 |
5 | The simplest way to use Logrus is simply the package-level exported logger:
6 |
7 | package main
8 |
9 | import (
10 | log "github.com/Sirupsen/logrus"
11 | )
12 |
13 | func main() {
14 | log.WithFields(log.Fields{
15 | "animal": "walrus",
16 | "number": 1,
17 | "size": 10,
18 | }).Info("A walrus appears")
19 | }
20 |
21 | Output:
22 | time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
23 |
24 | For a full guide visit https://github.com/Sirupsen/logrus
25 | */
26 | package logrus
27 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/Sirupsen/logrus"
5 | )
6 |
7 | var log = logrus.New()
8 |
9 | func init() {
10 | log.Formatter = new(logrus.JSONFormatter)
11 | log.Formatter = new(logrus.TextFormatter) // default
12 | log.Level = logrus.DebugLevel
13 | }
14 |
15 | func main() {
16 | defer func() {
17 | err := recover()
18 | if err != nil {
19 | log.WithFields(logrus.Fields{
20 | "omg": true,
21 | "err": err,
22 | "number": 100,
23 | }).Fatal("The ice breaks!")
24 | }
25 | }()
26 |
27 | log.WithFields(logrus.Fields{
28 | "animal": "walrus",
29 | "number": 8,
30 | }).Debug("Started observing beach")
31 |
32 | log.WithFields(logrus.Fields{
33 | "animal": "walrus",
34 | "size": 10,
35 | }).Info("A group of walrus emerges from the ocean")
36 |
37 | log.WithFields(logrus.Fields{
38 | "omg": true,
39 | "number": 122,
40 | }).Warn("The group's number increased tremendously!")
41 |
42 | log.WithFields(logrus.Fields{
43 | "temperature": -4,
44 | }).Debug("Temperature changes")
45 |
46 | log.WithFields(logrus.Fields{
47 | "animal": "orca",
48 | "size": 9009,
49 | }).Panic("It's over 9000!")
50 | }
51 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/Sirupsen/logrus"
5 | "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
6 | )
7 |
8 | var log = logrus.New()
9 |
10 | func init() {
11 | log.Formatter = new(logrus.TextFormatter) // default
12 | log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
13 | }
14 |
15 | func main() {
16 | log.WithFields(logrus.Fields{
17 | "animal": "walrus",
18 | "size": 10,
19 | }).Info("A group of walrus emerges from the ocean")
20 |
21 | log.WithFields(logrus.Fields{
22 | "omg": true,
23 | "number": 122,
24 | }).Warn("The group's number increased tremendously!")
25 |
26 | log.WithFields(logrus.Fields{
27 | "omg": true,
28 | "number": 100,
29 | }).Fatal("The ice breaks!")
30 | }
31 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go:
--------------------------------------------------------------------------------
1 | package logrus
2 |
3 | import "time"
4 |
5 | const DefaultTimestampFormat = time.RFC3339
6 |
7 | // The Formatter interface is used to implement a custom Formatter. It takes an
8 | // `Entry`. It exposes all the fields, including the default ones:
9 | //
10 | // * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
11 | // * `entry.Data["time"]`. The timestamp.
12 | // * `entry.Data["level"]. The level the entry was logged at.
13 | //
14 | // Any additional fields added with `WithField` or `WithFields` are also in
15 | // `entry.Data`. Format is expected to return an array of bytes which are then
16 | // logged to `logger.Out`.
17 | type Formatter interface {
18 | Format(*Entry) ([]byte, error)
19 | }
20 |
21 | // This is to not silently overwrite `time`, `msg` and `level` fields when
22 | // dumping it. If this code wasn't there doing:
23 | //
24 | // logrus.WithField("level", 1).Info("hello")
25 | //
26 | // Would just silently drop the user provided level. Instead with this code
27 | // it'll logged as:
28 | //
29 | // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
30 | //
31 | // It's not exported because it's still using Data in an opinionated way. It's to
32 | // avoid code duplication between the two default formatters.
33 | func prefixFieldClashes(data Fields) {
34 | _, ok := data["time"]
35 | if ok {
36 | data["fields.time"] = data["time"]
37 | }
38 |
39 | _, ok = data["msg"]
40 | if ok {
41 | data["fields.msg"] = data["msg"]
42 | }
43 |
44 | _, ok = data["level"]
45 | if ok {
46 | data["fields.level"] = data["level"]
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go:
--------------------------------------------------------------------------------
1 | package logstash
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 |
7 | "github.com/Sirupsen/logrus"
8 | )
9 |
10 | // Formatter generates json in logstash format.
11 | // Logstash site: http://logstash.net/
12 | type LogstashFormatter struct {
13 | Type string // if not empty use for logstash type field.
14 |
15 | // TimestampFormat sets the format used for timestamps.
16 | TimestampFormat string
17 | }
18 |
19 | func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) {
20 | entry.Data["@version"] = 1
21 |
22 | if f.TimestampFormat == "" {
23 | f.TimestampFormat = logrus.DefaultTimestampFormat
24 | }
25 |
26 | entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat)
27 |
28 | // set message field
29 | v, ok := entry.Data["message"]
30 | if ok {
31 | entry.Data["fields.message"] = v
32 | }
33 | entry.Data["message"] = entry.Message
34 |
35 | // set level field
36 | v, ok = entry.Data["level"]
37 | if ok {
38 | entry.Data["fields.level"] = v
39 | }
40 | entry.Data["level"] = entry.Level.String()
41 |
42 | // set type field
43 | if f.Type != "" {
44 | v, ok = entry.Data["type"]
45 | if ok {
46 | entry.Data["fields.type"] = v
47 | }
48 | entry.Data["type"] = f.Type
49 | }
50 |
51 | serialized, err := json.Marshal(entry.Data)
52 | if err != nil {
53 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
54 | }
55 | return append(serialized, '\n'), nil
56 | }
57 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go:
--------------------------------------------------------------------------------
1 | package logrus
2 |
3 | // A hook to be fired when logging on the logging levels returned from
4 | // `Levels()` on your implementation of the interface. Note that this is not
5 | // fired in a goroutine or a channel with workers, you should handle such
6 | // functionality yourself if your call is non-blocking and you don't wish for
7 | // the logging calls for levels returned from `Levels()` to block.
8 | type Hook interface {
9 | Levels() []Level
10 | Fire(*Entry) error
11 | }
12 |
13 | // Internal type for storing the hooks on a logger instance.
14 | type LevelHooks map[Level][]Hook
15 |
16 | // Add a hook to an instance of logger. This is called with
17 | // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
18 | func (hooks LevelHooks) Add(hook Hook) {
19 | for _, level := range hook.Levels() {
20 | hooks[level] = append(hooks[level], hook)
21 | }
22 | }
23 |
24 | // Fire all the hooks for the passed level. Used by `entry.log` to fire
25 | // appropriate hooks for a log entry.
26 | func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
27 | for _, hook := range hooks[level] {
28 | if err := hook.Fire(entry); err != nil {
29 | return err
30 | }
31 | }
32 |
33 | return nil
34 | }
35 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md:
--------------------------------------------------------------------------------
1 | # Syslog Hooks for Logrus
2 |
3 | ## Usage
4 |
5 | ```go
6 | import (
7 | "log/syslog"
8 | "github.com/Sirupsen/logrus"
9 | logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
10 | )
11 |
12 | func main() {
13 | log := logrus.New()
14 | hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
15 |
16 | if err == nil {
17 | log.Hooks.Add(hook)
18 | }
19 | }
20 | ```
21 |
22 | If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following.
23 |
24 | ```go
25 | import (
26 | "log/syslog"
27 | "github.com/Sirupsen/logrus"
28 | logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
29 | )
30 |
31 | func main() {
32 | log := logrus.New()
33 | hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
34 |
35 | if err == nil {
36 | log.Hooks.Add(hook)
37 | }
38 | }
39 | ```
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go:
--------------------------------------------------------------------------------
1 | // +build !windows,!nacl,!plan9
2 |
3 | package logrus_syslog
4 |
5 | import (
6 | "fmt"
7 | "github.com/Sirupsen/logrus"
8 | "log/syslog"
9 | "os"
10 | )
11 |
12 | // SyslogHook to send logs via syslog.
13 | type SyslogHook struct {
14 | Writer *syslog.Writer
15 | SyslogNetwork string
16 | SyslogRaddr string
17 | }
18 |
19 | // Creates a hook to be added to an instance of logger. This is called with
20 | // `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
21 | // `if err == nil { log.Hooks.Add(hook) }`
22 | func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
23 | w, err := syslog.Dial(network, raddr, priority, tag)
24 | return &SyslogHook{w, network, raddr}, err
25 | }
26 |
27 | func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
28 | line, err := entry.String()
29 | if err != nil {
30 | fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
31 | return err
32 | }
33 |
34 | switch entry.Level {
35 | case logrus.PanicLevel:
36 | return hook.Writer.Crit(line)
37 | case logrus.FatalLevel:
38 | return hook.Writer.Crit(line)
39 | case logrus.ErrorLevel:
40 | return hook.Writer.Err(line)
41 | case logrus.WarnLevel:
42 | return hook.Writer.Warning(line)
43 | case logrus.InfoLevel:
44 | return hook.Writer.Info(line)
45 | case logrus.DebugLevel:
46 | return hook.Writer.Debug(line)
47 | default:
48 | return nil
49 | }
50 | }
51 |
52 | func (hook *SyslogHook) Levels() []logrus.Level {
53 | return []logrus.Level{
54 | logrus.PanicLevel,
55 | logrus.FatalLevel,
56 | logrus.ErrorLevel,
57 | logrus.WarnLevel,
58 | logrus.InfoLevel,
59 | logrus.DebugLevel,
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go:
--------------------------------------------------------------------------------
1 | package logrus
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type JSONFormatter struct {
9 | // TimestampFormat sets the format used for marshaling timestamps.
10 | TimestampFormat string
11 | }
12 |
13 | func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
14 | data := make(Fields, len(entry.Data)+3)
15 | for k, v := range entry.Data {
16 | switch v := v.(type) {
17 | case error:
18 | // Otherwise errors are ignored by `encoding/json`
19 | // https://github.com/Sirupsen/logrus/issues/137
20 | data[k] = v.Error()
21 | default:
22 | data[k] = v
23 | }
24 | }
25 | prefixFieldClashes(data)
26 |
27 | timestampFormat := f.TimestampFormat
28 | if timestampFormat == "" {
29 | timestampFormat = DefaultTimestampFormat
30 | }
31 |
32 | data["time"] = entry.Time.Format(timestampFormat)
33 | data["msg"] = entry.Message
34 | data["level"] = entry.Level.String()
35 |
36 | serialized, err := json.Marshal(data)
37 | if err != nil {
38 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
39 | }
40 | return append(serialized, '\n'), nil
41 | }
42 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_bsd.go:
--------------------------------------------------------------------------------
1 | // +build darwin freebsd openbsd netbsd dragonfly
2 |
3 | package logrus
4 |
5 | import "syscall"
6 |
7 | const ioctlReadTermios = syscall.TIOCGETA
8 |
9 | type Termios syscall.Termios
10 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go:
--------------------------------------------------------------------------------
1 | // Based on ssh/terminal:
2 | // Copyright 2013 The Go Authors. All rights reserved.
3 | // Use of this source code is governed by a BSD-style
4 | // license that can be found in the LICENSE file.
5 |
6 | package logrus
7 |
8 | import "syscall"
9 |
10 | const ioctlReadTermios = syscall.TCGETS
11 |
12 | type Termios syscall.Termios
13 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go:
--------------------------------------------------------------------------------
1 | // Based on ssh/terminal:
2 | // Copyright 2011 The Go Authors. All rights reserved.
3 | // Use of this source code is governed by a BSD-style
4 | // license that can be found in the LICENSE file.
5 |
6 | // +build linux darwin freebsd openbsd netbsd dragonfly
7 |
8 | package logrus
9 |
10 | import (
11 | "syscall"
12 | "unsafe"
13 | )
14 |
15 | // IsTerminal returns true if stderr's file descriptor is a terminal.
16 | func IsTerminal() bool {
17 | fd := syscall.Stderr
18 | var termios Termios
19 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
20 | return err == 0
21 | }
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_solaris.go:
--------------------------------------------------------------------------------
1 | // +build solaris
2 |
3 | package logrus
4 |
5 | import (
6 | "os"
7 |
8 | "golang.org/x/sys/unix"
9 | )
10 |
11 | // IsTerminal returns true if the given file descriptor is a terminal.
12 | func IsTerminal() bool {
13 | _, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA)
14 | return err == nil
15 | }
16 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go:
--------------------------------------------------------------------------------
1 | // Based on ssh/terminal:
2 | // Copyright 2011 The Go Authors. All rights reserved.
3 | // Use of this source code is governed by a BSD-style
4 | // license that can be found in the LICENSE file.
5 |
6 | // +build windows
7 |
8 | package logrus
9 |
10 | import (
11 | "syscall"
12 | "unsafe"
13 | )
14 |
15 | var kernel32 = syscall.NewLazyDLL("kernel32.dll")
16 |
17 | var (
18 | procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
19 | )
20 |
21 | // IsTerminal returns true if stderr's file descriptor is a terminal.
22 | func IsTerminal() bool {
23 | fd := syscall.Stderr
24 | var st uint32
25 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
26 | return r != 0 && e == 0
27 | }
28 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/Sirupsen/logrus/writer.go:
--------------------------------------------------------------------------------
1 | package logrus
2 |
3 | import (
4 | "bufio"
5 | "io"
6 | "runtime"
7 | )
8 |
9 | func (logger *Logger) Writer() *io.PipeWriter {
10 | reader, writer := io.Pipe()
11 |
12 | go logger.writerScanner(reader)
13 | runtime.SetFinalizer(writer, writerFinalizer)
14 |
15 | return writer
16 | }
17 |
18 | func (logger *Logger) writerScanner(reader *io.PipeReader) {
19 | scanner := bufio.NewScanner(reader)
20 | for scanner.Scan() {
21 | logger.Print(scanner.Text())
22 | }
23 | if err := scanner.Err(); err != nil {
24 | logger.Errorf("Error while reading from Writer: %s", err)
25 | }
26 | reader.Close()
27 | }
28 |
29 | func writerFinalizer(writer *io.PipeWriter) {
30 | writer.Close()
31 | }
32 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/codegangsta/inject/.gitignore:
--------------------------------------------------------------------------------
1 | inject
2 | inject.test
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/codegangsta/inject/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Jeremy Saenz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/codegangsta/inject/update_readme.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | go get github.com/robertkrimen/godocdown/godocdown
3 | godocdown > README.md
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // borrowed from golang/net/context/ctxhttp/cancelreq.go
6 |
7 | package client
8 |
9 | import "net/http"
10 |
11 | func requestCanceler(tr CancelableTransport, req *http.Request) func() {
12 | ch := make(chan struct{})
13 | req.Cancel = ch
14 |
15 | return func() {
16 | close(ch)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/client/cluster_error.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 CoreOS, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package client
16 |
17 | import "fmt"
18 |
19 | type ClusterError struct {
20 | Errors []error
21 | }
22 |
23 | func (ce *ClusterError) Error() string {
24 | return ErrClusterUnavailable.Error()
25 | }
26 |
27 | func (ce *ClusterError) Detail() string {
28 | s := ""
29 | for i, e := range ce.Errors {
30 | s += fmt.Sprintf("error #%d: %s\n", i, e)
31 | }
32 | return s
33 | }
34 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/client/discover.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 CoreOS, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package client
16 |
17 | // Discoverer is an interface that wraps the Discover method.
18 | type Discoverer interface {
19 | // Discover looks up the etcd servers for the domain.
20 | Discover(domain string) ([]string, error)
21 | }
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/client/util.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 CoreOS, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package client
16 |
17 | // IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound.
18 | func IsKeyNotFound(err error) bool {
19 | if cErr, ok := err.(Error); ok {
20 | return cErr.Code == ErrorCodeKeyNotFound
21 | }
22 | return false
23 | }
24 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/pkg/pathutil/path.go:
--------------------------------------------------------------------------------
1 | // Copyright 2009 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package pathutil implements utility functions for handling slash-separated
6 | // paths.
7 | package pathutil
8 |
9 | import "path"
10 |
11 | // CanonicalURLPath returns the canonical url path for p, which follows the rules:
12 | // 1. the path always starts with "/"
13 | // 2. replace multiple slashes with a single slash
14 | // 3. replace each '.' '..' path name element with equivalent one
15 | // 4. keep the trailing slash
16 | // The function is borrowed from stdlib http.cleanPath in server.go.
17 | func CanonicalURLPath(p string) string {
18 | if p == "" {
19 | return "/"
20 | }
21 | if p[0] != '/' {
22 | p = "/" + p
23 | }
24 | np := path.Clean(p)
25 | // path.Clean removes trailing slash except for root,
26 | // put the trailing slash back if necessary.
27 | if p[len(p)-1] == '/' && np != "/" {
28 | np += "/"
29 | }
30 | return np
31 | }
32 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 CoreOS, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package types declares various data types and implements type-checking
16 | // functions.
17 | package types
18 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/id.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 CoreOS, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package types
16 |
17 | import (
18 | "strconv"
19 | )
20 |
21 | // ID represents a generic identifier which is canonically
22 | // stored as a uint64 but is typically represented as a
23 | // base-16 string for input/output
24 | type ID uint64
25 |
26 | func (i ID) String() string {
27 | return strconv.FormatUint(uint64(i), 16)
28 | }
29 |
30 | // IDFromString attempts to create an ID from a base-16 string.
31 | func IDFromString(s string) (ID, error) {
32 | i, err := strconv.ParseUint(s, 16, 64)
33 | return ID(i), err
34 | }
35 |
36 | // IDSlice implements the sort interface
37 | type IDSlice []ID
38 |
39 | func (p IDSlice) Len() int { return len(p) }
40 | func (p IDSlice) Less(i, j int) bool { return uint64(p[i]) < uint64(p[j]) }
41 | func (p IDSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
42 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/slice.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 CoreOS, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package types
16 |
17 | // Uint64Slice implements sort interface
18 | type Uint64Slice []uint64
19 |
20 | func (p Uint64Slice) Len() int { return len(p) }
21 | func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
22 | func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
23 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/garyburd/redigo/internal/commandinfo.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Gary Burd
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package internal
16 |
17 | import (
18 | "strings"
19 | )
20 |
21 | const (
22 | WatchState = 1 << iota
23 | MultiState
24 | SubscribeState
25 | MonitorState
26 | )
27 |
28 | type CommandInfo struct {
29 | Set, Clear int
30 | }
31 |
32 | var commandInfos = map[string]CommandInfo{
33 | "WATCH": {Set: WatchState},
34 | "UNWATCH": {Clear: WatchState},
35 | "MULTI": {Set: MultiState},
36 | "EXEC": {Clear: WatchState | MultiState},
37 | "DISCARD": {Clear: WatchState | MultiState},
38 | "PSUBSCRIBE": {Set: SubscribeState},
39 | "SUBSCRIBE": {Set: SubscribeState},
40 | "MONITOR": {Set: MonitorState},
41 | }
42 |
43 | func init() {
44 | for n, ci := range commandInfos {
45 | commandInfos[strings.ToLower(n)] = ci
46 | }
47 | }
48 |
49 | func LookupCommandInfo(commandName string) CommandInfo {
50 | if ci, ok := commandInfos[commandName]; ok {
51 | return ci
52 | }
53 | return commandInfos[strings.ToUpper(commandName)]
54 | }
55 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/garyburd/redigo/redis/redis.go:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Gary Burd
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may
4 | // not use this file except in compliance with the License. You may obtain
5 | // a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | // License for the specific language governing permissions and limitations
13 | // under the License.
14 |
15 | package redis
16 |
17 | // Error represents an error returned in a command reply.
18 | type Error string
19 |
20 | func (err Error) Error() string { return string(err) }
21 |
22 | // Conn represents a connection to a Redis server.
23 | type Conn interface {
24 | // Close closes the connection.
25 | Close() error
26 |
27 | // Err returns a non-nil value if the connection is broken. The returned
28 | // value is either the first non-nil value returned from the underlying
29 | // network connection or a protocol parsing error. Applications should
30 | // close broken connections.
31 | Err() error
32 |
33 | // Do sends a command to the server and returns the received reply.
34 | Do(commandName string, args ...interface{}) (reply interface{}, err error)
35 |
36 | // Send writes the command to the client's output buffer.
37 | Send(commandName string, args ...interface{}) error
38 |
39 | // Flush flushes the output buffer to the Redis server.
40 | Flush() error
41 |
42 | // Receive receives a single reply from the Redis server
43 | Receive() (reply interface{}, err error)
44 | }
45 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 | *.test
24 |
25 | /.godeps
26 | /.envrc
27 |
28 | # Godeps
29 | Godeps/_workspace
30 | Godeps/Readme
31 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/Godeps/Godeps.json:
--------------------------------------------------------------------------------
1 | {
2 | "ImportPath": "github.com/go-martini/martini",
3 | "GoVersion": "go1.4.2",
4 | "Deps": [
5 | {
6 | "ImportPath": "github.com/codegangsta/inject",
7 | "Comment": "v1.0-rc1-10-g33e0aa1",
8 | "Rev": "33e0aa1cb7c019ccc3fbe049a8262a6403d30504"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Jeremy Saenz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/env.go:
--------------------------------------------------------------------------------
1 | package martini
2 |
3 | import (
4 | "os"
5 | )
6 |
7 | // Envs
8 | const (
9 | Dev string = "development"
10 | Prod string = "production"
11 | Test string = "test"
12 | )
13 |
14 | // Env is the environment that Martini is executing in. The MARTINI_ENV is read on initialization to set this variable.
15 | var Env = Dev
16 | var Root string
17 |
18 | func setENV(e string) {
19 | if len(e) > 0 {
20 | Env = e
21 | }
22 | }
23 |
24 | func init() {
25 | setENV(os.Getenv("MARTINI_ENV"))
26 | var err error
27 | Root, err = os.Getwd()
28 | if err != nil {
29 | panic(err)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/go_version.go:
--------------------------------------------------------------------------------
1 | // +build !go1.1
2 |
3 | package martini
4 |
5 | func MartiniDoesNotSupportGo1Point0() {
6 | "Martini requires Go 1.1 or greater."
7 | }
8 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/logger.go:
--------------------------------------------------------------------------------
1 | package martini
2 |
3 | import (
4 | "log"
5 | "net/http"
6 | "time"
7 | )
8 |
9 | // Logger returns a middleware handler that logs the request as it goes in and the response as it goes out.
10 | func Logger() Handler {
11 | return func(res http.ResponseWriter, req *http.Request, c Context, log *log.Logger) {
12 | start := time.Now()
13 |
14 | addr := req.Header.Get("X-Real-IP")
15 | if addr == "" {
16 | addr = req.Header.Get("X-Forwarded-For")
17 | if addr == "" {
18 | addr = req.RemoteAddr
19 | }
20 | }
21 |
22 | log.Printf("Started %s %s for %s", req.Method, req.URL.Path, addr)
23 |
24 | rw := res.(ResponseWriter)
25 | c.Next()
26 |
27 | log.Printf("Completed %v %s in %v\n", rw.Status(), http.StatusText(rw.Status()), time.Since(start))
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/return_handler.go:
--------------------------------------------------------------------------------
1 | package martini
2 |
3 | import (
4 | "github.com/codegangsta/inject"
5 | "net/http"
6 | "reflect"
7 | )
8 |
9 | // ReturnHandler is a service that Martini provides that is called
10 | // when a route handler returns something. The ReturnHandler is
11 | // responsible for writing to the ResponseWriter based on the values
12 | // that are passed into this function.
13 | type ReturnHandler func(Context, []reflect.Value)
14 |
15 | func defaultReturnHandler() ReturnHandler {
16 | return func(ctx Context, vals []reflect.Value) {
17 | rv := ctx.Get(inject.InterfaceOf((*http.ResponseWriter)(nil)))
18 | res := rv.Interface().(http.ResponseWriter)
19 | var responseVal reflect.Value
20 | if len(vals) > 1 && vals[0].Kind() == reflect.Int {
21 | res.WriteHeader(int(vals[0].Int()))
22 | responseVal = vals[1]
23 | } else if len(vals) > 0 {
24 | responseVal = vals[0]
25 | }
26 | if canDeref(responseVal) {
27 | responseVal = responseVal.Elem()
28 | }
29 | if isByteSlice(responseVal) {
30 | res.Write(responseVal.Bytes())
31 | } else {
32 | res.Write([]byte(responseVal.String()))
33 | }
34 | }
35 | }
36 |
37 | func isByteSlice(val reflect.Value) bool {
38 | return val.Kind() == reflect.Slice && val.Type().Elem().Kind() == reflect.Uint8
39 | }
40 |
41 | func canDeref(val reflect.Value) bool {
42 | return val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr
43 | }
44 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-martini/martini/wercker.yml:
--------------------------------------------------------------------------------
1 | box: wercker/golang@1.1.1
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .DS_Store?
3 | ._*
4 | .Spotlight-V100
5 | .Trashes
6 | Icon?
7 | ehthumbs.db
8 | Thumbs.db
9 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: go
3 | go:
4 | - 1.2
5 | - 1.3
6 | - 1.4
7 | - tip
8 |
9 | before_script:
10 | - mysql -e 'create database gotest;'
11 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-sql-driver/mysql/AUTHORS:
--------------------------------------------------------------------------------
1 | # This is the official list of Go-MySQL-Driver authors for copyright purposes.
2 |
3 | # If you are submitting a patch, please add your name or the name of the
4 | # organization which holds the copyright to this list in alphabetical order.
5 |
6 | # Names should be added to this file as
7 | # Name
8 | # The email address is not required for organizations.
9 | # Please keep the list sorted.
10 |
11 |
12 | # Individual Persons
13 |
14 | Aaron Hopkins
15 | Arne Hormann
16 | Carlos Nieto
17 | Chris Moos
18 | DisposaBoy
19 | Frederick Mayle
20 | Gustavo Kristic
21 | Hanno Braun
22 | Henri Yandell
23 | INADA Naoki
24 | James Harr
25 | Jian Zhen
26 | Joshua Prunier
27 | Julien Schmidt
28 | Kamil Dziedzic
29 | Leonardo YongUk Kim
30 | Lucas Liu
31 | Luke Scott
32 | Michael Woolnough
33 | Nicola Peduzzi
34 | Runrioter Wung
35 | Soroush Pour
36 | Stan Putrya
37 | Xiaobing Jiang
38 | Xiuming Chen
39 |
40 | # Organizations
41 |
42 | Barracuda Networks, Inc.
43 | Google Inc.
44 | Stripe Inc.
45 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-sql-driver/mysql/appengine.go:
--------------------------------------------------------------------------------
1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2 | //
3 | // Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file,
7 | // You can obtain one at http://mozilla.org/MPL/2.0/.
8 |
9 | // +build appengine
10 |
11 | package mysql
12 |
13 | import (
14 | "appengine/cloudsql"
15 | )
16 |
17 | func init() {
18 | RegisterDial("cloudsql", cloudsql.Dial)
19 | }
20 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-sql-driver/mysql/result.go:
--------------------------------------------------------------------------------
1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2 | //
3 | // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file,
7 | // You can obtain one at http://mozilla.org/MPL/2.0/.
8 |
9 | package mysql
10 |
11 | type mysqlResult struct {
12 | affectedRows int64
13 | insertId int64
14 | }
15 |
16 | func (res *mysqlResult) LastInsertId() (int64, error) {
17 | return res.insertId, nil
18 | }
19 |
20 | func (res *mysqlResult) RowsAffected() (int64, error) {
21 | return res.affectedRows, nil
22 | }
23 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/go-sql-driver/mysql/transaction.go:
--------------------------------------------------------------------------------
1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2 | //
3 | // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file,
7 | // You can obtain one at http://mozilla.org/MPL/2.0/.
8 |
9 | package mysql
10 |
11 | type mysqlTx struct {
12 | mc *mysqlConn
13 | }
14 |
15 | func (tx *mysqlTx) Commit() (err error) {
16 | if tx.mc == nil || tx.mc.netConn == nil {
17 | return ErrInvalidConn
18 | }
19 | err = tx.mc.exec("COMMIT")
20 | tx.mc = nil
21 | return
22 | }
23 |
24 | func (tx *mysqlTx) Rollback() (err error) {
25 | if tx.mc == nil || tx.mc.netConn == nil {
26 | return ErrInvalidConn
27 | }
28 | err = tx.mc.exec("ROLLBACK")
29 | tx.mc = nil
30 | return
31 | }
32 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | ---
2 | engines:
3 | gofmt:
4 | enabled: true
5 | govet:
6 | enabled: true
7 | golint:
8 | enabled: true
9 | ratings:
10 | paths:
11 | - "**.go"
12 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/.gitignore:
--------------------------------------------------------------------------------
1 | documents
2 | _book
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | ## Bug Report
4 |
5 | - Do a search on GitHub under Issues in case it has already been reported
6 | - Submit __executable script__ or failing test pull request that could demonstrates the issue is *MUST HAVE*
7 |
8 | ## Feature Request
9 |
10 | - Feature request with pull request is welcome
11 | - Or it won't be implemented until I (other developers) find it is helpful for my (their) daily work
12 |
13 | ## Pull Request
14 |
15 | - Prefer single commit pull request, that make the git history can be a bit easier to follow.
16 | - New features need to be covered with tests to make sure your code works as expected, and won't be broken by others in future
17 |
18 | ## Contributing to Documentation
19 |
20 | - You are welcome ;)
21 | - You can help improve the README by making them more coherent, consistent or readable, and add more godoc documents to make people easier to follow.
22 | - Blogs & Usage Guides & PPT also welcome, please add them to https://github.com/jinzhu/gorm/wiki/Guides
23 |
24 | ### Executable script template
25 |
26 | ```go
27 | package main
28 |
29 | import (
30 | _ "github.com/mattn/go-sqlite3"
31 | _ "github.com/go-sql-driver/mysql"
32 | _ "github.com/lib/pq"
33 | "github.com/jinzhu/gorm"
34 | )
35 |
36 | var db gorm.DB
37 |
38 | func init() {
39 | var err error
40 | db, err = gorm.Open("sqlite3", "test.db")
41 | // db, err := gorm.Open("postgres", "user=username dbname=password sslmode=disable")
42 | // db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True")
43 | if err != nil {
44 | panic(err)
45 | }
46 | db.LogMode(true)
47 | }
48 |
49 | func main() {
50 | // Your code
51 | }
52 | ```
53 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/License:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013-NOW Jinzhu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/README.md:
--------------------------------------------------------------------------------
1 | # GORM
2 |
3 | The fantastic ORM library for Golang, aims to be developer friendly.
4 |
5 | [](https://gitter.im/jinzhu/gorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6 | [](https://app.wercker.com/project/bykey/0cb7bb1039e21b74f8274941428e0921)
7 | [](https://godoc.org/github.com/jinzhu/gorm)
8 |
9 | ## Overview
10 |
11 | * Full-Featured ORM (almost)
12 | * Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism)
13 | * Callbacks (Before/After Create/Save/Update/Delete/Find)
14 | * Preloading (eager loading)
15 | * Transactions
16 | * Composite Primary Key
17 | * SQL Builder
18 | * Auto Migrations
19 | * Logger
20 | * Extendable, write Plugins based on GORM callbacks
21 | * Every feature comes with tests
22 | * Developer Friendly
23 |
24 | ## Getting Started
25 |
26 | * GORM Guides [jinzhu.github.com/gorm](https://jinzhu.github.io/gorm)
27 |
28 | ## Upgrading To V1.0
29 |
30 | * [CHANGELOG](https://jinzhu.github.io/gorm/changelog.html)
31 |
32 | # Author
33 |
34 | **jinzhu**
35 |
36 | *
37 | *
38 | *
39 |
40 | # Contributors
41 |
42 | https://github.com/jinzhu/gorm/graphs/contributors
43 |
44 | ## License
45 |
46 | Released under the [MIT License](https://github.com/jinzhu/gorm/blob/master/License).
47 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/dialects/mysql/mysql.go:
--------------------------------------------------------------------------------
1 | package mysql
2 |
3 | import _ "github.com/go-sql-driver/mysql"
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/dialects/postgres/postgres.go:
--------------------------------------------------------------------------------
1 | package postgres
2 |
3 | import (
4 | "database/sql"
5 | "database/sql/driver"
6 |
7 | _ "github.com/lib/pq"
8 | "github.com/lib/pq/hstore"
9 | )
10 |
11 | type Hstore map[string]*string
12 |
13 | // Value get value of Hstore
14 | func (h Hstore) Value() (driver.Value, error) {
15 | hstore := hstore.Hstore{Map: map[string]sql.NullString{}}
16 | if len(h) == 0 {
17 | return nil, nil
18 | }
19 |
20 | for key, value := range h {
21 | var s sql.NullString
22 | if value != nil {
23 | s.String = *value
24 | s.Valid = true
25 | }
26 | hstore.Map[key] = s
27 | }
28 | return hstore.Value()
29 | }
30 |
31 | // Scan scan value into Hstore
32 | func (h *Hstore) Scan(value interface{}) error {
33 | hstore := hstore.Hstore{}
34 |
35 | if err := hstore.Scan(value); err != nil {
36 | return err
37 | }
38 |
39 | if len(hstore.Map) == 0 {
40 | return nil
41 | }
42 |
43 | *h = Hstore{}
44 | for k := range hstore.Map {
45 | if hstore.Map[k].Valid {
46 | s := hstore.Map[k].String
47 | (*h)[k] = &s
48 | } else {
49 | (*h)[k] = nil
50 | }
51 | }
52 |
53 | return nil
54 | }
55 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/dialects/sqlite/sqlite.go:
--------------------------------------------------------------------------------
1 | package sqlite
2 |
3 | import _ "github.com/mattn/go-sqlite3"
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/errors.go:
--------------------------------------------------------------------------------
1 | package gorm
2 |
3 | import (
4 | "errors"
5 | "strings"
6 | )
7 |
8 | var (
9 | // ErrRecordNotFound record not found error, happens when haven't find any matched data when looking up with a struct
10 | ErrRecordNotFound = errors.New("record not found")
11 | // ErrInvalidSQL invalid SQL error, happens when you passed invalid SQL
12 | ErrInvalidSQL = errors.New("invalid SQL")
13 | // ErrInvalidTransaction invalid transaction when you are trying to `Commit` or `Rollback`
14 | ErrInvalidTransaction = errors.New("no valid transaction")
15 | // ErrCantStartTransaction can't start transaction when you are trying to start one with `Begin`
16 | ErrCantStartTransaction = errors.New("can't start transaction")
17 | // ErrUnaddressable unaddressable value
18 | ErrUnaddressable = errors.New("using unaddressable value")
19 | )
20 |
21 | type errorsInterface interface {
22 | GetErrors() []error
23 | }
24 |
25 | // Errors contains all happened errors
26 | type Errors struct {
27 | errors []error
28 | }
29 |
30 | // GetErrors get all happened errors
31 | func (errs Errors) GetErrors() []error {
32 | return errs.errors
33 | }
34 |
35 | // Add add an error
36 | func (errs *Errors) Add(err error) {
37 | if errors, ok := err.(errorsInterface); ok {
38 | for _, err := range errors.GetErrors() {
39 | errs.Add(err)
40 | }
41 | } else {
42 | for _, e := range errs.errors {
43 | if err == e {
44 | return
45 | }
46 | }
47 | errs.errors = append(errs.errors, err)
48 | }
49 | }
50 |
51 | // Error format happened errors
52 | func (errs Errors) Error() string {
53 | var errors = []string{}
54 | for _, e := range errs.errors {
55 | errors = append(errors, e.Error())
56 | }
57 | return strings.Join(errors, "; ")
58 | }
59 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/field.go:
--------------------------------------------------------------------------------
1 | package gorm
2 |
3 | import (
4 | "database/sql"
5 | "errors"
6 | "fmt"
7 | "reflect"
8 | )
9 |
10 | // Field model field definition
11 | type Field struct {
12 | *StructField
13 | IsBlank bool
14 | Field reflect.Value
15 | }
16 |
17 | // Set set a value to the field
18 | func (field *Field) Set(value interface{}) (err error) {
19 | if !field.Field.IsValid() {
20 | return errors.New("field value not valid")
21 | }
22 |
23 | if !field.Field.CanAddr() {
24 | return ErrUnaddressable
25 | }
26 |
27 | reflectValue, ok := value.(reflect.Value)
28 | if !ok {
29 | reflectValue = reflect.ValueOf(value)
30 | }
31 |
32 | fieldValue := field.Field
33 | if reflectValue.IsValid() {
34 | if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
35 | fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
36 | } else {
37 | if fieldValue.Kind() == reflect.Ptr {
38 | if fieldValue.IsNil() {
39 | fieldValue.Set(reflect.New(field.Struct.Type.Elem()))
40 | }
41 | fieldValue = fieldValue.Elem()
42 | }
43 |
44 | if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
45 | fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
46 | } else if scanner, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
47 | err = scanner.Scan(reflectValue.Interface())
48 | } else {
49 | err = fmt.Errorf("could not convert argument of field %s from %s to %s", field.Name, reflectValue.Type(), fieldValue.Type())
50 | }
51 | }
52 | } else {
53 | field.Field.Set(reflect.Zero(field.Field.Type()))
54 | }
55 |
56 | field.IsBlank = isBlank(field.Field)
57 | return err
58 | }
59 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/interface.go:
--------------------------------------------------------------------------------
1 | package gorm
2 |
3 | import "database/sql"
4 |
5 | type sqlCommon interface {
6 | Exec(query string, args ...interface{}) (sql.Result, error)
7 | Prepare(query string) (*sql.Stmt, error)
8 | Query(query string, args ...interface{}) (*sql.Rows, error)
9 | QueryRow(query string, args ...interface{}) *sql.Row
10 | }
11 |
12 | type sqlDb interface {
13 | Begin() (*sql.Tx, error)
14 | }
15 |
16 | type sqlTx interface {
17 | Commit() error
18 | Rollback() error
19 | }
20 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/model.go:
--------------------------------------------------------------------------------
1 | package gorm
2 |
3 | import "time"
4 |
5 | // Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models
6 | // type User struct {
7 | // gorm.Model
8 | // }
9 | type Model struct {
10 | ID uint `gorm:"primary_key"`
11 | CreatedAt time.Time
12 | UpdatedAt time.Time
13 | DeletedAt *time.Time `sql:"index"`
14 | }
15 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/gorm/test_all.sh:
--------------------------------------------------------------------------------
1 | dialects=("postgres" "mysql" "sqlite")
2 |
3 | for dialect in "${dialects[@]}" ; do
4 | GORM_DIALECT=${dialect} go test
5 | done
6 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/inflection/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 - Jinzhu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/jinzhu/inflection/README.md:
--------------------------------------------------------------------------------
1 | Inflection
2 | =========
3 |
4 | Inflection pluralizes and singularizes English nouns
5 |
6 | ## Basic Usage
7 |
8 | ```go
9 | inflection.Plural("person") => "people"
10 | inflection.Plural("Person") => "People"
11 | inflection.Plural("PERSON") => "PEOPLE"
12 | inflection.Plural("bus") => "buses"
13 | inflection.Plural("BUS") => "BUSES"
14 | inflection.Plural("Bus") => "Buses"
15 |
16 | inflection.Singularize("people") => "person"
17 | inflection.Singularize("People") => "Person"
18 | inflection.Singularize("PEOPLE") => "PERSON"
19 | inflection.Singularize("buses") => "bus"
20 | inflection.Singularize("BUSES") => "BUS"
21 | inflection.Singularize("Buses") => "Bus"
22 |
23 | inflection.Plural("FancyPerson") => "FancyPeople"
24 | inflection.Singularize("FancyPeople") => "FancyPerson"
25 | ```
26 |
27 | ## Register Rules
28 |
29 | Standard rules are from Rails's ActiveSupport (https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflections.rb)
30 |
31 | If you want to register more rules, follow:
32 |
33 | ```
34 | inflection.AddUncountable("fish")
35 | inflection.AddIrregular("person", "people")
36 | inflection.AddPlural("(bu)s$", "${1}ses") # "bus" => "buses" / "BUS" => "BUSES" / "Bus" => "Buses"
37 | inflection.AddSingular("(bus)(es)?$", "${1}") # "buses" => "bus" / "Buses" => "Bus" / "BUSES" => "BUS"
38 | ```
39 |
40 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/binding/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Jeremy Saenz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/binding/wercker.yml:
--------------------------------------------------------------------------------
1 | box: wercker/golang@1.1.1
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Jeremy Saenz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/admin/index.tmpl:
--------------------------------------------------------------------------------
1 | Admin {{.}}
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/another_layout.tmpl:
--------------------------------------------------------------------------------
1 | another head
2 | {{ yield }}
3 | another foot
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/content.tmpl:
--------------------------------------------------------------------------------
1 | {{ . }}
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/current_layout.tmpl:
--------------------------------------------------------------------------------
1 | {{ current }} head
2 | {{ yield }}
3 | {{ current }} foot
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/delims.tmpl:
--------------------------------------------------------------------------------
1 | Hello {[{.}]}
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/hello.tmpl:
--------------------------------------------------------------------------------
1 | Hello {{.}}
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/hypertext.html:
--------------------------------------------------------------------------------
1 | Hypertext!
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/basic/layout.tmpl:
--------------------------------------------------------------------------------
1 | head
2 | {{ yield }}
3 | foot
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/fixtures/custom_funcs/index.tmpl:
--------------------------------------------------------------------------------
1 | {{ myCustomFunc }}
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/martini-contrib/render/wercker.yml:
--------------------------------------------------------------------------------
1 | box: wercker/golang@1.1.1
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/oxtoacart/bpool/bpool.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package bpool implements leaky pools of byte arrays and Buffers as bounded
3 | channels. It is based on the leaky buffer example from the Effective Go
4 | documentation: http://golang.org/doc/effective_go.html#leaky_buffer
5 | */
6 | package bpool
7 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/oxtoacart/bpool/bufferpool.go:
--------------------------------------------------------------------------------
1 | package bpool
2 |
3 | import (
4 | "bytes"
5 | )
6 |
7 | // BufferPool implements a pool of bytes.Buffers in the form of a bounded
8 | // channel.
9 | type BufferPool struct {
10 | c chan *bytes.Buffer
11 | }
12 |
13 | // NewBufferPool creates a new BufferPool bounded to the given size.
14 | func NewBufferPool(size int) (bp *BufferPool) {
15 | return &BufferPool{
16 | c: make(chan *bytes.Buffer, size),
17 | }
18 | }
19 |
20 | // Get gets a Buffer from the BufferPool, or creates a new one if none are
21 | // available in the pool.
22 | func (bp *BufferPool) Get() (b *bytes.Buffer) {
23 | select {
24 | case b = <-bp.c:
25 | // reuse existing buffer
26 | default:
27 | // create new buffer
28 | b = bytes.NewBuffer([]byte{})
29 | }
30 | return
31 | }
32 |
33 | // Put returns the given Buffer to the BufferPool.
34 | func (bp *BufferPool) Put(b *bytes.Buffer) {
35 | b.Reset()
36 | select {
37 | case bp.c <- b:
38 | default: // Discard the buffer if the pool is full.
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/oxtoacart/bpool/bytepool.go:
--------------------------------------------------------------------------------
1 | package bpool
2 |
3 | // BytePool implements a leaky pool of []byte in the form of a bounded
4 | // channel.
5 | type BytePool struct {
6 | c chan []byte
7 | w int
8 | }
9 |
10 | // NewBytePool creates a new BytePool bounded to the given maxSize, with new
11 | // byte arrays sized based on width.
12 | func NewBytePool(maxSize int, width int) (bp *BytePool) {
13 | return &BytePool{
14 | c: make(chan []byte, maxSize),
15 | w: width,
16 | }
17 | }
18 |
19 | // Get gets a []byte from the BytePool, or creates a new one if none are
20 | // available in the pool.
21 | func (bp *BytePool) Get() (b []byte) {
22 | select {
23 | case b = <-bp.c:
24 | // reuse existing buffer
25 | default:
26 | // create new buffer
27 | b = make([]byte, bp.w)
28 | }
29 | return
30 | }
31 |
32 | // Put returns the given Buffer to the BytePool.
33 | func (bp *BytePool) Put(b []byte) {
34 | select {
35 | case bp.c <- b:
36 | // buffer went back into pool
37 | default:
38 | // buffer didn't go back into pool, just discard
39 | }
40 | }
41 |
42 | // Width returns the width of the byte arrays in this pool.
43 | func (bp *BytePool) Width() (n int) {
44 | return bp.w
45 | }
46 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/pborman/uuid/CONTRIBUTORS:
--------------------------------------------------------------------------------
1 | Paul Borman
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/pborman/uuid/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009,2014 Google Inc. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above
10 | copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the
12 | distribution.
13 | * Neither the name of Google Inc. nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/pborman/uuid/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // The uuid package generates and inspects UUIDs.
6 | //
7 | // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services.
8 | package uuid
9 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/pborman/uuid/json.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package uuid
6 |
7 | import "errors"
8 |
9 | func (u UUID) MarshalJSON() ([]byte, error) {
10 | if len(u) == 0 {
11 | return []byte(`""`), nil
12 | }
13 | return []byte(`"` + u.String() + `"`), nil
14 | }
15 |
16 | func (u *UUID) UnmarshalJSON(data []byte) error {
17 | if len(data) == 0 || string(data) == `""` {
18 | return nil
19 | }
20 | if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
21 | return errors.New("invalid UUID format")
22 | }
23 | data = data[1 : len(data)-1]
24 | uu := Parse(string(data))
25 | if uu == nil {
26 | return errors.New("invalid UUID format")
27 | }
28 | *u = uu
29 | return nil
30 | }
31 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/pborman/uuid/sql.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package uuid
6 |
7 | import (
8 | "errors"
9 | "fmt"
10 | )
11 |
12 | // Scan implements sql.Scanner so UUIDs can be read from databases transparently
13 | // Currently, database types that map to string and []byte are supported. Please
14 | // consult database-specific driver documentation for matching types.
15 | func (uuid *UUID) Scan(src interface{}) error {
16 | switch src.(type) {
17 | case string:
18 | // see uuid.Parse for required string format
19 | parsed := Parse(src.(string))
20 |
21 | if parsed == nil {
22 | return errors.New("Scan: invalid UUID format")
23 | }
24 |
25 | *uuid = parsed
26 | case []byte:
27 | // assumes a simple slice of bytes, just check validity and store
28 | u := UUID(src.([]byte))
29 |
30 | if u.Variant() == Invalid {
31 | return errors.New("Scan: invalid UUID format")
32 | }
33 |
34 | *uuid = u
35 | default:
36 | return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
37 | }
38 |
39 | return nil
40 | }
41 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/pborman/uuid/version1.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package uuid
6 |
7 | import (
8 | "encoding/binary"
9 | )
10 |
11 | // NewUUID returns a Version 1 UUID based on the current NodeID and clock
12 | // sequence, and the current time. If the NodeID has not been set by SetNodeID
13 | // or SetNodeInterface then it will be set automatically. If the NodeID cannot
14 | // be set NewUUID returns nil. If clock sequence has not been set by
15 | // SetClockSequence then it will be set automatically. If GetTime fails to
16 | // return the current NewUUID returns nil.
17 | func NewUUID() UUID {
18 | if nodeID == nil {
19 | SetNodeInterface("")
20 | }
21 |
22 | now, seq, err := GetTime()
23 | if err != nil {
24 | return nil
25 | }
26 |
27 | uuid := make([]byte, 16)
28 |
29 | time_low := uint32(now & 0xffffffff)
30 | time_mid := uint16((now >> 32) & 0xffff)
31 | time_hi := uint16((now >> 48) & 0x0fff)
32 | time_hi |= 0x1000 // Version 1
33 |
34 | binary.BigEndian.PutUint32(uuid[0:], time_low)
35 | binary.BigEndian.PutUint16(uuid[4:], time_mid)
36 | binary.BigEndian.PutUint16(uuid[6:], time_hi)
37 | binary.BigEndian.PutUint16(uuid[8:], seq)
38 | copy(uuid[10:], nodeID)
39 |
40 | return uuid
41 | }
42 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/pborman/uuid/version4.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package uuid
6 |
7 | // Random returns a Random (Version 4) UUID or panics.
8 | //
9 | // The strength of the UUIDs is based on the strength of the crypto/rand
10 | // package.
11 | //
12 | // A note about uniqueness derived from from the UUID Wikipedia entry:
13 | //
14 | // Randomly generated UUIDs have 122 random bits. One's annual risk of being
15 | // hit by a meteorite is estimated to be one chance in 17 billion, that
16 | // means the probability is about 0.00000000006 (6 × 10−11),
17 | // equivalent to the odds of creating a few tens of trillions of UUIDs in a
18 | // year and having one duplicate.
19 | func NewRandom() UUID {
20 | uuid := make([]byte, 16)
21 | randomBits([]byte(uuid))
22 | uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
23 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
24 | return uuid
25 | }
26 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/robfig/cron/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/robfig/cron/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/robfig/cron/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2012 Rob Figueiredo
2 | All Rights Reserved.
3 |
4 | MIT LICENSE
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/robfig/cron/README.md:
--------------------------------------------------------------------------------
1 | [](http://godoc.org/github.com/robfig/cron)
2 | [](https://travis-ci.org/robfig/cron)
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/robfig/cron/constantdelay.go:
--------------------------------------------------------------------------------
1 | package cron
2 |
3 | import "time"
4 |
5 | // ConstantDelaySchedule represents a simple recurring duty cycle, e.g. "Every 5 minutes".
6 | // It does not support jobs more frequent than once a second.
7 | type ConstantDelaySchedule struct {
8 | Delay time.Duration
9 | }
10 |
11 | // Every returns a crontab Schedule that activates once every duration.
12 | // Delays of less than a second are not supported (will round up to 1 second).
13 | // Any fields less than a Second are truncated.
14 | func Every(duration time.Duration) ConstantDelaySchedule {
15 | if duration < time.Second {
16 | duration = time.Second
17 | }
18 | return ConstantDelaySchedule{
19 | Delay: duration - time.Duration(duration.Nanoseconds())%time.Second,
20 | }
21 | }
22 |
23 | // Next returns the next time this should be run.
24 | // This rounds so that the next activation time will be on the second.
25 | func (schedule ConstantDelaySchedule) Next(t time.Time) time.Time {
26 | return t.Add(schedule.Delay - time.Duration(t.Nanosecond())*time.Nanosecond)
27 | }
28 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/streadway/amqp/.gitignore:
--------------------------------------------------------------------------------
1 | spec/spec
2 | examples/simple-consumer/simple-consumer
3 | examples/simple-producer/simple-producer
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/streadway/amqp/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - 1.1
5 | - 1.4
6 | - 1.5
7 |
8 | services:
9 | - rabbitmq
10 |
11 | env:
12 | - AMQP_URL=amqp://guest:guest@127.0.0.1:5672/ GOMAXPROCS=2
13 |
14 | script: go test -v -tags integration ./...
15 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/streadway/amqp/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | Redistributions in binary form must reproduce the above copyright notice, this
11 | list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/streadway/amqp/auth.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 | // Source code and contact info at http://github.com/streadway/amqp
5 |
6 | package amqp
7 |
8 | import (
9 | "fmt"
10 | )
11 |
12 | // Authentication interface provides a means for different SASL authentication
13 | // mechanisms to be used during connection tuning.
14 | type Authentication interface {
15 | Mechanism() string
16 | Response() string
17 | }
18 |
19 | // PlainAuth is a similar to Basic Auth in HTTP.
20 | type PlainAuth struct {
21 | Username string
22 | Password string
23 | }
24 |
25 | func (me *PlainAuth) Mechanism() string {
26 | return "PLAIN"
27 | }
28 |
29 | func (me *PlainAuth) Response() string {
30 | return fmt.Sprintf("\000%s\000%s", me.Username, me.Password)
31 | }
32 |
33 | // Finds the first mechanism preferred by the client that the server supports.
34 | func pickSASLMechanism(client []Authentication, serverMechanisms []string) (auth Authentication, ok bool) {
35 | for _, auth = range client {
36 | for _, mech := range serverMechanisms {
37 | if auth.Mechanism() == mech {
38 | return auth, true
39 | }
40 | }
41 | }
42 |
43 | return
44 | }
45 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/streadway/amqp/fuzz.go:
--------------------------------------------------------------------------------
1 | // +build gofuzz
2 | package amqp
3 |
4 | import "bytes"
5 |
6 | func Fuzz(data []byte) int {
7 | r := reader{bytes.NewReader(data)}
8 | frame, err := r.ReadFrame()
9 | if err != nil {
10 | if frame != nil {
11 | panic("frame is not nil")
12 | }
13 | return 0
14 | }
15 | return 1
16 | }
17 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/streadway/amqp/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | go run spec/gen.go < spec/amqp0-9-1.stripped.extended.xml | gofmt > spec091.go
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/README.md:
--------------------------------------------------------------------------------
1 | # codecgen tool
2 |
3 | Generate is given a list of *.go files to parse, and an output file (fout),
4 | codecgen will create an output file __file.go__ which
5 | contains `codec.Selfer` implementations for the named types found
6 | in the files parsed.
7 |
8 | Using codecgen is very straightforward.
9 |
10 | **Download and install the tool**
11 |
12 | `go get -u github.com/ugorji/go/codec/codecgen`
13 |
14 | **Run the tool on your files**
15 |
16 | The command line format is:
17 |
18 | `codecgen [options] (-o outfile) (infile ...)`
19 |
20 | ```sh
21 | % codecgen -?
22 | Usage of codecgen:
23 | -c="github.com/ugorji/go/codec": codec path
24 | -o="": out file
25 | -r=".*": regex for type name to match
26 | -rt="": tags for go run
27 | -t="": build tag to put in file
28 | -u=false: Use unsafe, e.g. to avoid unnecessary allocation on []byte->string
29 | -x=false: keep temp file
30 |
31 | % codecgen -o values_codecgen.go values.go values2.go moretypedefs.go
32 | ```
33 |
34 | Please see the [blog article](http://ugorji.net/blog/go-codecgen)
35 | for more information on how to use the tool.
36 |
37 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/z.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | const genCodecPath = "github.com/ugorji/go/codec"
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.not.go:
--------------------------------------------------------------------------------
1 | // +build notfastpath
2 |
3 | package codec
4 |
5 | import "reflect"
6 |
7 | // The generated fast-path code is very large, and adds a few seconds to the build time.
8 | // This causes test execution, execution of small tools which use codec, etc
9 | // to take a long time.
10 | //
11 | // To mitigate, we now support the notfastpath tag.
12 | // This tag disables fastpath during build, allowing for faster build, test execution,
13 | // short-program runs, etc.
14 |
15 | func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { return false }
16 | func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { return false }
17 | func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
18 | func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { return false }
19 |
20 | type fastpathT struct{}
21 | type fastpathE struct {
22 | rtid uintptr
23 | rt reflect.Type
24 | encfn func(*encFnInfo, reflect.Value)
25 | decfn func(*decFnInfo, reflect.Value)
26 | }
27 | type fastpathA [0]fastpathE
28 |
29 | func (x fastpathA) index(rtid uintptr) int { return -1 }
30 |
31 | var fastpathAV fastpathA
32 | var fastpathTV fastpathT
33 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_not_unsafe.go:
--------------------------------------------------------------------------------
1 | //+build !unsafe
2 |
3 | // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
4 | // Use of this source code is governed by a MIT license found in the LICENSE file.
5 |
6 | package codec
7 |
8 | // stringView returns a view of the []byte as a string.
9 | // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
10 | // In regular safe mode, it is an allocation and copy.
11 | func stringView(v []byte) string {
12 | return string(v)
13 | }
14 |
15 | // bytesView returns a view of the string as a []byte.
16 | // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
17 | // In regular safe mode, it is an allocation and copy.
18 | func bytesView(v string) []byte {
19 | return []byte(v)
20 | }
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go:
--------------------------------------------------------------------------------
1 | //+build unsafe
2 |
3 | // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
4 | // Use of this source code is governed by a MIT license found in the LICENSE file.
5 |
6 | package codec
7 |
8 | import (
9 | "unsafe"
10 | )
11 |
12 | // This file has unsafe variants of some helper methods.
13 |
14 | type unsafeString struct {
15 | Data uintptr
16 | Len int
17 | }
18 |
19 | type unsafeBytes struct {
20 | Data uintptr
21 | Len int
22 | Cap int
23 | }
24 |
25 | // stringView returns a view of the []byte as a string.
26 | // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
27 | // In regular safe mode, it is an allocation and copy.
28 | func stringView(v []byte) string {
29 | if len(v) == 0 {
30 | return ""
31 | }
32 | x := unsafeString{uintptr(unsafe.Pointer(&v[0])), len(v)}
33 | return *(*string)(unsafe.Pointer(&x))
34 | }
35 |
36 | // bytesView returns a view of the string as a []byte.
37 | // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
38 | // In regular safe mode, it is an allocation and copy.
39 | func bytesView(v string) []byte {
40 | if len(v) == 0 {
41 | return zeroByteSlice
42 | }
43 | x := unsafeBytes{uintptr(unsafe.Pointer(&v)), len(v), len(v)}
44 | return *(*[]byte)(unsafe.Pointer(&x))
45 | }
46 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.go:
--------------------------------------------------------------------------------
1 | package codec
2 |
3 | //go:generate bash prebuild.sh
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build go1.5
6 |
7 | package ctxhttp
8 |
9 | import "net/http"
10 |
11 | func canceler(client *http.Client, req *http.Request) func() {
12 | ch := make(chan struct{})
13 | req.Cancel = ch
14 |
15 | return func() {
16 | close(ch)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build !go1.5
6 |
7 | package ctxhttp
8 |
9 | import "net/http"
10 |
11 | type requestCanceler interface {
12 | CancelRequest(*http.Request)
13 | }
14 |
15 | func canceler(client *http.Client, req *http.Request) func() {
16 | rc, ok := client.Transport.(requestCanceler)
17 | if !ok {
18 | return func() {}
19 | }
20 | return func() {
21 | rc.CancelRequest(req)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/.bzrignore:
--------------------------------------------------------------------------------
1 | _*
2 | [856].out
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/LICENSE:
--------------------------------------------------------------------------------
1 | mgo - MongoDB driver for Go
2 |
3 | Copyright (c) 2010-2013 - Gustavo Niemeyer
4 |
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/Makefile:
--------------------------------------------------------------------------------
1 | startdb:
2 | @testdb/setup.sh start
3 |
4 | stopdb:
5 | @testdb/setup.sh stop
6 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/bson/LICENSE:
--------------------------------------------------------------------------------
1 | BSON library for Go
2 |
3 | Copyright (c) 2010-2012 - Gustavo Niemeyer
4 |
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/doc.go:
--------------------------------------------------------------------------------
1 | // Package mgo offers a rich MongoDB driver for Go.
2 | //
3 | // Details about the mgo project (pronounced as "mango") are found
4 | // in its web page:
5 | //
6 | // http://labix.org/mgo
7 | //
8 | // Usage of the driver revolves around the concept of sessions. To
9 | // get started, obtain a session using the Dial function:
10 | //
11 | // session, err := mgo.Dial(url)
12 | //
13 | // This will establish one or more connections with the cluster of
14 | // servers defined by the url parameter. From then on, the cluster
15 | // may be queried with multiple consistency rules (see SetMode) and
16 | // documents retrieved with statements such as:
17 | //
18 | // c := session.DB(database).C(collection)
19 | // err := c.Find(query).One(&result)
20 | //
21 | // New sessions are typically created by calling session.Copy on the
22 | // initial session obtained at dial time. These new sessions will share
23 | // the same cluster information and connection cache, and may be easily
24 | // handed into other methods and functions for organizing logic.
25 | // Every session created must have its Close method called at the end
26 | // of its life time, so its resources may be put back in the pool or
27 | // collected, depending on the case.
28 | //
29 | // For more details, see the documentation for the types and methods.
30 | //
31 | package mgo
32 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/saslimpl.go:
--------------------------------------------------------------------------------
1 | //+build sasl
2 |
3 | package mgo
4 |
5 | import (
6 | "labix.org/v2/mgo/sasl"
7 | )
8 |
9 | func saslNew(cred Credential, host string) (saslStepper, error) {
10 | return sasl.New(cred.Username, cred.Password, cred.Mechanism, cred.Service, host)
11 | }
12 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/saslstub.go:
--------------------------------------------------------------------------------
1 | //+build !sasl
2 |
3 | package mgo
4 |
5 | import (
6 | "fmt"
7 | )
8 |
9 | func saslNew(cred Credential, host string) (saslStepper, error) {
10 | return nil, fmt.Errorf("SASL support not enabled during build (-tags sasl)")
11 | }
12 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/testdb/dropall.js:
--------------------------------------------------------------------------------
1 |
2 | var ports = [40001, 40002, 40011, 40012, 40013, 40021, 40022, 40023, 40041, 40101, 40102, 40103, 40201, 40202, 40203]
3 | var auth = [40002, 40103, 40203, 40031]
4 |
5 | for (var i in ports) {
6 | var port = ports[i]
7 | var server = "localhost:" + port
8 | var mongo = new Mongo("localhost:" + port)
9 | var admin = mongo.getDB("admin")
10 |
11 | for (var j in auth) {
12 | if (auth[j] == port) {
13 | admin.auth("root", "rapadura")
14 | break
15 | }
16 | }
17 | var result = admin.runCommand({"listDatabases": 1})
18 | // Why is the command returning undefined!?
19 | while (typeof result.databases == "undefined") {
20 | print("dropall.js: listing databases of :" + port + " got:", result)
21 | result = admin.runCommand({"listDatabases": 1})
22 | }
23 | var dbs = result.databases
24 | for (var j = 0; j != dbs.length; j++) {
25 | var db = dbs[j]
26 | switch (db.name) {
27 | case "admin":
28 | case "local":
29 | case "config":
30 | break
31 | default:
32 | mongo.getDB(db.name).dropDatabase()
33 | }
34 | }
35 | }
36 |
37 | // vim:ts=4:sw=4:et
38 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/testdb/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 |
3 | start() {
4 | mkdir _testdb
5 | cd _testdb
6 | mkdir db1 db2 rs1a rs1b rs1c rs2a rs2b rs2c rs3a rs3b rs3c rs4a cfg1 cfg2 cfg3
7 | ln -s ../testdb/supervisord.conf supervisord.conf
8 | echo keyfile > keyfile
9 | chmod 600 keyfile
10 | echo "Running supervisord..."
11 | supervisord || ( echo "Supervisord failed executing ($?)" && exit 1 )
12 | COUNT=$(grep '^\[program' supervisord.conf | wc -l)
13 | echo "Supervisord is up, starting $COUNT processes..."
14 | for i in $(seq 10); do
15 | RUNNING=$(supervisorctl status | grep RUNNING | wc -l)
16 | echo "$RUNNING processes running..."
17 | if [ x$COUNT = x$RUNNING ]; then
18 | echo "Running setup.js with mongo..."
19 | mongo --nodb ../testdb/init.js
20 | exit 0
21 | fi
22 | sleep 1
23 | done
24 | echo "Failed to start all processes. Check out what's up at $PWD now!"
25 | exit 1
26 | }
27 |
28 | stop() {
29 | if [ -d _testdb ]; then
30 | echo "Shutting down test cluster..."
31 | (cd _testdb && supervisorctl shutdown)
32 | rm -rf _testdb
33 | fi
34 | }
35 |
36 |
37 | if [ ! -f suite_test.go ]; then
38 | echo "This script must be run from within the source directory."
39 | exit 1
40 | fi
41 |
42 | case "$1" in
43 |
44 | start)
45 | start
46 | ;;
47 |
48 | stop)
49 | stop
50 | ;;
51 |
52 | esac
53 |
54 | # vim:ts=4:sw=4:et
55 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/labix.org/v2/mgo/txn/chaos.go:
--------------------------------------------------------------------------------
1 | package txn
2 |
3 | import (
4 | mrand "math/rand"
5 | "time"
6 | )
7 |
8 | var chaosEnabled = false
9 | var chaosSetting Chaos
10 |
11 | // Chaos holds parameters for the failure injection mechanism.
12 | type Chaos struct {
13 | // KillChance is the 0.0 to 1.0 chance that a given checkpoint
14 | // within the algorithm will raise an interruption that will
15 | // stop the procedure.
16 | KillChance float64
17 |
18 | // SlowdownChance is the 0.0 to 1.0 chance that a given checkpoint
19 | // within the algorithm will be delayed by Slowdown before
20 | // continuing.
21 | SlowdownChance float64
22 | Slowdown time.Duration
23 |
24 | // If Breakpoint is set, the above settings will only affect the
25 | // named breakpoint.
26 | Breakpoint string
27 | }
28 |
29 | // SetChaos sets the failure injection parameters to c.
30 | func SetChaos(c Chaos) {
31 | chaosSetting = c
32 | chaosEnabled = c.KillChance > 0 || c.SlowdownChance > 0
33 | }
34 |
35 | func chaos(bpname string) {
36 | if !chaosEnabled {
37 | return
38 | }
39 | switch chaosSetting.Breakpoint {
40 | case "", bpname:
41 | kc := chaosSetting.KillChance
42 | if kc > 0 && mrand.Intn(1000) < int(kc*1000) {
43 | panic(chaosError{})
44 | }
45 | if bpname == "insert" {
46 | return
47 | }
48 | sc := chaosSetting.SlowdownChance
49 | if sc > 0 && mrand.Intn(1000) < int(kc*1000) {
50 | time.Sleep(chaosSetting.Slowdown)
51 | }
52 | }
53 | }
54 |
55 | type chaosError struct{}
56 |
57 | func (f *flusher) handleChaos(err *error) {
58 | v := recover()
59 | if v == nil {
60 | return
61 | }
62 | if _, ok := v.(chaosError); ok {
63 | f.debugf("Killed by chaos!")
64 | *err = ErrChaos
65 | return
66 | }
67 | panic(v)
68 | }
69 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 PandoCloud
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/build/local/docker/base.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | SERVICES='etcd mysql redis mongo'
4 |
5 | echo "stopping all services..."
6 | docker stop `echo $SERVICES`
7 | docker rm `echo $SERVICES`
8 |
9 | echo "starting etcd..."
10 | docker run -d --name etcd elcolio/etcd
11 |
12 | echo "starting mysql..."
13 | docker run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
14 |
15 | echo "starting redis..."
16 | docker run -d --name redis redis
17 |
18 | echo "starting mongo..."
19 | docker run -d --name mongo mongo
20 |
--------------------------------------------------------------------------------
/build/local/linux/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # restore dependency packages.
4 | cd $GOPATH/src/github.com/PandoCloud/pando-cloud
5 | cp -r Godeps/_workspace/src/* $GOPATH/src
6 |
7 | # install binaries
8 | go install -v github.com/PandoCloud/pando-cloud/services/...
9 |
--------------------------------------------------------------------------------
/build/local/linux/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | killall -9 httpaccess registry apiprovider devicemanager controller mqttaccess
4 |
5 | # start services
6 | $GOPATH/bin/httpaccess -etcd http://localhost:2379 -httphost internal:443 -loglevel debug -usehttps -keyfile $GOPATH/src/github.com/PandoCloud/pando-cloud/pkg/server/testdata/key.pem -cafile $GOPATH/src/github.com/PandoCloud/pando-cloud/pkg/server/testdata/cert.pem &
7 | $GOPATH/bin/registry -etcd http://localhost:2379 -rpchost localhost:20034 -aeskey ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP -dbhost localhost -dbname PandoCloud -dbport 3306 -dbuser root -loglevel debug &
8 | $GOPATH/bin/apiprovider -etcd http://localhost:2379 -loglevel debug -httphost :8888 &
9 | $GOPATH/bin/devicemanager -etcd http://localhost:2379 -loglevel debug -rpchost localhost:20033 &
10 | $GOPATH/bin/controller -etcd http://localhost:2379 -loglevel debug -rpchost localhost:20032 &
11 | $GOPATH/bin/mqttaccess -etcd http://localhost:2379 -loglevel debug -rpchost localhost:20030 -tcphost internal:1883 -usetls -keyfile $GOPATH/src/github.com/PandoCloud/pando-cloud/pkg/server/testdata/key.pem -cafile $GOPATH/src/github.com/PandoCloud/pando-cloud/pkg/server/testdata/cert.pem &
12 |
13 | exit 0
14 |
--------------------------------------------------------------------------------
/docs/img/architecture.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ruizeng/pando-cloud/004f9ac1c98aeca5e8d8de5f410702e9c9eaf483/docs/img/architecture.jpeg
--------------------------------------------------------------------------------
/docs/zh-cn/api-doc/device.md:
--------------------------------------------------------------------------------
1 | # 设备接入API
2 |
3 | ## 概述
4 | 需要接入pando云平台的设备,都需要遵循pando物联网平台的接入流程和接入协议。设备相关api由设备代理(网关)向服务器发起,设备在第一次成功联网后第一时间向服务器注册自己的信息,设备通过设备登陆接口获取设备token。
5 |
6 | ## API列表
7 | ### 设备注册
8 | *请求方式*
9 | ```
10 | POST
11 | ```
12 | *请求URL*
13 | ```
14 | /v1/devices/registration
15 | ```
16 | *参数*
17 | ```
18 | 无
19 | ```
20 | *请求头*
21 | ```
22 | 无
23 | ```
24 | *请求内容*
25 | ```
26 | {
27 | // 产品key,平台分配给产品
28 | "product_key": "3d6few3ac31w7a6d3f...",
29 | // 设备序列号,设备唯一硬件标识,如mac地址
30 | "device_code": "4d3e2a5d3fff",
31 | // 网关版本
32 | "产品版本": "0.1.0"
33 | }
34 | ```
35 | *返回内容*
36 | ```
37 | {
38 | // 返回码
39 | "code": 0,
40 | // 正确或错误信息
41 | "message": "",
42 | // 如果成功,将返回设备id及设备密码
43 | "data": {
44 | // 设备id
45 | "device_id": 12324,
46 | // 设备密码
47 | "device_secret": "3d6few3ac31w7a6d3f",
48 | // 设备激活码,用来绑定设备
49 | "device_key": "34ffffffff",
50 | // 设备标识符
51 | "device_identifier": "64-64-fe4efe"
52 | }
53 | }
54 | ```
55 |
56 | ### 设备登录
57 | *请求方式*
58 | ```
59 | POST
60 | ```
61 | *请求URL*
62 | ```
63 | /v1/devices/authentication
64 | ```
65 | *参数*
66 | ```
67 | 无
68 | ```
69 | *请求头*
70 | ```
71 | 无
72 | ```
73 | *请求内容*
74 | ```
75 | {
76 | // 设备id
77 | "device_id": 123,
78 | // 设备密码
79 | "device_secret": "fsfwefewf23r2r32r23rfs",
80 | // 协议类型,不填写表示默认协议(mqtt)
81 | "protocol": "mqtt"
82 | }
83 | ```
84 | *返回内容*
85 | ```
86 | {
87 | //返回码
88 | "code": 0,
89 | //正确或错误信息
90 | "message": "",
91 | "data": {
92 | // 设备token,16个字节,经过hex编码
93 | "access_token": "3sffefefefefsf...",
94 | // 接入服务器地址+端口
95 | "access_addr": "ip:port"
96 | }
97 | }
98 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/config/product-json-config.md:
--------------------------------------------------------------------------------
1 | # 产品配置
2 | 平台采用JSON格式的字符串来描述产品支持的功能。提供JSON配置文件时请严格按照JSON的格式规范和本文档的格式规范,否则可能造成产品无法使用。
3 |
4 | ## 概要说明
5 | ### status
6 | 我们用`status`作为信息的描述参数。一个产品的功能,由`object`、`command`、`event`三组信息描述。
7 |
8 | ### object
9 | 对象。产品由若干个可复用的功能组件组成,这些组件称之为对象。一个对象描述了其包含的**状态**(`status`)的描述参数,如支持的数据类型和标签。
10 |
11 | ### command
12 | 命令。外界对产品本地信息处理提出的要求。可能含有一个或多个参数,并有优先级。
13 |
14 | ### event
15 | 事件。产品需要通知外界关注的、处理后的、有效信息。可能含有一个或多个参数,并有优先级。
16 |
17 | ## JSON格式说明
18 | 下面是一个完整的产品配置,注释中对相应字段的意义进行了说明。(**注意**:标准的json格式规范是不允许有注释的,如果你参考这份配置编辑配置文件,请删除所有`//`及其后的注释!)
19 |
20 | ```javascript
21 | {
22 | // objects是一个数组,包含至少一个object对象
23 | "objects": [{
24 | "no": 1, // 对象编号,需保证产品内唯一,设备端固件实现需对应
25 | "label": "atmosphere", // 对象标签,根据自己喜好给产品中的该对象取得别名
26 | "part": 1, // 部件编号,对象所述的子设备
27 | // status是一个数组,包含了该对象支持的信息的数据类型
28 | "status": [{
29 | "value_type": 8, // 值类型
30 | "name": "red" // 给该属性命的别名,方便区分,此例为三色灯的红色值,以下类似
31 | }, {
32 | "value_type": 8,
33 | "name": "humidity"
34 | }, {
35 | "value_type": 8,
36 | "name": "air-quality"
37 | }]
38 | }],
39 | // commands是一个数组,包含产品支持的命令列表,数组可以为空([])
40 | "commands": [{
41 | "no": 1, // 命令编号,产品内唯一,设备端固件实现需对应
42 | "name": "upgrade", // 命令名称
43 | "part": 1, // 部件编号
44 | "priority": 0, // 优先级,0-99,值越高,优先级越高
45 | // params是一个参数列表,描述参数的值类型和名称
46 | "params": [{
47 | "value_type": 12,
48 | "name": "url"
49 | }, {
50 | "value_type": 11,
51 | "name": "md5"
52 | }]
53 | }],
54 | // events是一个数组,包含产品支持的事件列表,可为空([])
55 | "events": [{
56 | "no": 1, // 事件编号,产品内唯一,设备端固件实现需对应
57 | "name": "alert", // 事件名称
58 | "part": 1, // 部件编号,所述的子设备
59 | "priority": 0, // 优先级,0-99,值越高,优先级越高
60 | "params": []
61 | }]
62 | }
63 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/contribution/work-flow.md:
--------------------------------------------------------------------------------
1 | # 贡献流程
2 |
3 | 欢迎参与Pando物联网平台的代码贡献!我们的代码全部托管在github并通过github进行协作开发。
4 |
5 | ## 流程
6 | 1. 从官方项目github地址Fork项目,并进行修改
7 | * 请Fork master分支而不是其他分支,因为其他分支经常变动
8 | * 请为分支起一个好理解的名字来描述你做的修改,分支名采用横线分割,如some-buf-fix
9 | * 你的分支应该只做某一个功能,如果需要实现多个功能,请拉取不同分支并分别提交
10 | * 确保代码符合我们的[Go语言编码规范](coding-standard.md)
11 | 2. 请尽量全面地测试你的代码,硬性要求如下:
12 | * 必须通过travis-ci的测试(目前为编译和单元测试)
13 | * 如果新功能或者代码,请添加完备的单元测试
14 | * 必须保证测试覆盖率不会明显下降(我们通过coverall进行测试覆盖率扫描)
15 | 3. 合并你的提交
16 | * 请通过rebase将多个提交合并为一个
17 | 4. 通过GitHub发起一个pull request
18 | * 请详细地描述此分支的修改
19 | * 项目keeper会对你的修改进行审核,并提出意见
20 | * 如果审核不通过,请重新按照要求修改后重新提交
21 | 5. 项目keeper将分支合入主干
--------------------------------------------------------------------------------
/docs/zh-cn/environment/golang.md:
--------------------------------------------------------------------------------
1 | # GoLang
2 | 本文档介绍如何安装Go语言环境。
3 |
4 | ## Ubuntu
5 |
6 | ### 1.下载Go二进制包:
7 |
8 | * [64位](http://www.golangtc.com/static/go/go1.5.1/go1.5.1.linux-amd64.tar.gz)
9 | * [32位](http://www.golangtc.com/static/go/go1.5.1/go1.5.1.linux-386.tar.gz)
10 |
11 | 在Ubuntu下,可以通过wget命令进行下载,如(64位):
12 |
13 | ```sh
14 | wget http://www.golangtc.com/static/go/go1.5.1/go1.5.1.linux-amd64.tar.gz
15 | ```
16 |
17 | > 注意,不要使用apt-get命令安装Go环境,否则安装的Go版本过低。
18 |
19 | ### 2. 解压
20 |
21 | 将下载的二进制包解压到任何喜欢的目录下,如`/usr/local`:
22 |
23 | ```sh
24 | sudo tar -C /usr/local -xzf go1.5.1.linux-amd64.tar.gz
25 | ```
26 |
27 | ### 3. 创建Go工程目录
28 |
29 | 创建一个目录作为Go工作目录,如:
30 |
31 | ```sh
32 | mkdir ~/golang
33 | ```
34 |
35 | ### 4. 配置环境变量
36 |
37 | 打开home下的bashrc,增加Go环境变量:
38 |
39 | ```sh
40 | vi ~/.bashrc
41 | ```
42 |
43 | 在最末尾添加:
44 |
45 | ```sh
46 | export GOROOT=/usr/local/go
47 | export GOPATH=~/golang
48 | export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
49 | ```
50 |
51 | ### 5. 加载环境变量
52 |
53 | ```sh
54 | source ~/.bashrc
55 | ```
56 |
57 | ### 6. 验证
58 |
59 | ```sh
60 | go version
61 | ```
62 | 如果能正常显示go版本号,则证明安装成功。
--------------------------------------------------------------------------------
/docs/zh-cn/quick-start/README.md:
--------------------------------------------------------------------------------
1 | # 快速开始
2 | 这里将介绍如何编译pando cloud,以及如何在自己的服务器或pc机上单机部署pando物联网云。
3 |
4 | * [Ubuntu](ubuntu.md):介绍如何在安装Ubuntu Linux操作系统的服务器或PC机上编译及部署服务。
5 | * [Docker](docker.md):介绍如何通过制作好的docker镜像部署服务。
--------------------------------------------------------------------------------
/docs/zh-cn/services/README.md:
--------------------------------------------------------------------------------
1 | # 服务部署指南
2 |
3 | Pando物联网云平台采用微服务架构。除了系统依赖的MySQL,MongoDB等开源服务,平台自身目前有以下几个服务组成:
4 |
5 | - **[registry](registry.md)**:维护平台全局配置和信息的服务。
6 | - **[devicemanager](devicemanager.md)**: 设备信息和设备状态维护。
7 | - **[controller](controller.md)**: 和设备进行信息交互的路由服务。
8 | - **[apiprovider](apiprovider.md)**: 为应用提供REST接口。
9 | - **[httpaccess](httpaccess.md)**: 设备API服务,提供设备登陆、注册等逻辑。
10 | - **[mqttaccess](mqttaccess.md)**:MQTT接入服务。
--------------------------------------------------------------------------------
/docs/zh-cn/services/apiprovider.md:
--------------------------------------------------------------------------------
1 | # apiprovider
2 |
3 | `apiprovider`服务为应用提供HTTP REST接口。
4 |
5 | ## 工作原理
6 | [应用接口文档](../api-doc/application.md)
7 |
8 | ## 启动参数
9 | * `-etcd` etcd服务的访问地址,必需参数。如`http://localhost:2379`,如果etcd是多副本部署,可以用分号隔开访问地址,如`http://192.168.0.2:2379;http://192.168.0.3:2379`。
10 | * `-rpchost` rpc服务访问地址,必需参数。该参数定义该服务对其他服务提供的rpc服务的监听地址。如`http://localhost:20034`。
11 | * `-httphost` HTTP服务地址,必须参数。格式为`ip:port`如`localhost:443`,为了安全考虑,建议最好只绑定内网ip和端口。如果需要外网访问,强烈建议开启https选项。
12 | * `-usehttps` 是否启动https服务,默认不启用。如果启用,则必须提供以下`cafile`和`keyfile`两个参数。
13 | * `-cafile` ssl加密证书的证书文件路径(pem格式)。
14 | * `-keyfile` ssl加密证书的密钥文件路径(pem格式)。
15 | * `-loglevel` 服务打印日志的级别,选填,如果没有指定则默认为`info`级别。
16 |
17 | > 说明:ssl证书和密钥的pem文件生成方法可以参考[这里](http://killeraction.iteye.com/blog/858325)
18 |
--------------------------------------------------------------------------------
/docs/zh-cn/services/controller.md:
--------------------------------------------------------------------------------
1 | # controller
2 |
3 | `controller`服务作为和设备进行信息交互时的控制节点,为访问设备提供路由服务,并接收设备上报的信息。
4 |
5 | ## 工作原理
6 | `controller`主要负责设备信息交互,具体分两种场景:
7 |
8 | * 当应用需要向设备发送信息时,`controller`会向`devicemanager` 查询当前设备的在线信息,并根据反馈的接入点,向接入服务器发送信息转发请求。
9 | * 当设备向平台发送数据时,`controller`会将数据存入MongoDB,如需通知应用则放入消息队列。
10 |
11 | ## 启动参数
12 | * `-etcd` etcd服务的访问地址,必需参数。如`http://localhost:2379`,如果etcd是多副本部署,可以用分号隔开访问地址,如`http://192.168.0.2:2379;http://192.168.0.3:2379`。
13 | * `-rpchost` rpc服务访问地址,必需参数。该参数定义该服务对其他服务提供的rpc服务的监听地址。如`http://localhost:20034`。
14 | * `-mongohost` MongoDB地址,可选参数。如果没有提供则为`localhost`,如果需要指定,格式为`ip:port`如`192.168.0.3:27017`。
15 | * `-loglevel` 服务打印日志的级别,选填,如果没有指定则默认为`info`级别。
--------------------------------------------------------------------------------
/docs/zh-cn/services/devicemanager.md:
--------------------------------------------------------------------------------
1 | # devicemanager
2 |
3 | `devicemanager`维护了设备的状态,如设备当前在哪台接入服务器接入,设备是否在线等。
4 |
5 | ## 工作原理
6 | `devicemanager`是无状态的,采用redis存储了设备的实时状态信息,并对外提供了rpc接口供其他服务查询设备的当前信息。
7 |
8 | ## 启动参数
9 | * `-etcd` etcd服务的访问地址,必需参数。如`http://localhost:2379`,如果etcd是多副本部署,可以用分号隔开访问地址,如`http://192.168.0.2:2379;http://192.168.0.3:2379`。
10 | * `-rpchost` rpc服务访问地址,必需参数。该参数定义该服务对其他服务提供的rpc服务的监听地址。如`http://localhost:20034`。
11 | * `-loglevel` 服务打印日志的级别,选填,如果没有指定则默认为`info`级别。
--------------------------------------------------------------------------------
/docs/zh-cn/services/httpaccess.md:
--------------------------------------------------------------------------------
1 | # httpaccess
2 |
3 | `httpaccess`服务提供了供设备注册、登录的HTTP[接口](../api-doc/device.md)。
4 |
5 | ## 启动参数
6 | * `-etcd` etcd服务的访问地址,必需参数。如`http://localhost:2379`,如果etcd是多副本部署,可以用分号隔开访问地址,如`http://192.168.0.2:2379;http://192.168.0.3:2379`。
7 | * `-httphost` HTTP服务地址,必须参数。格式为`ip:port`如`localhost:443`,强烈建议开启https选项。一般情况下绑定到外网的443端口(https默认端口)。
8 | * `-usehttps` 是否启动https服务,默认不启用。如果启用,则必须提供以下`cafile`和`keyfile`两个参数。如果需要pando设备连接,则必须启用,否则无法连接。
9 | * `-cafile` ssl加密证书的证书文件路径(pem格式)。
10 | * `-keyfile` ssl加密证书的密钥文件路径(pem格式)。
11 | * `-loglevel` 服务打印日志的级别,选填,如果没有指定则默认为`info`级别。
12 |
13 | > 说明:ssl证书和密钥的pem文件生成方法可以参考[这里](http://killeraction.iteye.com/blog/858325)
--------------------------------------------------------------------------------
/docs/zh-cn/services/mqttaccess.md:
--------------------------------------------------------------------------------
1 | # mqttaccess
2 |
3 | mqttaccess是支持mqtt协议的接入服务器,平台目前默认采用该协议。提供了tcp长连接连接设备,并对设备交互数据进行转发服务。
4 |
5 | ## 启动参数
6 |
7 | * `-etcd` etcd服务的访问地址,必需参数。如`http://localhost:2379`,如果etcd是多副本部署,可以用分号隔开访问地址,如`http://192.168.0.2:2379;http://192.168.0.3:2379`。
8 | * `-rpchost` rpc服务访问地址,必需参数。该参数定义该服务对其他服务提供的rpc服务的监听地址。如`http://localhost:20034`。
9 | * `-tcphost` tcp服务地址,必须参数。格式为`ip:port`如`localhost:1883`,一般绑定为外网ip加1883端口(mqtt默认端口)。
10 | * `-usetls` 是否启动ssl加密服务,默认不启用。如果启用,则必须提供以下`cafile`和`keyfile`两个参数。如果pando设备需接入,必须开启tls加密选项,否则无法接入。
11 | * `-cafile` ssl加密证书的证书文件路径(pem格式)。
12 | * `-keyfile` ssl加密证书的密钥文件路径(pem格式)。
13 | * `-loglevel` 服务打印日志的级别,选填,如果没有指定则默认为`info`级别。
14 |
15 | > 说明:ssl证书和密钥的pem文件生成方法可以参考[这里](http://killeraction.iteye.com/blog/858325)
--------------------------------------------------------------------------------
/docs/zh-cn/services/registry.md:
--------------------------------------------------------------------------------
1 | # registry
2 |
3 | `registry`服务负责维护平台的全局配置。
4 |
5 | ## 工作原理
6 | 该服务采用MySQL存储平台的配置和设备注册信息。
7 |
8 | `registry`服务是无状态的,在名为`PandoCloud`的库中维护了`application`, `vendor`, `product`以及`device`表,并为了加快访问速度提供了缓存机制。
9 |
10 | ## 启动参数列表
11 | * `-etcd` etcd服务的访问地址,必需参数。如`http://localhost:2379`,如果etcd是多副本部署,可以用分号隔开访问地址,如`http://192.168.0.2:2379;http://192.168.0.3:2379`。
12 | * `-rpchost` rpc服务访问地址,必需参数。该参数定义该服务对其他服务提供的rpc服务的监听地址。如`http://localhost:20034`。
13 | * `-aeskey` 用来生成KEY的aes加密密钥串,必须参数。该参数为32位的任意字符串,如`ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP`。该参数越随机越好。
14 | * `-dbhost` MySQL数据库的访问地址,选填,如果没有填写默认为`localhost`。
15 | * `-dbport` MySQL数据库的访问端口,选填,如果没有填写默认为`3306`。
16 | * `-dbuser` MySQL数据库的访问用户名,选填,如果没有填写默认为`root`。
17 | * `-dbpass` MySQL数据库的访问用户密码,选填,如果没有填写默认为空。
18 | * `-loglevel` 服务打印日志的级别,选填,如果没有指定则默认为`info`级别。
19 |
--------------------------------------------------------------------------------
/make_deps.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | rm -rf ./Godeps
4 | $GOPATH/bin/godep save ./...
5 |
--------------------------------------------------------------------------------
/pkg/README.md:
--------------------------------------------------------------------------------
1 | common libs and frameworks
2 |
--------------------------------------------------------------------------------
/pkg/cache/cache.go:
--------------------------------------------------------------------------------
1 | package cache
2 |
3 |
4 |
5 | //return status of chache
6 | type CacheStatus struct {
7 | Gets int64
8 | Hits int64
9 | MaxItemSize int
10 | CurrentSize int
11 | }
12 |
13 | //this is a interface which defines some common functions
14 | type Cache interface{
15 | Set(key string, value interface{})
16 | Get(key string) (interface{}, bool)
17 | Delete(key string)
18 | Status()(*CacheStatus)
19 | }
--------------------------------------------------------------------------------
/pkg/generator/key_gen_test.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestKeyGen(t *testing.T) {
8 | generator, err := NewKeyGenerator("INVALIDKEY")
9 | if err == nil {
10 | t.Error("should return error when key length is invalid")
11 | }
12 | testid := int64(10000)
13 | generator, err = NewKeyGenerator("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
14 | if err != nil {
15 | t.Fatal(err)
16 | }
17 | key, err := generator.GenRandomKey(testid)
18 | if err != nil {
19 | t.Error(err)
20 | }
21 | t.Log(key)
22 | id, err := generator.DecodeIdFromRandomKey(key)
23 | if err != nil {
24 | t.Error(err)
25 | }
26 | if id != testid {
27 | t.Errorf("wrong id %d, want %d", id, testid)
28 | }
29 |
30 | id, err = generator.DecodeIdFromRandomKey("")
31 | if err == nil {
32 | t.Error("decode id from random key should return error for empty key.")
33 | }
34 |
35 | id, err = generator.DecodeIdFromRandomKey("1111111111111111111111111111111111111111")
36 | if err == nil {
37 | t.Errorf("decode id from random key should return error for bad key : %s", "1111111111111111111111111111111111111111")
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/generator/password_gen.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "crypto/rand"
5 | "encoding/base64"
6 | )
7 |
8 | const (
9 | ranPasswordByteLength = 24
10 | )
11 |
12 | // gen random base64 encoded password
13 | func GenRandomPassword() (string, error) {
14 | ranbuf := make([]byte, ranPasswordByteLength)
15 | _, err := rand.Read(ranbuf)
16 | if err != nil {
17 | return "", err
18 | }
19 |
20 | return base64.StdEncoding.EncodeToString(ranbuf), nil
21 | }
22 |
--------------------------------------------------------------------------------
/pkg/generator/password_gen_test.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestPasswordGen(t *testing.T) {
8 | pass, err := GenRandomPassword()
9 | if err != nil {
10 | t.Error(err)
11 | }
12 | t.Log(pass)
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/generator/token_gen.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "crypto/rand"
5 | )
6 |
7 | const (
8 | ranTokendByteLength = 16
9 | )
10 |
11 | // gen random token bytes
12 | func GenRandomToken() ([]byte, error) {
13 | ranbuf := make([]byte, ranTokendByteLength)
14 | _, err := rand.Read(ranbuf)
15 | if err != nil {
16 | return nil, err
17 | }
18 |
19 | return ranbuf, nil
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/generator/token_gen_test.go:
--------------------------------------------------------------------------------
1 | package generator
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestTokenGen(t *testing.T) {
8 | pass, err := GenRandomToken()
9 | if err != nil {
10 | t.Error(err)
11 | }
12 | t.Log(pass)
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/models/application.go:
--------------------------------------------------------------------------------
1 | // application is app who will use the cloud api
2 | package models
3 |
4 | import (
5 | "time"
6 | )
7 |
8 | type Application struct {
9 | // inner id
10 | ID int32
11 | // App-Key for api
12 | AppKey string `sql:"type:varchar(200);not null;"`
13 | // App-Token for web hook
14 | AppToken string `sql:"type:varchar(200);not null;"`
15 | // Report Url for web hook
16 | ReportUrl string `sql:"type:varchar(200);not null;"`
17 | // name
18 | AppName string `sql:"type:varchar(200);"`
19 | // desc
20 | AppDescription string `sql:"type:text;"`
21 | // app domain which allows wildcard string like "*", "vendor/12", "product/10"
22 | AppDomain string `sql:"type:varchar(200);not null;"`
23 |
24 | CreatedAt time.Time
25 | UpdatedAt time.Time
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/models/device.go:
--------------------------------------------------------------------------------
1 | // device is a product instance, which is managed by our platform
2 | package models
3 |
4 | import (
5 | "time"
6 | )
7 |
8 | type Device struct {
9 | // inner id
10 | ID int64
11 | // which product the device belongs to
12 | ProductID int32
13 | // universal device identifier, generated from vendorid-productid-deviceserial
14 | DeviceIdentifier string `sql:"type:varchar(200);not null;unique;key"`
15 | // device secret which is auto generated by the platform
16 | DeviceSecret string `sql:"type:varchar(200);not null;"`
17 | // device key is used to auth a device
18 | DeviceKey string `sql:"type:varchar(200);not null;key;"`
19 | // device name
20 | DeviceName string `sql:"type:varchar(200);not null;"`
21 | // device desc
22 | DeviceDescription string `sql:"type:text;not null;"`
23 | // device version(the agent version)
24 | DeviceVersion string `sql:"type:text;not null;"`
25 | // change history
26 | CreatedAt time.Time
27 | UpdatedAt time.Time
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/models/product.go:
--------------------------------------------------------------------------------
1 | // product is a abstract define of same devices made by some vendor
2 | package models
3 |
4 | import (
5 | "time"
6 | )
7 |
8 | type Product struct {
9 | // inner id
10 | ID int32
11 | // which vendor
12 | VendorID int32
13 | // name
14 | ProductName string `sql:"type:varchar(200);not null;"`
15 | // desc
16 | ProductDescription string `sql:"type:text;not null;"`
17 | // product key to auth a product
18 | ProductKey string `sql:"type:varchar(200);not null;unique;key;"`
19 | // product config string (JSON)
20 | ProductConfig string `sql:"type:text"; not null;`
21 | // change history
22 | CreatedAt time.Time
23 | UpdatedAt time.Time
24 |
25 | Devices []Device
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/models/rule.go:
--------------------------------------------------------------------------------
1 | // rule is used for automated works such as timers, ifttts.
2 | package models
3 |
4 | import (
5 | "time"
6 | )
7 |
8 | type Rule struct {
9 | // inner id
10 | ID int64
11 | // which device the rule belongs to
12 | DeviceID int64
13 | // rule type, timmer | ifttt
14 | RuleType string `sql:"type:varchar(20);not null;"`
15 | // which action triggers the rule
16 | Trigger string `sql:"type:varchar(200);not null;"`
17 | // where to send
18 | Target string `sql:"type:varchar(200);not null;"`
19 | // what action to take.
20 | Action string `sql:"type:varchar(200);not null;"`
21 | // if trigger once
22 | Once bool `sql:"default(false)"`
23 | // change history
24 | CreatedAt time.Time
25 | UpdatedAt time.Time
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/models/vendor.go:
--------------------------------------------------------------------------------
1 | // vendor is those who make products
2 | package models
3 |
4 | import (
5 | "time"
6 | )
7 |
8 | type Vendor struct {
9 | // inner id
10 | ID int32
11 | // vendor name
12 | VendorName string `sql:"type:varchar(200);not null;"`
13 | // vendor key
14 | VendorKey string `sql:"type:varchar(200);not null;key;"`
15 | // vendor description
16 | VendorDescription string `sql:"type:text;not null;"`
17 | // change history
18 | CreatedAt time.Time
19 | UpdatedAt time.Time
20 |
21 | Products []Product
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/mongo/recorder.go:
--------------------------------------------------------------------------------
1 | package mongo
2 |
3 | import (
4 | "labix.org/v2/mgo"
5 | "labix.org/v2/mgo/bson"
6 | )
7 |
8 | type Recorder struct {
9 | session *mgo.Session
10 | set string
11 | collection string
12 | }
13 |
14 | func NewRecorder(host string, set string, collection string) (*Recorder, error) {
15 | sess, err := mgo.Dial(host)
16 | if err != nil {
17 | return nil, err
18 | }
19 |
20 | sess.DB(set).C(collection).EnsureIndexKey("deviceid", "timestamp")
21 |
22 | return &Recorder{
23 | session: sess,
24 | set: set,
25 | collection: collection,
26 | }, nil
27 | }
28 |
29 | func (r *Recorder) Insert(args interface{}) error {
30 | dbHandler := r.session.DB(r.set).C(r.collection)
31 |
32 | err := dbHandler.Insert(args)
33 | if err != nil {
34 | return err
35 | }
36 |
37 | return nil
38 | }
39 |
40 | func (r *Recorder) FindLatest(deviceid uint64, record interface{}) error {
41 | dbHandler := r.session.DB(r.set).C(r.collection)
42 | err := dbHandler.Find(bson.M{
43 | "$query": bson.M{"deviceid": deviceid},
44 | "$orderby": bson.M{"timestamp": -1},
45 | }).Limit(1).One(record)
46 |
47 | return err
48 | }
49 |
50 | func (r *Recorder) FindByTimestamp(deviceid uint64, start uint64, end uint64, records interface{}) error {
51 | dbHandler := r.session.DB(r.set).C(r.collection)
52 | err := dbHandler.Find(bson.M{
53 | "deviceid": deviceid,
54 | "timestamp": bson.M{"$gte": start, "$lte": end},
55 | }).All(records)
56 |
57 | return err
58 | }
59 |
--------------------------------------------------------------------------------
/pkg/mongo/recorder_test.go:
--------------------------------------------------------------------------------
1 | package mongo
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/protocol"
5 | "github.com/PandoCloud/pando-cloud/pkg/rpcs"
6 | "github.com/PandoCloud/pando-cloud/pkg/tlv"
7 | "reflect"
8 | "testing"
9 | "time"
10 | )
11 |
12 | func TestRecorder(t *testing.T) {
13 | r, err := NewRecorder("localhost", "pandocloud", "commands")
14 | if err != nil {
15 | t.Fatal(err)
16 | }
17 |
18 | tlvs, err := tlv.MakeTLVs([]interface{}{float64(0.1), int64(100), uint64(200)})
19 | if err != nil {
20 | t.Error(err)
21 | }
22 |
23 | deviceid := uint64(12345)
24 | timestamp := uint64(time.Now().Unix() * 1000)
25 |
26 | subdata := protocol.SubData{
27 | Head: protocol.SubDataHead{1, 2, 3},
28 | Params: tlvs,
29 | }
30 |
31 | subdatas := []protocol.SubData{}
32 |
33 | subdatas = append(subdatas, subdata)
34 |
35 | data := rpcs.ArgsOnStatus{
36 | DeviceId: deviceid,
37 | Timestamp: timestamp,
38 | Subdata: subdatas,
39 | }
40 |
41 | err = r.Insert(data)
42 | if err != nil {
43 | t.Error(err)
44 | }
45 |
46 | readData := rpcs.ArgsOnStatus{}
47 | err = r.FindLatest(deviceid, &readData)
48 |
49 | if err != nil {
50 | t.Error(err)
51 | }
52 |
53 | if !reflect.DeepEqual(data, readData) {
54 | t.Errorf("read data want %v, but got %v", data, readData)
55 | }
56 |
57 | readDatas := []rpcs.ArgsOnStatus{}
58 | err = r.FindByTimestamp(deviceid, timestamp, timestamp, &readDatas)
59 | t.Log(readDatas)
60 | if !reflect.DeepEqual(data, readDatas[0]) {
61 | t.Errorf("read data by timestamp want %v, but got %v", data, readDatas[0])
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/pkg/mqtt/broker.go:
--------------------------------------------------------------------------------
1 | package mqtt
2 |
3 | import (
4 | "net"
5 | "time"
6 | )
7 |
8 | type Broker struct {
9 | mgr *Manager
10 | }
11 |
12 | func NewBroker(p Provider) *Broker {
13 | // manager
14 | mgr := NewManager(p)
15 |
16 | handler := &Broker{mgr: mgr}
17 |
18 | return handler
19 | }
20 |
21 | func (b *Broker) Handle(conn net.Conn) {
22 | b.mgr.NewConn(conn)
23 | }
24 |
25 | func (b *Broker) SendMessageToDevice(deviceid uint64, msgtype string, message []byte, timeout time.Duration) error {
26 | msg := &Publish{}
27 | msg.Header.QosLevel = QosAtLeastOnce
28 | msg.TopicName = msgtype
29 | msg.Payload = BytesPayload(message)
30 | return b.mgr.PublishMessage2Device(deviceid, msg, timeout)
31 | }
32 |
33 | func (b *Broker) GetToken(deviceid uint64) ([]byte, error) {
34 | return b.mgr.GetToken(deviceid)
35 | }
36 |
--------------------------------------------------------------------------------
/pkg/mqtt/payload.go:
--------------------------------------------------------------------------------
1 | package mqtt
2 |
3 | import (
4 | "bytes"
5 | "io"
6 | )
7 |
8 | // Payload is the interface for Publish payloads. Typically the BytesPayload
9 | // implementation will be sufficient for small payloads whose full contents
10 | // will exist in memory. However, other implementations can read or write
11 | // payloads requiring them holding their complete contents in memory.
12 | type Payload interface {
13 | // Size returns the number of bytes that WritePayload will write.
14 | Size() int
15 |
16 | // WritePayload writes the payload data to w. Implementations must write
17 | // Size() bytes of data, but it is *not* required to do so prior to
18 | // returning. Size() bytes must have been written to w prior to another
19 | // message being encoded to the underlying connection.
20 | WritePayload(b *bytes.Buffer) error
21 |
22 | // ReadPayload reads the payload data from r (r will EOF at the end of the
23 | // payload). It is *not* required for r to have been consumed prior to this
24 | // returning. r must have been consumed completely prior to another message
25 | // being decoded from the underlying connection.
26 | ReadPayload(r io.Reader, n int) error
27 | }
28 |
29 | type BytesPayload []byte
30 |
31 | func (p BytesPayload) Size() int {
32 | return len(p)
33 | }
34 |
35 | func (p BytesPayload) WritePayload(b *bytes.Buffer) error {
36 | _, err := b.Write(p)
37 | return err
38 | }
39 |
40 | func (p BytesPayload) ReadPayload(r io.Reader, n int) error {
41 | _, err := io.ReadFull(r, p)
42 | return err
43 | }
44 |
--------------------------------------------------------------------------------
/pkg/mqtt/provider.go:
--------------------------------------------------------------------------------
1 | package mqtt
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/rpcs"
5 | )
6 |
7 | type Provider interface {
8 | ValidateDeviceToken(deviceid uint64, token []byte) error
9 | OnDeviceOnline(args rpcs.ArgsGetOnline) error
10 | OnDeviceOffline(deviceid uint64) error
11 | OnDeviceHeartBeat(deviceid uint64) error
12 | OnDeviceMessage(deviceid uint64, msgtype string, message []byte)
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/mysql/client.go:
--------------------------------------------------------------------------------
1 | package mysql
2 |
3 | import (
4 | "database/sql"
5 | _ "github.com/go-sql-driver/mysql"
6 | "time"
7 | )
8 |
9 | var mapClients map[string]*sql.DB
10 |
11 | func GetClient(dbhost, dbport, dbname, dbuser, dbpass string) (*sql.DB, error) {
12 |
13 | pattern := dbuser + ":" + dbpass + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname
14 | _, exist := mapClients[pattern]
15 | if !exist {
16 | var err error
17 | mapClients[pattern], err = sql.Open("mysql", pattern+"?charset=utf8&parseTime=True")
18 | if err != nil {
19 | return nil, err
20 | }
21 | err = mapClients[pattern].Ping()
22 | if err != nil {
23 | return nil, err
24 | }
25 | }
26 |
27 | return mapClients[pattern], nil
28 | }
29 |
30 | func init() {
31 | mapClients = make(map[string]*sql.DB)
32 |
33 | timer := time.NewTicker(30 * time.Second)
34 | go func() {
35 | for {
36 | <-timer.C
37 | for _, db := range mapClients {
38 | db.Ping()
39 | }
40 | }
41 | }()
42 | }
43 |
--------------------------------------------------------------------------------
/pkg/mysql/migrate.go:
--------------------------------------------------------------------------------
1 | // database initial and migrate
2 | package mysql
3 |
4 | import (
5 | "github.com/PandoCloud/pando-cloud/pkg/models"
6 | _ "github.com/go-sql-driver/mysql"
7 | "github.com/jinzhu/gorm"
8 | )
9 |
10 | func MigrateDatabase(dbhost, dbport, dbname, dbuser, dbpass string) error {
11 | mysqldb, err := GetClient(dbhost, dbport, dbname, dbuser, dbpass)
12 | if err != nil {
13 | return err
14 | }
15 | db, err := gorm.Open("mysql", mysqldb)
16 | if err != nil {
17 | return err
18 | }
19 |
20 | // Then you could invoke `*sql.DB`'s functions with it
21 | err = db.DB().Ping()
22 | if err != nil {
23 | return err
24 | }
25 |
26 | // Disable table name's pluralization
27 | db.SingularTable(true)
28 | db.LogMode(false)
29 |
30 | db.DB().Query("CREATE DATABASE PandoCloud; ")
31 | db.DB().Query("USE PandoCloud;")
32 | // Automating Migration
33 | db.Set("gorm:table_options", "ENGINE=MyISAM").AutoMigrate(
34 | &models.Device{},
35 | &models.Product{},
36 | &models.Vendor{},
37 | &models.Application{},
38 | &models.Rule{},
39 | )
40 |
41 | return nil
42 | }
43 |
--------------------------------------------------------------------------------
/pkg/mysql/migrate_test.go:
--------------------------------------------------------------------------------
1 | package mysql
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestMigrate(t *testing.T) {
8 | err := MigrateDatabase("localhost", "3306", "", "root", "")
9 | if err != nil {
10 | t.Error(err)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/pkg/online/online_test.go:
--------------------------------------------------------------------------------
1 | package online
2 |
3 | import (
4 | "github.com/garyburd/redigo/redis"
5 | "reflect"
6 | "testing"
7 | "time"
8 | )
9 |
10 | var testid = uint64(100)
11 |
12 | func checkOnlineStatus(t *testing.T, mgr *Manager, status Status) {
13 | readstatus, err := mgr.GetStatus(testid)
14 | if err != nil && err != redis.ErrNil {
15 | t.Error(err)
16 | }
17 |
18 | if readstatus == nil {
19 | t.Errorf("device should be online, but is offline.")
20 | }
21 |
22 | if !reflect.DeepEqual(status, *readstatus) {
23 | t.Errorf("get status test error, want %v, got %v", status, *readstatus)
24 | }
25 | }
26 |
27 | func checkOfflineStatus(t *testing.T, mgr *Manager) {
28 | readstatus, err := mgr.GetStatus(testid)
29 | if err != nil && err != redis.ErrNil {
30 | t.Error(err)
31 | }
32 |
33 | if readstatus != nil {
34 | t.Errorf("device should be offline, but got status: %v", readstatus)
35 | }
36 |
37 | }
38 |
39 | func TestManager(t *testing.T) {
40 | mgr := NewManager("localhost:6379")
41 |
42 | status := Status{
43 | ClientIP: "3.3.3.3",
44 | AccessRPCHost: "192.168.9.1:20030",
45 | HeartbeatInterval: 2,
46 | }
47 |
48 | err := mgr.GetOnline(testid, status)
49 | if err != nil {
50 | t.Error(err)
51 | }
52 |
53 | checkOnlineStatus(t, mgr, status)
54 |
55 | cnt := 0
56 | for {
57 | time.Sleep(time.Second * 2)
58 | if cnt > 2 {
59 | break
60 | }
61 | err := mgr.SetHeartbeat(testid)
62 | if err != nil {
63 | t.Error(err)
64 | }
65 | cnt++
66 | }
67 |
68 | checkOnlineStatus(t, mgr, status)
69 |
70 | err = mgr.GetOffline(testid)
71 | if err != nil {
72 | t.Error(err)
73 | }
74 |
75 | checkOfflineStatus(t, mgr)
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/pkg/protocol/structure.go:
--------------------------------------------------------------------------------
1 | package protocol
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/tlv"
5 | )
6 |
7 | type CommandEventHead struct {
8 | Flag uint8
9 | Timestamp uint64
10 | Token [16]byte
11 | SubDeviceid uint16
12 | No uint16
13 | Priority uint16
14 | ParamsCount uint16
15 | }
16 |
17 | type Command struct {
18 | Head CommandEventHead
19 | Params []tlv.TLV
20 | }
21 |
22 | type Event struct {
23 | Head CommandEventHead
24 | Params []tlv.TLV
25 | }
26 |
27 | type DataHead struct {
28 | Flag uint8
29 | Timestamp uint64
30 | Token [16]byte
31 | }
32 |
33 | type Data struct {
34 | Head DataHead
35 | SubData []SubData
36 | }
37 |
38 | type SubDataHead struct {
39 | SubDeviceid uint16
40 | PropertyNum uint16
41 | ParamsCount uint16
42 | }
43 |
44 | type SubData struct {
45 | Head SubDataHead
46 | Params []tlv.TLV
47 | }
48 |
--------------------------------------------------------------------------------
/pkg/queue/queque_test.go:
--------------------------------------------------------------------------------
1 | package queue
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 | "time"
7 | )
8 |
9 | type test struct {
10 | Cmd int
11 | Msg string
12 | }
13 |
14 | const testQueueName = "test/queue/somename"
15 |
16 | var testChan chan test = make(chan test)
17 |
18 | func recv(t *testing.T) {
19 | q, err := New("amqp://guest:guest@localhost:5672/", testQueueName)
20 | if err != nil {
21 | t.Error(err)
22 | }
23 | msg := test{}
24 | err = q.Receive(&msg)
25 | if err != nil {
26 | t.Error(err)
27 | }
28 | testChan <- msg
29 | }
30 |
31 | func TestQueue(t *testing.T) {
32 | testMessage := test{123, "hello"}
33 |
34 | q, err := New("amqp://guest:guest@localhost:5672/", testQueueName)
35 | if err != nil {
36 | t.Fatal(err)
37 | }
38 |
39 | go recv(t)
40 |
41 | time.Sleep(time.Second)
42 |
43 | err = q.Send(testMessage)
44 | if err != nil {
45 | t.Fatal(err)
46 | }
47 |
48 | recvMessage := <-testChan
49 |
50 | if !reflect.DeepEqual(testMessage, recvMessage) {
51 | t.Errorf("receive message not match, want: %v, got : %v", testMessage, recvMessage)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/pkg/redispool/redispool.go:
--------------------------------------------------------------------------------
1 | package redispool
2 |
3 | import (
4 | "github.com/garyburd/redigo/redis"
5 | "time"
6 | )
7 |
8 | var mapRedisPool map[string]*redis.Pool
9 |
10 | // GetClient get a redis connection by host
11 | func GetClient(host string) (redis.Conn, error) {
12 |
13 | pool, exist := mapRedisPool[host]
14 | if !exist {
15 | pool = &redis.Pool{
16 | MaxIdle: 10,
17 | Dial: func() (redis.Conn, error) {
18 | c, err := redis.Dial("tcp", host)
19 | if err != nil {
20 | return nil, err
21 | }
22 | return c, err
23 | },
24 | TestOnBorrow: func(c redis.Conn, t time.Time) error {
25 | _, err := c.Do("PING")
26 | return err
27 | },
28 | }
29 | mapRedisPool[host] = pool
30 | }
31 | return pool.Get(), nil
32 | }
33 |
34 | func init() {
35 | mapRedisPool = make(map[string]*redis.Pool)
36 | }
37 |
--------------------------------------------------------------------------------
/pkg/redispool/redispool_test.go:
--------------------------------------------------------------------------------
1 | package redispool
2 |
3 | import (
4 | "github.com/garyburd/redigo/redis"
5 | "testing"
6 | )
7 |
8 | func TestRedisCli(t *testing.T) {
9 | cli, err := GetClient("localhost:6379")
10 | if err != nil {
11 | t.Fatal(err)
12 | }
13 |
14 | _, err = redis.String(cli.Do("GET", "testkey"))
15 | if err != nil && err != redis.ErrNil {
16 | t.Error(err)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/rpcs/access.go:
--------------------------------------------------------------------------------
1 | package rpcs
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/protocol"
5 | "github.com/PandoCloud/pando-cloud/pkg/tlv"
6 | )
7 |
8 | type ArgsSetStatus struct {
9 | DeviceId uint64
10 | Status []protocol.SubData
11 | }
12 | type ReplySetStatus ReplyEmptyResult
13 |
14 | type ArgsGetStatus ArgsDeviceId
15 | type ReplyGetStatus struct {
16 | Status []protocol.SubData
17 | }
18 |
19 | type ArgsSendCommand struct {
20 | DeviceId uint64
21 | SubDevice uint16
22 | No uint16
23 | Priority uint16
24 | WaitTime uint32
25 | Params []tlv.TLV
26 | }
27 | type ReplySendCommand ReplyEmptyResult
28 |
--------------------------------------------------------------------------------
/pkg/rpcs/common.go:
--------------------------------------------------------------------------------
1 | package rpcs
2 |
3 | type ArgsDeviceId struct {
4 | Id uint64
5 | }
6 |
7 | type ReplyEmptyResult struct{}
8 |
--------------------------------------------------------------------------------
/pkg/rpcs/controller.go:
--------------------------------------------------------------------------------
1 | package rpcs
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/protocol"
5 | "github.com/PandoCloud/pando-cloud/pkg/tlv"
6 | )
7 |
8 | type ArgsOnStatus struct {
9 | DeviceId uint64
10 | Timestamp uint64
11 | Subdata []protocol.SubData
12 | }
13 | type ReplyOnStatus ReplyEmptyResult
14 |
15 | type ArgsOnEvent struct {
16 | DeviceId uint64
17 | TimeStamp uint64
18 | SubDevice uint16
19 | No uint16
20 | Priority uint16
21 | Params []tlv.TLV
22 | }
23 | type ReplyOnEvent ReplyEmptyResult
24 |
--------------------------------------------------------------------------------
/pkg/rpcs/devicemanager.go:
--------------------------------------------------------------------------------
1 | package rpcs
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/online"
5 | )
6 |
7 | type ArgsGenerateDeviceAccessToken ArgsDeviceId
8 | type ReplyGenerateDeviceAccessToken struct {
9 | AccessToken []byte
10 | }
11 |
12 | type ArgsValidateDeviceAccessToken struct {
13 | Id uint64
14 | AccessToken []byte
15 | }
16 | type ReplyValidateDeviceAccessToken ReplyEmptyResult
17 |
18 | type ArgsGetOnline struct {
19 | Id uint64
20 | ClientIP string
21 | AccessRPCHost string
22 | HeartbeatInterval uint32
23 | }
24 | type ReplyGetOnline ReplyEmptyResult
25 |
26 | type ArgsGetOffline ArgsDeviceId
27 | type ReplyGetOffline ReplyEmptyResult
28 |
29 | type ArgsHeartBeat struct {
30 | Id uint64
31 | }
32 | type ReplyHeartBeat ReplyEmptyResult
33 |
34 | type ArgsGetDeviceOnlineStatus ArgsDeviceId
35 | type ReplyGetDeviceOnlineStatus online.Status
36 |
--------------------------------------------------------------------------------
/pkg/rpcs/registry.go:
--------------------------------------------------------------------------------
1 | package rpcs
2 |
3 | // device register args
4 | type ArgsDeviceRegister struct {
5 | ProductKey string
6 | DeviceCode string
7 | DeviceVersion string
8 | }
9 |
10 | // device update args
11 | type ArgsDeviceUpdate struct {
12 | DeviceIdentifier string
13 | DeviceName string
14 | DeviceDescription string
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/rule/timer.go:
--------------------------------------------------------------------------------
1 | // suport cron like schedule tasks.
2 | package rule
3 |
4 | import (
5 | "fmt"
6 | "github.com/PandoCloud/pando-cloud/pkg/models"
7 | "github.com/PandoCloud/pando-cloud/pkg/server"
8 | "github.com/robfig/cron"
9 | "time"
10 | )
11 |
12 | type Timer struct {
13 | c *cron.Cron
14 | }
15 |
16 | func NewTimer() *Timer {
17 | t := &Timer{}
18 |
19 | return t
20 | }
21 |
22 | func (t *Timer) createTimerFunc(target string, action string) func() {
23 | return func() {
24 | err := performRuleAction(target, action)
25 | if err != nil {
26 | server.Log.Warnf("timer action failed: %v", err)
27 | }
28 | }
29 | }
30 |
31 | func (t *Timer) refresh() {
32 | if t.c != nil {
33 | t.c.Stop()
34 | }
35 | t.c = cron.New()
36 | timers := &[]models.Rule{}
37 | query := &models.Rule{
38 | RuleType: "timer",
39 | }
40 | err := server.RPCCallByName("registry", "Registry.QueryRules", query, timers)
41 | if err != nil {
42 | server.Log.Warnf("refresh timer rules error : %v", err)
43 | return
44 | }
45 |
46 | sec := fmt.Sprintf("%d ", (time.Now().Second()+30)%60)
47 |
48 | for _, one := range *timers {
49 | t.c.AddFunc(sec+one.Trigger, t.createTimerFunc(one.Target, one.Action))
50 | }
51 |
52 | t.c.Start()
53 | }
54 |
55 | func (t *Timer) Run() {
56 | go func() {
57 | for {
58 | t.refresh()
59 | time.Sleep(time.Minute)
60 | }
61 | }()
62 | }
63 |
--------------------------------------------------------------------------------
/pkg/serializer/serializer.go:
--------------------------------------------------------------------------------
1 | package serializer
2 |
3 | import (
4 | "bytes"
5 | "encoding/gob"
6 | )
7 |
8 | // convert string to any kind of struct
9 | func String2Struct(str string, target interface{}) error {
10 | bytes_buffer := bytes.NewBufferString(str)
11 | dec := gob.NewDecoder(bytes_buffer)
12 | err := dec.Decode(target)
13 | return err
14 | }
15 |
16 | // convert any kind of struct to string
17 | func Struct2String(stru interface{}) (string, error) {
18 | var bytes_buffer bytes.Buffer
19 | enc := gob.NewEncoder(&bytes_buffer)
20 | err := enc.Encode(stru)
21 | return bytes_buffer.String(), err
22 | }
23 |
--------------------------------------------------------------------------------
/pkg/serializer/serializer_test.go:
--------------------------------------------------------------------------------
1 | package serializer
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 | )
7 |
8 | type testStruct struct {
9 | Int1 int
10 | Str1 string
11 | Int2 int32
12 | Arr []byte
13 | }
14 |
15 | func TestStringStructConvert(t *testing.T) {
16 | test := testStruct{0, "hello", 12, []byte{1, 0, 12}}
17 | str, err := Struct2String(test)
18 | if err != nil {
19 | t.Error(err)
20 | }
21 | stru := testStruct{}
22 | err = String2Struct(str, &stru)
23 | if err != nil {
24 | t.Error(err)
25 | }
26 | if !reflect.DeepEqual(test, stru) {
27 | t.Errorf("wrong result %v, want %v", stru, test)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/server/README.md:
--------------------------------------------------------------------------------
1 | # the server framework.
2 | includes:
3 |
4 | - tcp/http service framework
5 | - rpc helper
6 | - stats api
7 | - timer task interface
8 |
--------------------------------------------------------------------------------
/pkg/server/config.go:
--------------------------------------------------------------------------------
1 | // config flags from command line or ini conf file.
2 |
3 | package server
4 |
5 | import (
6 | "flag"
7 | )
8 |
9 | const (
10 | FlagTCPHost = "tcphost"
11 | FlagUseTls = "usetls"
12 | FlagHTTPHost = "httphost"
13 | FlagUseHttps = "usehttps"
14 | FlagCAFile = "cafile"
15 | FlagKeyFile = "keyfile"
16 | FlagRPCHost = "rpchost"
17 | FlagEtcd = "etcd"
18 | FlagLogLevel = "loglevel"
19 | )
20 |
21 | var (
22 | confTCPHost = flag.String(FlagTCPHost, "", "tcp server listen address, format ip:port")
23 | confUseTls = flag.Bool(FlagUseTls, false, "if tcp server uses tls, default false")
24 |
25 | confHTTPHost = flag.String(FlagHTTPHost, "", "http server listen address, format ip:port")
26 | confUseHttps = flag.Bool(FlagUseHttps, false, "if http server uses tls, default false")
27 |
28 | confCAFile = flag.String(FlagCAFile, "cacert.pem", "public ca pem file path")
29 | confKeyFile = flag.String(FlagKeyFile, "privkey.pem", "private key pem file path")
30 |
31 | confRPCHost = flag.String(FlagRPCHost, "", "rpc server listen address, format ip:port")
32 |
33 | confEtcd = flag.String(FlagEtcd, "", "etcd service addr, format ip:port;ip:port")
34 |
35 | confLogLevel = flag.String(FlagLogLevel, "info", "default log level, options are panic|fatal|error|warn|info|debug")
36 | )
37 |
--------------------------------------------------------------------------------
/pkg/server/errors.go:
--------------------------------------------------------------------------------
1 | // error messages
2 |
3 | package server
4 |
5 | const (
6 | errServerNotInit = "Server has not been initialized...You must call server.Init(name) first !"
7 | errTCPHandlerNotRegistered = "Start TCP Server error : tcp handler not registered !"
8 | errMissingFlag = "Missing flag: %s !"
9 | errLoadSecureKey = "Load secret key file failed - %s"
10 | errListenFailed = "FATAL: tcp listen (%s) failed - %s"
11 | errNewConnection = "receive new connection error (%s)"
12 | errWrongHostAddr = "wrong address : %s"
13 | errWrongEtcdPath = "wrong path in etcd: %s"
14 | errServerManagerNotInit = "sever manager not init!"
15 | )
16 |
--------------------------------------------------------------------------------
/pkg/server/http_server.go:
--------------------------------------------------------------------------------
1 | // http server library.
2 | package server
3 |
4 | import (
5 | "net/http"
6 | )
7 |
8 | type HTTPServer struct {
9 | addr string
10 | handler http.Handler
11 | useHttps bool
12 | }
13 |
14 | func (hs *HTTPServer) Start() error {
15 | // field check
16 | if hs.handler == nil {
17 | return errorf("Start HTTP Server error : http handler not registered!")
18 | }
19 |
20 | if hs.useHttps {
21 | // secure files
22 | if *confCAFile == "" {
23 | return errorf(errMissingFlag, FlagCAFile)
24 | }
25 | if *confKeyFile == "" {
26 | return errorf(errMissingFlag, FlagKeyFile)
27 | }
28 | }
29 |
30 | Log.Infof("HTTP Server Listen on %s, use https: %v", hs.addr, hs.useHttps)
31 | go func() {
32 | var err error
33 | if hs.useHttps == false {
34 | err = http.ListenAndServe(hs.addr, hs.handler)
35 | } else {
36 | err = http.ListenAndServeTLS(hs.addr, *confCAFile, *confKeyFile, hs.handler)
37 | }
38 |
39 | if err != nil {
40 | Log.Fatal(err.Error())
41 | }
42 | }()
43 |
44 | return nil
45 | }
46 |
--------------------------------------------------------------------------------
/pkg/server/log.go:
--------------------------------------------------------------------------------
1 | // log provides log api.
2 | // thanks to the helpful log tool logrus(https://github.com/Sirupsen/logrus)
3 | package server
4 |
5 | import (
6 | "github.com/Sirupsen/logrus"
7 | )
8 |
9 | var Log *logrus.Entry
10 |
11 | func initLog(name string, level string) error {
12 | if Log == nil {
13 | // Log as JSON instead of the default ASCII formatter.
14 | logrus.SetFormatter(&logrus.JSONFormatter{})
15 |
16 | // Output to stderr instead of stdout, could also be a file.
17 | // logrus.SetOutput(os.Stderr)
18 |
19 | // logging level
20 | lvl, err := logrus.ParseLevel(level)
21 | if err != nil {
22 | return err
23 | }
24 |
25 | logrus.SetLevel(lvl)
26 |
27 | // default fields
28 | Log = logrus.WithFields(logrus.Fields{
29 | "service": name,
30 | "ip": InternalIP,
31 | })
32 | }
33 |
34 | return nil
35 | }
36 |
--------------------------------------------------------------------------------
/pkg/server/log_test.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestLog(t *testing.T) {
8 | Log = nil
9 | err := initLog("wrongtest", "wronglevel")
10 | if err == nil {
11 | t.Errorf("init log should return error when level is wrong.")
12 | }
13 |
14 | err = initLog("test", "error")
15 | if err != nil {
16 | t.Error(err)
17 | }
18 |
19 | Log.Error("test log.")
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/server/netif_test.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestNetIf(t *testing.T) {
8 | readNetInterfaces()
9 | t.Logf("internal ip: %s", InternalIP)
10 | t.Logf("external ip: %s", ExternalIP)
11 | }
12 |
13 | func TestIsInternalIP(t *testing.T) {
14 | testIPs := []string{"127.0.0.1", "192.168.5.234", "10.23.45.56", "172.17.2.4"}
15 | for _, ip := range testIPs {
16 | if isInternalIP(ip) == false {
17 | t.Errorf("test internal ip failed: %s", ip)
18 | }
19 | }
20 | }
21 |
22 | func TestFixHostIP(t *testing.T) {
23 | InternalIP = "10.1.1.1"
24 | ExternalIP = "5.1.1.1"
25 | fixedIP, err := fixHostIp("internal:40")
26 | if err != nil || fixedIP != "10.1.1.1:40" {
27 | t.Errorf("test fix host ip failed: %s, %s", fixedIP, err)
28 | }
29 | fixedIP, err = fixHostIp("external:40")
30 | if err != nil || fixedIP != "5.1.1.1:40" {
31 | t.Errorf("test fix host ip failed: %s, %s", fixedIP, err)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/pkg/server/rpc_client_test.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func validateRPCClient(t *testing.T) {
8 | rpccli, err := NewRPCClient()
9 | if err != nil {
10 | t.Fatal(err)
11 | }
12 |
13 | args := &Args{100, 200}
14 | var reply int
15 |
16 | err = rpccli.Call("test", "Arith.Multiply", args, &reply)
17 | if err != nil {
18 | t.Fatal(err)
19 | }
20 |
21 | if reply != testRPCArgs.A*testRPCArgs.B {
22 | t.Fatalf("rpc client test faild, want %d, got %d", testRPCArgs.A*testRPCArgs.B, reply)
23 | }
24 |
25 | err = RPCCallByName("test", "Arith.Multiply", args, &reply)
26 | if err != nil {
27 | t.Fatal(err)
28 | }
29 |
30 | err = RPCCallByHost(*confRPCHost, "Arith.Multiply", args, &reply)
31 | if err != nil {
32 | t.Fatal(err)
33 | }
34 |
35 | if reply != testRPCArgs.A*testRPCArgs.B {
36 | t.Fatalf("rpc client test faild, want %d, got %d", testRPCArgs.A*testRPCArgs.B, reply)
37 | }
38 |
39 | err = rpccli.Call("wrongtest", "Arith.Multiply", args, &reply)
40 | t.Log(err)
41 | if err == nil {
42 | t.Fatalf("rpc client should return error when no server found!")
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/pkg/server/rpc_server.go:
--------------------------------------------------------------------------------
1 | // rpc server
2 | package server
3 |
4 | import (
5 | "net"
6 | "net/rpc"
7 | )
8 |
9 | type RPCServer struct {
10 | TCPServer
11 | }
12 |
13 | type rpcHandler struct{}
14 |
15 | func (handler *rpcHandler) Handle(conn net.Conn) {
16 | rpc.ServeConn(conn)
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/server/rpc_server_test.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "net/rpc"
5 | "testing"
6 | "time"
7 | )
8 |
9 | const (
10 | testRPCHost = "localhost:12346"
11 | )
12 |
13 | var testRPCArgs = &Args{100, 200}
14 |
15 | type Args struct {
16 | A, B int
17 | }
18 |
19 | type Arith int
20 |
21 | func (t *Arith) Multiply(args *Args, reply *int) error {
22 | *reply = args.A * args.B
23 | return nil
24 | }
25 |
26 | func validateRPCServer(t *testing.T, addr string, method string) {
27 | rpccli, err := rpc.Dial("tcp", addr)
28 | if err != nil {
29 | t.Fatal(err)
30 | }
31 |
32 | var reply int
33 |
34 | err = rpccli.Call(method, testRPCArgs, &reply)
35 | if err != nil {
36 | t.Fatal(err)
37 | }
38 |
39 | if reply != testRPCArgs.A*testRPCArgs.B {
40 | t.Fatalf("rpc test faild, want %d, got %d", testRPCArgs.A*testRPCArgs.B, reply)
41 | }
42 | }
43 |
44 | func TestRPCServer(t *testing.T) {
45 | initLog("test", "debug")
46 |
47 | testRPC := new(Arith)
48 |
49 | err := rpc.Register(testRPC)
50 | if err != nil {
51 | t.Fatal(err)
52 | }
53 |
54 | handler := rpcHandler{}
55 |
56 | svr := &RPCServer{
57 | TCPServer{
58 | addr: testRPCHost,
59 | handler: &handler,
60 | useTls: false,
61 | },
62 | }
63 |
64 | err = svr.Start()
65 | if err != nil {
66 | t.Fatal(err)
67 | }
68 |
69 | time.Sleep(time.Millisecond * 300)
70 |
71 | validateRPCServer(t, testRPCHost, "Arith.Multiply")
72 | }
73 |
--------------------------------------------------------------------------------
/pkg/server/testdata/cert.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+TCCAeGgAwIBAgIQJfY0073hjBlu0vY/xbvYHzANBgkqhkiG9w0BAQsFADAS
3 | MRAwDgYDVQQKEwdBY21lIENvMB4XDTE1MTAyMjA3MzkwOFoXDTE2MTAyMTA3Mzkw
4 | OFowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
5 | AQoCggEBAMbJZYRbvbevHkFzkVrP8Zg54QAfiaCMx36W9YWVaTf793Y90dqmUAdr
6 | A7DhB5TO6Dz0L1Zao+7HAqwEHxNSkOjGDxI3zo3/N5Q5dStHmmTRz49+lUR1L1NA
7 | kX9QlvPPgkAGb9Z40CmtckZStH9QXujxuYqH18HJnbuVxntogbNMfCX98Ix3N6oI
8 | ktuRE/GtysmJ7YyrPP1JUv358jA3Y44WLFFcJ3+X4MsZEthEqRsb/fqd5WUfRarK
9 | HgC5AuX226out8QRfd0WWjiuWaXWmV7y9lw2Buzakh4Wu+P0tkbc+iLwtTlhEgx9
10 | dXMIZfVrO6OcAkNxunbojuCR/wl0REkCAwEAAaNLMEkwDgYDVR0PAQH/BAQDAgWg
11 | MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFAYDVR0RBA0wC4IJ
12 | bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQB1fqZEISFArzR5oIiy1tdJu4wO
13 | YcZxKvemJo7PaZluNE4eAw1ITbVZKEGpSzi5dYC5A13Q5pP8ue7FvOQonm5elEY4
14 | fLDZhzpfnRj+oDhc+NPBhczCh640gcdxe6BtAcmsOJJEenLEPsGj3NrQZbPl9anL
15 | 94v9NPdvFuy1ZpLMRb8WEZO4f/iGTAj7Hg7tzxvWMIg0mbrZg9spR2wgRqyzXPEK
16 | A0awbuFuVDmg1+x1SVq6BjY+XL9+B4KiCAOQFA5dX+v1+ruSxsliUzcM8840V8i6
17 | uRBTV982FZWhbuiFJJY4/c46tjJ0DRvXdkUiEAeLeTaIb1Lkk2Q+XtfvV+2c
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/pkg/server/testdata/key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpQIBAAKCAQEAxsllhFu9t68eQXORWs/xmDnhAB+JoIzHfpb1hZVpN/v3dj3R
3 | 2qZQB2sDsOEHlM7oPPQvVlqj7scCrAQfE1KQ6MYPEjfOjf83lDl1K0eaZNHPj36V
4 | RHUvU0CRf1CW88+CQAZv1njQKa1yRlK0f1Be6PG5iofXwcmdu5XGe2iBs0x8Jf3w
5 | jHc3qgiS25ET8a3KyYntjKs8/UlS/fnyMDdjjhYsUVwnf5fgyxkS2ESpGxv9+p3l
6 | ZR9FqsoeALkC5fbbqi63xBF93RZaOK5ZpdaZXvL2XDYG7NqSHha74/S2Rtz6IvC1
7 | OWESDH11cwhl9Ws7o5wCQ3G6duiO4JH/CXRESQIDAQABAoIBAHTduBn9WWbgxBfU
8 | mpLaB33oIRhScjX6LdqFY2iac1Zfgpd4NqSl/AywZGYblbptfek/4YiSFyhsxWxd
9 | q+tPMjQ3JGsgdgXTEljJAtJj8SfulWkWESlC/4ShRCimN2i1CS0c26kqM68c8j7X
10 | ppfmpzWpztvbiwO5xUqf/iVVRlMizdDXXPssGJlDI/DtiyVx1tMt0YkUrsrZKW2P
11 | cTrYWA638GnQ6IDYPp9rQYwkaAeWbvm1aI5CqB7fJdIsyp9XslUGdUiRe1yIoT/G
12 | q/BMP38NfyxfbZQzVPrniZl67wwVRLvp3Te2PKjOts89/yBN5FaqgdIpbzJ06aOc
13 | 9Mqci9ECgYEA2/GUVMnjmct0Wd1/PaPVWfjyMknVIMP2pLZLN07DEu6x+5i2DOtd
14 | B6bp23yDyX2okNho0GTmq+l7qRaMNb/pFcOiFuduaJ4H5NM445pw9EWwn9keah6R
15 | SFE7pq2qoBRi2ogiqJGnMOrWNmBvxBVYDqavWLLEZuvjAaJWJWKb6qUCgYEA51/r
16 | JCG3bLE4Q3anmaXer0Bpqwr7iDRM1qw+3gAzWN/ePUtEefC4iUPnxRKxRy/ovDGZ
17 | iUCmYD6p3yR0g9+4pdmgoeekQm81Rrr6jk9T3bMpg15x1h9VqKqnZliXMo4dH67o
18 | HUTUIPag8YUnFavDi63zZzQgUwTU7YJw0PUIldUCgYEAldz6s/dIRO+zXNQmsepj
19 | IkYVSRyzwvqjoUGw6IObOdg4n/VC/nSU0/TwXaRu66jaZa9/Y5eM8VBK+UCq0qjr
20 | +e9uD2sr+M7NFCa0GamPE3I00gYPykD/vyXSnlSw8RhS7xJZg0CTiipJQY3eOd5N
21 | PNZonehZGMPbzq49QoX5NR0CgYEAyIA+bFkrcm1ArHWuV1990bCn4SjrP+TSkVVC
22 | RW83D9Uv6T3IYUNRJuJJfmXsahwCOtNgkagMhWrIGi6lKYI9qLsmkCcEGO315Q0z
23 | Aw+LRZt0Zfr5+uu8dyUrW2152L1+T25qhrKWgNo4LhONAyKNmgVr4Asz171gJ1Ha
24 | Ibm1buECgYEAmNBNkfgm4OcGOABcR/8TU1uBE7aplN8XUOv3rTslD9gs4SCMmK1x
25 | 87MofB4aX6gQ2KNfvIlOQ8vhxc5XgTTYIZt+TL/UlQXQKPeKgX8ok9I3U7YEmhJ+
26 | 98q5D+qpyQOqVO/mcgwN3+YWG8fq9OrEcB/anFYJb7KtQbXWm3p7iX0=
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/pkg/server/timer_task.go:
--------------------------------------------------------------------------------
1 | // the timer task interface.
2 |
3 | package server
4 |
5 | type TimerTask interface {
6 | DoTask()
7 | }
8 |
--------------------------------------------------------------------------------
/pkg/server/utils.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // will print a log and return error
8 | func errorf(format string, a ...interface{}) error {
9 | err := fmt.Errorf(format, a...)
10 | Log.Error(err)
11 | return err
12 | }
13 |
--------------------------------------------------------------------------------
/pkg/server/utils_test.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "errors"
5 | "testing"
6 | )
7 |
8 | func TestErrorf(t *testing.T) {
9 | err := errorf("err %s %d", "1", 2)
10 | if err.Error() != "err 1 2" {
11 | t.Errorf("err is %v ,want %v", err, errors.New("err 1 2"))
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/pkg/token/token_test.go:
--------------------------------------------------------------------------------
1 | package token
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestTokenHelper(t *testing.T) {
8 | helper := NewHelper("localhost:6379")
9 |
10 | testid := uint64(123)
11 |
12 | token, err := helper.GenerateToken(testid)
13 | if err != nil {
14 | t.Error(err)
15 | }
16 |
17 | err = helper.ValidateToken(testid, token)
18 | if err != nil {
19 | t.Error(err)
20 | }
21 |
22 | err = helper.ClearToken(testid)
23 | if err != nil {
24 | t.Error(err)
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/pkg/utils/http.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "bytes"
5 | "crypto/tls"
6 | "io/ioutil"
7 | "net/http"
8 | )
9 |
10 | /**
11 | Params:
12 | argUrl: reqeust url
13 | argReq: reqeust contents
14 | argType: reqeust type
15 | argHead: reqeust head
16 | Retrun: reqesut result body
17 | */
18 | func SendHttpRequest(argUrl string, argReq string, argType string, argHead map[string]string) ([]byte, error) {
19 | bReq := []byte(argReq)
20 | req, err := http.NewRequest(argType, argUrl, bytes.NewBuffer(bReq))
21 | if err != nil {
22 | return []byte{}, err
23 | }
24 | req.Header.Set("Content-Type", "application/json")
25 | if argHead != nil {
26 | for key, vaule := range argHead {
27 | req.Header.Set(key, vaule)
28 | }
29 | }
30 | tr := &http.Transport{
31 | TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
32 | }
33 | client := &http.Client{Transport: tr}
34 | resp, err := client.Do(req)
35 | if err != nil {
36 | return []byte{}, err
37 | }
38 | defer resp.Body.Close()
39 | body, _ := ioutil.ReadAll(resp.Body)
40 | return body, nil
41 | }
42 |
--------------------------------------------------------------------------------
/pkg/utils/http_test.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestSendHttpRequest(t *testing.T) {
8 | headers := make(map[string]string)
9 | headers["test"] = "test"
10 |
11 | res, err := SendHttpRequest("http://www.baidu.com", "", "GET", headers)
12 |
13 | if err != nil {
14 | t.Error(err)
15 | }
16 |
17 | t.Log(len(res))
18 | }
19 |
--------------------------------------------------------------------------------
/services/README.md:
--------------------------------------------------------------------------------
1 | # core services to serve iot devices.
2 |
3 | - **mqttaccess**: mqtt access service which accepts device mqtt connections.
4 | - **httpaccess**: device api service which offers device http apis like authentication, registration, etc.
5 | - **devicemanager**: device info and status management.
6 | - **controller**: logic and route service.
7 | - **apiprovidor**: http apis for applications, and notify device status changes to applications.
8 | - **registry**: service that keep global configuration and info.
9 |
--------------------------------------------------------------------------------
/services/apiprovider/flags.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | )
6 |
7 | const (
8 | flagRabbitHost = "rabbithost"
9 | defaultRabbitHost = "amqp://guest:guest@localhost:5672/"
10 | )
11 |
12 | var (
13 | confRabbitHost = flag.String(flagRabbitHost, defaultRabbitHost, "rabbitmq host address, amqp://user:password@ip:port/")
14 | )
15 |
--------------------------------------------------------------------------------
/services/apiprovider/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/server"
5 | "github.com/go-martini/martini"
6 | "github.com/martini-contrib/render"
7 | )
8 |
9 | func main() {
10 | // init server
11 | err := server.Init("apiprovidor")
12 | if err != nil {
13 | server.Log.Fatal(err)
14 | return
15 | }
16 |
17 | // martini setup
18 | martini.Env = martini.Prod
19 | handler := martini.Classic()
20 | handler.Use(render.Renderer())
21 | route(handler)
22 |
23 | // register a http handler
24 | err = server.RegisterHTTPHandler(handler)
25 | if err != nil {
26 | server.Log.Errorf("RegisterHTTPHandler Error: %s", err)
27 | return
28 | }
29 |
30 | // run notifier
31 | err = RunNotifier()
32 | if err != nil {
33 | server.Log.Fatalf("Run Notifier Error: %s", err)
34 | }
35 |
36 | // go
37 | err = server.Run()
38 | if err != nil {
39 | server.Log.Fatal(err)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/services/apiprovider/middleware_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func checkPair(t *testing.T, domain string, identifier string, shoudpass bool) {
8 | err := checkAppDomain(domain, identifier)
9 | if shoudpass {
10 | if err != nil {
11 | t.Errorf("check domain should pass, but failed: domain: %v, identifier: %v, err: %v", domain, identifier, err)
12 | }
13 | } else {
14 | if err == nil {
15 | t.Errorf("check domain should fail, but passed: domain: %v, identifier: %v, err: %v", domain, identifier, err)
16 | }
17 | }
18 | }
19 |
20 | func TestCheckAppDomain(t *testing.T) {
21 | checkPair(t, "", "", false)
22 | checkPair(t, "*", "1-2-3333", true)
23 | checkPair(t, "vendor/1", "1-2-3333", true)
24 | checkPair(t, "product/2", "1-2-3333", true)
25 | checkPair(t, "product/2", "1-a-3333", false)
26 | checkPair(t, "product/10", "1-a-3333", true)
27 | checkPair(t, "vendor/11", "b-a-3333", true)
28 | checkPair(t, "fff/product/2", "1-a-3333", false)
29 | checkPair(t, "product/10", "1-a-3333-11111", false)
30 | }
31 |
--------------------------------------------------------------------------------
/services/apiprovider/request.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | type CreateRuleRequest struct {
4 | Type string `json:"type"`
5 | Trigger string `json:"trigger"`
6 | Target string `json:"target"`
7 | Action string `json:"action"`
8 | }
9 |
--------------------------------------------------------------------------------
/services/apiprovider/response.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // common response fields
4 | type Common struct {
5 | Code int `json:"code"`
6 | Message string `json:"message"`
7 | }
8 |
9 | type DeviceInfoData struct {
10 | Identifier string `json:"identifier"`
11 | Name string `json:"name"`
12 | Description string `json:"description"`
13 | Version string `json:"version"`
14 | }
15 |
16 | type DeviceInfoResponse struct {
17 | Common
18 | Data DeviceInfoData `json:"data"`
19 | }
20 |
21 | type DeviceStatusData map[string][]interface{}
22 |
23 | type DeviceStatusResponse struct {
24 | Common
25 | Data DeviceStatusData `json:"data"`
26 | }
27 |
--------------------------------------------------------------------------------
/services/apiprovider/router.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/go-martini/martini"
5 | // "github.com/martini-contrib/binding"
6 | )
7 |
8 | // martini router
9 | func route(m *martini.ClassicMartini) {
10 | // find a device by key
11 | m.Get("/application/v1/device/info", GetDeviceInfoByKey)
12 |
13 | // find a device by identifier
14 | m.Get("/application/v1/devices/:identifier/info", ApplicationAuthOnDeviceIdentifer, GetDeviceInfoByIdentifier)
15 |
16 | // get devie current status
17 | m.Get("/application/v1/devices/:identifier/status/current",
18 | ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
19 | GetDeviceCurrentStatus)
20 |
21 | // get devie latest status
22 | m.Get("/application/v1/devices/:identifier/status/latest",
23 | ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
24 | GetDeviceLatestStatus)
25 |
26 | // set device status
27 | m.Put("/application/v1/devices/:identifier/status",
28 | ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
29 | SetDeviceStatus)
30 |
31 | // send a command to device
32 | m.Post("/application/v1/devices/:identifier/commands",
33 | ApplicationAuthOnDeviceIdentifer, CheckDeviceOnline, CheckProductConfig,
34 | SendCommandToDevice)
35 |
36 | // and a rule to device
37 | m.Post("/application/v1/devices/:identifier/rules",
38 | ApplicationAuthOnDeviceIdentifer, CheckDeviceIdentifier,
39 | AddRule)
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/services/controller/flags.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | )
6 |
7 | const (
8 | flagMongoHost = "mongohost"
9 | defaultMongoHost = "localhost"
10 |
11 | flagRabbitHost = "rabbithost"
12 | defaultRabbitHost = "amqp://guest:guest@localhost:5672/"
13 | )
14 |
15 | var (
16 | confMongoHost = flag.String(flagMongoHost, defaultMongoHost, "mongo host address, ip:port")
17 | confRabbitHost = flag.String(flagRabbitHost, defaultRabbitHost, "rabbitmq host address, amqp://user:password@ip:port/")
18 | )
19 |
--------------------------------------------------------------------------------
/services/controller/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/server"
5 | )
6 |
7 | func main() {
8 | // init server
9 | err := server.Init("controller")
10 | if err != nil {
11 | server.Log.Fatal(err)
12 | return
13 | }
14 |
15 | // register a rpc service
16 | controller, err := NewController(*confMongoHost, *confRabbitHost)
17 | if err != nil {
18 | server.Log.Errorf("NewController Error: %s", err)
19 | return
20 | }
21 |
22 | err = server.RegisterRPCHandler(controller)
23 | if err != nil {
24 | server.Log.Errorf("Register RPC service Error: %s", err)
25 | return
26 | }
27 |
28 | // start to run
29 | err = server.Run()
30 | if err != nil {
31 | server.Log.Fatal(err)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/services/devicemanager/flags.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | )
6 |
7 | const (
8 | flagRedisHost = "redishost"
9 |
10 | defaultRedisHost = "localhost:6379"
11 | )
12 |
13 | var (
14 | confRedisHost = flag.String(flagRedisHost, defaultRedisHost, "redis host address, ip:port")
15 | )
16 |
--------------------------------------------------------------------------------
/services/devicemanager/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/server"
5 | )
6 |
7 | func main() {
8 | // init server
9 | err := server.Init("devicemanager")
10 | if err != nil {
11 | server.Log.Fatal(err)
12 | return
13 | }
14 |
15 | // register a rpc service
16 | dm := NewDeviceManager(*confRedisHost)
17 | err = server.RegisterRPCHandler(dm)
18 | if err != nil {
19 | server.Log.Errorf("Register RPC service Error: %s", err)
20 | return
21 | }
22 |
23 | // start to run
24 | err = server.Run()
25 | if err != nil {
26 | server.Log.Fatal(err)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/services/devicemanager/manager_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/rpcs"
5 | "testing"
6 | )
7 |
8 | func TestDeviceManager(t *testing.T) {
9 | mgr := NewDeviceManager("localhost:6379")
10 |
11 | deviceid := uint64(123456)
12 |
13 | args1 := rpcs.ArgsGenerateDeviceAccessToken{
14 | Id: deviceid,
15 | }
16 | reply1 := rpcs.ReplyGenerateDeviceAccessToken{}
17 | err := mgr.GenerateDeviceAccessToken(args1, &reply1)
18 | if err != nil {
19 | t.Fatal(err)
20 | }
21 |
22 | token := reply1.AccessToken
23 |
24 | args2 := rpcs.ArgsValidateDeviceAccessToken{
25 | Id: deviceid,
26 | AccessToken: token,
27 | }
28 | reply2 := rpcs.ReplyValidateDeviceAccessToken{}
29 | err = mgr.ValidateDeviceAccessToken(args2, &reply2)
30 | if err != nil {
31 | t.Fatal(err)
32 | }
33 |
34 | args3 := rpcs.ArgsGetOnline{
35 | Id: deviceid,
36 | ClientIP: "",
37 | AccessRPCHost: "",
38 | HeartbeatInterval: 10,
39 | }
40 | reply3 := rpcs.ReplyGetOnline{}
41 | err = mgr.GetOnline(args3, &reply3)
42 | if err != nil {
43 | t.Fatal(err)
44 | }
45 |
46 | args4 := rpcs.ArgsHeartBeat{
47 | Id: deviceid,
48 | }
49 | reply4 := rpcs.ReplyHeartBeat{}
50 | err = mgr.HeartBeat(args4, &reply4)
51 | if err != nil {
52 | t.Fatal(err)
53 | }
54 |
55 | args5 := rpcs.ArgsGetDeviceStatus{
56 | Id: deviceid,
57 | }
58 | reply5 := rpcs.ReplyGetDeviceStatus{}
59 | err = mgr.GetDeviceStatus(args5, &reply5)
60 | if err != nil {
61 | t.Fatal(err)
62 | }
63 | t.Log(reply5)
64 |
65 | args6 := rpcs.ArgsGetOffline{
66 | Id: deviceid,
67 | }
68 | reply6 := rpcs.ReplyGetOffline{}
69 | err = mgr.GetOffline(args6, &reply6)
70 | if err != nil {
71 | t.Fatal(err)
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/services/httpaccess/flags.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | )
6 |
7 | const (
8 | flagRedisHost = "redishost"
9 |
10 | defaultRedisHost = "localhost:6379"
11 | )
12 |
13 | var (
14 | confRedisHost = flag.String(flagRedisHost, defaultRedisHost, "redis host address, ip:port")
15 | )
16 |
--------------------------------------------------------------------------------
/services/httpaccess/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/server"
5 | "github.com/go-martini/martini"
6 | "github.com/martini-contrib/render"
7 | )
8 |
9 | func main() {
10 | // init server
11 | err := server.Init("httpaccess")
12 | if err != nil {
13 | server.Log.Fatal(err)
14 | return
15 | }
16 |
17 | // martini setup
18 | martini.Env = martini.Prod
19 | handler := martini.Classic()
20 | handler.Use(render.Renderer())
21 | route(handler)
22 |
23 | // register a http handler
24 | err = server.RegisterHTTPHandler(handler)
25 | if err != nil {
26 | server.Log.Errorf("RegisterHTTPHandler Error: %s", err)
27 | return
28 | }
29 |
30 | // go
31 | err = server.Run()
32 | if err != nil {
33 | server.Log.Fatal(err)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/services/httpaccess/response.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // common response fields
4 | type Common struct {
5 | Code int `json:"code"`
6 | Message string `json:"message"`
7 | }
8 |
9 | // device register response data field
10 | type DeviceRegisterData struct {
11 | DeviceId int64 `json:"device_id"`
12 | DeviceSecret string `json:"device_secret"`
13 | DeviceKey string `json:"device_key"`
14 | DeviceIdentifier string `json:"device_identifier"`
15 | }
16 |
17 | // device register response
18 | type DeviceRegisterResponse struct {
19 | Common
20 | Data DeviceRegisterData `json:"data"`
21 | }
22 |
23 | // device auth response data field
24 | type DeviceAuthData struct {
25 | AccessToken string `json:"access_token"`
26 | AccessAddr string `json:"access_addr"`
27 | }
28 |
29 | // device auth response
30 | type DeviceAuthResponse struct {
31 | Common
32 | Data DeviceAuthData `json:"data"`
33 | }
34 |
--------------------------------------------------------------------------------
/services/httpaccess/router.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/go-martini/martini"
5 | "github.com/martini-contrib/binding"
6 | )
7 |
8 | // martini router
9 | func route(m *martini.ClassicMartini) {
10 | // regist a device
11 | m.Post("/v1/devices/registration", binding.Json(DeviceRegisterArgs{}), RegisterDevice)
12 |
13 | // auth device
14 | m.Post("/v1/devices/authentication", binding.Json(DeviceAuthArgs{}), AuthDevice)
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/services/mqttaccess/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/server"
5 | )
6 |
7 | func main() {
8 | // init server
9 | err := server.Init("mqttaccess")
10 | if err != nil {
11 | server.Log.Fatal(err)
12 | return
13 | }
14 |
15 | a, err := NewAccess()
16 | if err != nil {
17 | server.Log.Fatal(err)
18 | return
19 | }
20 |
21 | // register a rpc service
22 | err = server.RegisterRPCHandler(a)
23 | if err != nil {
24 | server.Log.Errorf("Register RPC service Error: %s", err)
25 | return
26 | }
27 |
28 | // register a tcp service for mqtt
29 | err = server.RegisterTCPHandler(a.MqttBroker)
30 | if err != nil {
31 | server.Log.Errorf("Register TCP service Error: %s", err)
32 | return
33 | }
34 |
35 | // start to run
36 | err = server.Run()
37 | if err != nil {
38 | server.Log.Fatal(err)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/services/mqttaccess/status.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/protocol"
5 | )
6 |
7 | var StatusChan map[uint64]chan *protocol.Data
8 |
9 | func init() {
10 | StatusChan = make(map[uint64]chan *protocol.Data)
11 | }
12 |
--------------------------------------------------------------------------------
/services/registry/cache.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "github.com/PandoCloud/pando-cloud/pkg/cache"
6 | )
7 |
8 | const (
9 | flagCacheSize = "cacheSize"
10 | defaultCacheSize = 102400
11 | )
12 |
13 | var (
14 | confCacheSize = flag.Int(flagCacheSize, defaultCacheSize, "maximum size of cache")
15 | )
16 |
17 | var MemCache cache.Cache
18 |
19 | func getCache() cache.Cache {
20 | if MemCache == nil {
21 | MemCache = cache.NewMemCache(*confCacheSize)
22 | }
23 | return MemCache
24 | }
25 |
--------------------------------------------------------------------------------
/services/registry/db.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "github.com/PandoCloud/pando-cloud/pkg/mysql"
6 | "github.com/jinzhu/gorm"
7 | )
8 |
9 | const (
10 | flagDBHost = "dbhost"
11 | flagDBPort = "dbport"
12 | flagDBName = "dbname"
13 | flagDBUser = "dbuser"
14 | flagDBPass = "dbpass"
15 |
16 | defaultDBHost = "localhost"
17 | defaultDBPort = "3306"
18 | defaultDBName = "PandoCloud"
19 | defaultDBUser = "root"
20 | )
21 |
22 | var (
23 | confDBHost = flag.String(flagDBHost, defaultDBHost, "database host address.")
24 | confDBPort = flag.String(flagDBPort, defaultDBPort, "database host port.")
25 | confDBName = flag.String(flagDBName, defaultDBName, "database name.")
26 | confDBUser = flag.String(flagDBUser, defaultDBUser, "database user.")
27 | confDBPass = flag.String(flagDBPass, "", "databse password.")
28 | )
29 |
30 | var DB *gorm.DB
31 |
32 | func getDB() (*gorm.DB, error) {
33 | db, err := mysql.GetClient(*confDBHost, *confDBPort, *confDBName, *confDBUser, *confDBPass)
34 | if err != nil {
35 | return nil, err
36 | }
37 | gormdb, err := gorm.Open("mysql", db)
38 | if err != nil {
39 | return nil, err
40 | }
41 | gormdb.SingularTable(true)
42 | gormdb.LogMode(true)
43 | return gormdb, nil
44 | }
45 |
--------------------------------------------------------------------------------
/services/registry/db_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestWrongDB(t *testing.T) {
8 | *confDBPass = "wrongpassword"
9 |
10 | _, err := getDB()
11 | if err == nil {
12 | t.Errorf("get db should fail with wrong db config")
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/services/registry/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/PandoCloud/pando-cloud/pkg/mysql"
5 | "github.com/PandoCloud/pando-cloud/pkg/server"
6 | )
7 |
8 | func main() {
9 | // init server
10 | err := server.Init("registry")
11 | if err != nil {
12 | server.Log.Fatal(err)
13 | return
14 | }
15 |
16 | err = mysql.MigrateDatabase(*confDBHost, *confDBPort, *confDBName, *confDBUser, *confDBPass)
17 | if err != nil {
18 | server.Log.Fatal(err)
19 | return
20 | }
21 |
22 | // register a rpc service
23 | r, err := NewRegistry()
24 | if err != nil {
25 | server.Log.Fatal(err)
26 | return
27 | }
28 | err = server.RegisterRPCHandler(r)
29 | if err != nil {
30 | server.Log.Errorf("Register RPC service Error: %s", err)
31 | return
32 | }
33 |
34 | // start to run
35 | err = server.Run()
36 | if err != nil {
37 | server.Log.Fatal(err)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/services/registry/utils.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strconv"
5 | )
6 |
7 | func genDeviceIdentifier(vendor int32, product int32, device string) string {
8 | return strconv.FormatInt(int64(vendor), 16) + "-" + strconv.FormatInt(int64(product), 16) + "-" + device
9 | }
10 |
--------------------------------------------------------------------------------
/services/registry/utils_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestGenDeviceIdentifier(t *testing.T) {
8 | vendorid, productid, devicecode := int32(100), int32(100), "ffaf4fffeeaa"
9 | identifier := genDeviceIdentifier(vendorid, productid, devicecode)
10 | if identifier != "64-64-ffaf4fffeeaa" {
11 | t.Errorf("gen identifier error, need %s, got %s ", "64-64-ffaf4fffeeaa", identifier)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/device/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | )
7 |
8 | var (
9 | TestUrl = flag.String("url", "https://localhost", "login url")
10 | TestProductKey = flag.String("productkey", "", "product key")
11 | )
12 |
13 | func main() {
14 | flag.Parse()
15 |
16 | if *TestProductKey == "" {
17 | fmt.Println("product key not provided. use -productkey flag")
18 | return
19 | }
20 |
21 | dev := NewDevice(*TestUrl, *TestProductKey, "ffe34e", "version")
22 |
23 | err := dev.DoRegister()
24 | if err != nil {
25 | fmt.Errorf("device register error %s", err)
26 | return
27 | }
28 |
29 | err = dev.DoLogin()
30 | if err != nil {
31 | fmt.Errorf("device login error %s", err)
32 | return
33 | }
34 |
35 | err = dev.DoAccess()
36 | if err != nil {
37 | fmt.Errorf("device access error %s", err)
38 | return
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/tools/pdcfg/README.md:
--------------------------------------------------------------------------------
1 | # pdcfg
2 | a interactive command line config tool for pando cloud.
3 |
--------------------------------------------------------------------------------
/tools/pdcfg/command_handlers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | )
6 |
7 | type CommandHandler struct {
8 | cmdHandler map[string]func(args []string) error
9 | }
10 |
11 | func NewCommandHander() *CommandHandler {
12 | return &CommandHandler{
13 | cmdHandler: make(map[string](func(args []string) error)),
14 | }
15 | }
16 |
17 | func (ch *CommandHandler) SetHandler(cmd string, handler func(args []string) error) {
18 | ch.cmdHandler[cmd] = handler
19 | }
20 |
21 | func (ch *CommandHandler) GetHandler(cmd string) (func(args []string) error, error) {
22 | handler, exist := ch.cmdHandler[cmd]
23 | if !exist {
24 | return nil, errors.New("command not found: " + cmd)
25 | }
26 | return handler, nil
27 | }
28 |
--------------------------------------------------------------------------------
/tools/pdcfg/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "github.com/PandoCloud/pando-cloud/pkg/server"
7 | "os"
8 | "strings"
9 | )
10 |
11 | func main() {
12 | // init server
13 | err := server.Init("pdcfg")
14 | if err != nil {
15 | fmt.Printf("pdcfg init error : %s\n", err)
16 | return
17 | }
18 |
19 | cmdHandler := NewCommandHander()
20 | cmdHandler.SetHandler("vendor", DoVendorCommand)
21 | cmdHandler.SetHandler("product", DoProductCommand)
22 | cmdHandler.SetHandler("application", DoApplicationCommand)
23 |
24 | reader := bufio.NewReader(os.Stdin)
25 |
26 | for {
27 | fmt.Printf("> ")
28 | line, err := reader.ReadString('\n')
29 | if err != nil {
30 | fmt.Println(err)
31 | continue
32 | }
33 |
34 | fragments := strings.Split(line, " ")
35 | if len(fragments) < 1 {
36 | fmt.Println("wrong command.")
37 | continue
38 | }
39 | cmd := fragments[0]
40 | handler, err := cmdHandler.GetHandler(cmd)
41 | if err != nil {
42 | fmt.Printf("Error: %v \n", err)
43 | continue
44 | }
45 |
46 | args := fragments[1:]
47 | err = handler(args)
48 | if err != nil {
49 | fmt.Println(err)
50 | continue
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tools/pdcfg/utils.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "reflect"
6 | )
7 |
8 | func printStruct(stru interface{}) {
9 | value := reflect.ValueOf(stru)
10 | elem := value.Elem()
11 | for i := 0; i < elem.NumField(); i++ {
12 | switch elem.Field(i).Kind() {
13 | case reflect.String, reflect.Int32, reflect.Int64:
14 | fmt.Printf("%v: %v\n", elem.Type().Field(i).Name, elem.Field(i))
15 | default:
16 | }
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tools/pdcfg/utils_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | type testStruct struct {
8 | aa int
9 | bb string
10 | cc float32
11 | }
12 |
13 | func TestPrintStruct(t *testing.T) {
14 | args := &testStruct{1, "2222", 1.23}
15 | printStruct(args)
16 | }
17 |
--------------------------------------------------------------------------------
/tools/pdcfg/vendor.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "errors"
6 | "fmt"
7 | "github.com/PandoCloud/pando-cloud/pkg/models"
8 | "github.com/PandoCloud/pando-cloud/pkg/server"
9 | "os"
10 | "strings"
11 | )
12 |
13 | func addVendor() error {
14 | args := models.Vendor{}
15 |
16 | reader := bufio.NewReader(os.Stdin)
17 |
18 | fmt.Printf("vendor name: ")
19 | name, err := reader.ReadString('\n')
20 | if err != nil {
21 | return err
22 | }
23 | args.VendorName = strings.Replace(name, "\n", "", -1)
24 |
25 | fmt.Printf("vendor description: ")
26 | desc, err := reader.ReadString('\n')
27 | if err != nil {
28 | return err
29 | }
30 | args.VendorDescription = strings.Replace(desc, "\n", "", -1)
31 |
32 | reply := &models.Vendor{}
33 |
34 | err = server.RPCCallByName("registry", "Registry.SaveVendor", &args, reply)
35 | if err != nil {
36 | return err
37 | }
38 |
39 | fmt.Println("=======> vendor created successfully:")
40 | printStruct(reply)
41 | fmt.Println("=======")
42 |
43 | return nil
44 | }
45 |
46 | func DoVendorCommand(args []string) error {
47 | if len(args) < 1 {
48 | return errors.New("command arguments not enough!")
49 | }
50 |
51 | op := strings.Replace(args[0], "\n", "", -1)
52 |
53 | switch op {
54 | case "add":
55 | if len(args) > 1 {
56 | return errors.New("unnecessary command arguments. just type 'vendor add'")
57 | }
58 | err := addVendor()
59 | if err != nil {
60 | return err
61 | }
62 | default:
63 | return errors.New("operation not suported:" + op)
64 | }
65 |
66 | return nil
67 | }
68 |
--------------------------------------------------------------------------------
/unit_test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This script runs the cover tool on all packages with test files. If you set a
4 | # WEB environment variable, it will additionally open the web-based coverage
5 | # visualizer for each package.
6 |
7 | set -e
8 |
9 | echo 'Please make sure all the core services(redis, mongodb, mysql, etcd) is started before run unit test!!!'
10 |
11 | function go_files { find ./pkg -name '*_test.go' ; }
12 | function filter { grep -v '/_' ; }
13 | function remove_relative_prefix { sed -e 's/^\.\///g' ; }
14 |
15 | function directories {
16 | go_files | filter | remove_relative_prefix | while read f
17 | do
18 | dirname $f
19 | done
20 | }
21 |
22 | function unique_directories { directories | sort | uniq ; }
23 |
24 | PATHS=${1:-$(unique_directories)}
25 |
26 | function report {
27 | for path in $PATHS
28 | do
29 | go test -v -coverprofile=$path/cover.coverprofile ./$path
30 | done
31 | }
32 |
33 | function combine {
34 | gover
35 | }
36 |
37 | function clean {
38 | find . -name cover.coverprofile | xargs rm
39 | }
40 |
41 | report
42 | combine
43 | clean
44 |
45 | if [ -n "${WEB+x}" ]
46 | then
47 | go tool cover -html=gover.coverprofile
48 | fi
--------------------------------------------------------------------------------