├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── ACI Event Driven Worker Queue.mp4 ├── Batch - Demo.pptx ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── LICENSE.md ├── README.md ├── arm ├── azuredeploy.json └── azuredeploy.parameters.json ├── go-worker ├── Dockerfile ├── Gopkg.lock ├── Gopkg.toml ├── Makefile ├── main.go └── vendor │ └── gopkg.in │ └── mgo.v2 │ ├── .travis.yml │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── auth.go │ ├── auth_test.go │ ├── bson │ ├── LICENSE │ ├── bson.go │ ├── bson_test.go │ ├── decimal.go │ ├── decimal_test.go │ ├── decode.go │ ├── encode.go │ ├── json.go │ ├── json_test.go │ ├── specdata │ │ └── update.sh │ └── specdata_test.go │ ├── bulk.go │ ├── bulk_test.go │ ├── cluster.go │ ├── cluster_test.go │ ├── dbtest │ ├── dbserver.go │ ├── dbserver_test.go │ └── export_test.go │ ├── doc.go │ ├── export_test.go │ ├── gridfs.go │ ├── gridfs_test.go │ ├── harness │ ├── certs │ │ ├── client.crt │ │ ├── client.key │ │ ├── client.pem │ │ ├── client.req │ │ ├── server.crt │ │ ├── server.key │ │ └── server.pem │ ├── daemons │ │ ├── cfg1 │ │ │ ├── db │ │ │ │ ├── .empty │ │ │ │ ├── journal │ │ │ │ │ └── tempLatencyTest │ │ │ │ └── mongod.lock │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── cfg2 │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── cfg3 │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── db1 │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── db2 │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── db3 │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs1a │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs1b │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs1c │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs2a │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs2b │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs2c │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs3a │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs3b │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs3c │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── rs4a │ │ │ ├── db │ │ │ │ └── .empty │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── s1 │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ ├── s2 │ │ │ ├── log │ │ │ │ └── run │ │ │ └── run │ │ └── s3 │ │ │ ├── log │ │ │ └── run │ │ │ └── run │ ├── mongojs │ │ ├── dropall.js │ │ ├── init.js │ │ └── wait.js │ └── setup.sh │ ├── internal │ ├── json │ │ ├── LICENSE │ │ ├── bench_test.go │ │ ├── decode.go │ │ ├── decode_test.go │ │ ├── encode.go │ │ ├── encode_test.go │ │ ├── example_test.go │ │ ├── extension.go │ │ ├── extension_test.go │ │ ├── fold.go │ │ ├── fold_test.go │ │ ├── indent.go │ │ ├── number_test.go │ │ ├── scanner.go │ │ ├── scanner_test.go │ │ ├── stream.go │ │ ├── stream_test.go │ │ ├── tagkey_test.go │ │ ├── tags.go │ │ ├── tags_test.go │ │ └── testdata │ │ │ └── code.json.gz │ ├── sasl │ │ ├── sasl.c │ │ ├── sasl.go │ │ ├── sasl_windows.c │ │ ├── sasl_windows.go │ │ ├── sasl_windows.h │ │ ├── sspi_windows.c │ │ └── sspi_windows.h │ └── scram │ │ ├── scram.go │ │ └── scram_test.go │ ├── log.go │ ├── queue.go │ ├── queue_test.go │ ├── raceoff.go │ ├── raceon.go │ ├── saslimpl.go │ ├── saslstub.go │ ├── server.go │ ├── session.go │ ├── session_test.go │ ├── socket.go │ ├── stats.go │ ├── suite_test.go │ ├── syscall_test.go │ ├── syscall_windows_test.go │ └── txn │ ├── chaos.go │ ├── debug.go │ ├── dockey_test.go │ ├── flusher.go │ ├── output.txt │ ├── sim_test.go │ ├── tarjan.go │ ├── tarjan_test.go │ ├── txn.go │ └── txn_test.go ├── images └── diagram.png ├── spawner-functions ├── host.json ├── package-lock.json ├── package.json ├── sbqTriggerCreateWorkerContainer │ ├── function.json │ └── index.js └── sbqTriggerDeleteWorkerContainer │ ├── function.json │ └── index.js ├── spawner ├── .dockerignore ├── Dockerfile ├── Makefile ├── config │ ├── __init__.py │ └── config.py ├── create-aci.sh ├── example-config.py ├── requirements.txt ├── run.py └── test.py └── web-server ├── .dockerignore ├── Dockerfile ├── Makefile ├── aci-create.sh ├── config ├── __init__.py └── config.py ├── example-config.py ├── requirements.txt ├── run.py ├── static └── vendor │ ├── jquery │ ├── jquery.js │ └── jquery.min.js │ └── materialize │ ├── materialize.min.css │ └── materialize.min.js ├── templates └── index.html └── util.ps1 /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | > Please provide us with the following information: 5 | > --------------------------------------------------------------- 6 | 7 | ### This issue is for a: (mark with an `x`) 8 | ``` 9 | - [ ] bug report -> please search issues before submitting 10 | - [ ] feature request 11 | - [ ] documentation issue or request 12 | - [ ] regression (a behavior that used to work and stopped in a new release) 13 | ``` 14 | 15 | ### Minimal steps to reproduce 16 | > 17 | 18 | ### Any log messages given by the failure 19 | > 20 | 21 | ### Expected/desired behavior 22 | > 23 | 24 | ### OS and Version? 25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) 26 | 27 | ### Versions 28 | > 29 | 30 | ### Mention any other details that might be useful 31 | 32 | > --------------------------------------------------------------- 33 | > Thanks! We'll be in touch soon. 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | 3 | * ... 4 | 5 | ## Does this introduce a breaking change? 6 | 7 | ``` 8 | [ ] Yes 9 | [ ] No 10 | ``` 11 | 12 | ## Pull Request Type 13 | What kind of change does this Pull Request introduce? 14 | 15 | 16 | ``` 17 | [ ] Bugfix 18 | [ ] Feature 19 | [ ] Code style update (formatting, local variables) 20 | [ ] Refactoring (no functional changes, no api changes) 21 | [ ] Documentation content changes 22 | [ ] Other... Please describe: 23 | ``` 24 | 25 | ## How to Test 26 | * Get the code 27 | 28 | ``` 29 | git clone [repo-address] 30 | cd [repo-name] 31 | git checkout [branch-name] 32 | npm install 33 | ``` 34 | 35 | * Test the code 36 | 37 | ``` 38 | ``` 39 | 40 | ## What to Check 41 | Verify that the following are valid 42 | * ... 43 | 44 | ## Other Information 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | **/.env 3 | 4 | go-worker/vender/ 5 | 6 | # Byte-compiled / optimized / DLL files 7 | __pycache__/ 8 | *.py[cod] 9 | *$py.class 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | env/ 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | .hypothesis/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # pyenv 79 | .python-version 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # dotenv 88 | .env 89 | 90 | # virtualenv 91 | .venv 92 | venv/ 93 | ENV/ 94 | 95 | # Spyder project settings 96 | .spyderproject 97 | .spyproject 98 | 99 | # Rope project settings 100 | .ropeproject 101 | 102 | # mkdocs documentation 103 | /site 104 | 105 | # mypy 106 | .mypy_cache/ 107 | 108 | #node_modules 109 | node_modules/ 110 | 111 | .vscode/ -------------------------------------------------------------------------------- /ACI Event Driven Worker Queue.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/ACI Event Driven Worker Queue.mp4 -------------------------------------------------------------------------------- /Batch - Demo.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/Batch - Demo.pptx -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## ACI Event Driven Worker Queue Changelog 2 | 3 | # Initial commit (2018-04-16) 4 | 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to ACI Event Driven Worker Queue 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 5 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 6 | 7 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 8 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 9 | provided by the bot. You will only need to do this once across all repos using our CLA. 10 | 11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 14 | 15 | - [Code of Conduct](#coc) 16 | - [Issues and Bugs](#issue) 17 | - [Feature Requests](#feature) 18 | - [Submission Guidelines](#submit) 19 | 20 | ## Code of Conduct 21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 22 | 23 | ## Found an Issue? 24 | If you find a bug in the source code or a mistake in the documentation, you can help us by 25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can 26 | [submit a Pull Request](#submit-pr) with a fix. 27 | 28 | ## Want a Feature? 29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub 30 | Repository. If you would like to *implement* a new feature, please submit an issue with 31 | a proposal for your work first, to be sure that we can use it. 32 | 33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). 34 | 35 | ## Submission Guidelines 36 | 37 | ### Submitting an Issue 38 | Before you submit an issue, search the archive, maybe your question was already answered. 39 | 40 | If your issue appears to be a bug, and hasn't been reported, open a new issue. 41 | Help us to maximize the effort we can spend fixing issues and adding new 42 | features, by not reporting duplicate issues. Providing the following information will increase the 43 | chances of your issue being dealt with quickly: 44 | 45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps 46 | * **Version** - what version is affected (e.g. 0.1.2) 47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you 48 | * **Browsers and Operating System** - is this a problem with all browsers? 49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps 50 | * **Related Issues** - has a similar issue been reported before? 51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be 52 | causing the problem (line of code or commit) 53 | 54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/Azure-Samples/aci-event-driven-worker-queue/issues/new]. 55 | 56 | ### Submitting a Pull Request (PR) 57 | Before you submit your Pull Request (PR) consider the following guidelines: 58 | 59 | * Search the repository (https://github.com/Azure-Samples/aci-event-driven-worker-queue/pulls) for an open or closed PR 60 | that relates to your submission. You don't want to duplicate effort. 61 | 62 | * Make your changes in a new git fork: 63 | 64 | * Commit your changes using a descriptive commit message 65 | * Push your fork to GitHub: 66 | * In GitHub, create a pull request 67 | * If we suggest changes then: 68 | * Make the required updates. 69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request): 70 | 71 | ```shell 72 | git rebase master -i 73 | git push -f 74 | ``` 75 | 76 | That's it! Thank you for your contribution! 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sam Kreter 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 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 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 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | languages: 4 | - html 5 | - python 6 | - javascript 7 | - go 8 | products: 9 | - azure 10 | description: "web-server: This is the host for the dashboard and the api. The dashboard will let you add work to the queue. When work is added a yellow pending container will show up." 11 | urlFragment: aci-event-driven-worker-queue 12 | --- 13 | 14 | # ACI Event Driven Worker Queue 15 | 16 | ## Components 17 | 18 | 1. web-server: This is the host for the dashboard and the api. The dashboard will let you add work to the queue. When work is added a yellow pending container will show up. This is a default place holder until the actual ACI instance comes up and adds it's InProgress state to the DB to be read. Once the container has reached InProgress, the UI will chagne the default pending to Blue with the container's name in place. You can also hit the "More Details" Button to open the model with that containers ID. Currently the modal is calling to the metrics api endpoint for that specific container. 19 | 20 | 2. go-worker: This is the container to be spawned by the azure function watching the service bus queue. Its takes the enviorment variables: MESSAGE: The message from the queue, CONTAINER_NAME: container group name, DATABASE_URI: CosmosDb mongo connection string. *IMPORTANT:* You must remove the ssl=true url param from the connection string or it will break. When the container is started, it will add a state entry to the DB with its name and InProgress. It then waits a set number of seconds and Adds Done as its state to the DB. 21 | 22 | 3. Spawner-functions: This consists of two functions. One is watching a queue to create aci instances and another is watching a queue to delete aci instances. 23 | 24 | ![](images/diagram.png) 25 | 26 | 27 | ## Setup Docker Images 28 | 29 | Follow the steps below if you want to build your own docker images. 30 | 31 | 1. Setup `web-server` image 32 | - Build image. 33 | ```console 34 | cd web-server 35 | docker build -t /web-server:latest . 36 | ``` 37 | - Push image to Docker Hub. 38 | ```console 39 | docker push /web-server:latest 40 | ``` 41 | - Open the file [azuredeploy.parameters.json](arm/azuredeploy.parameters.json) in `arm` folder, and update the value of the parameter `webServerImage` to point to the new image. 42 | ```javascript 43 | "webServerImage": { 44 | "value": "/web-server" 45 | } 46 | ``` 47 | 48 | 1. Setup `go-worker` image 49 | - Build image 50 | ```console 51 | cd ../go-worker 52 | docker build -t /go-worker:latest . 53 | ``` 54 | - Upload image to repository 55 | ```console 56 | docker push /go-worker:latest 57 | ``` 58 | - Open the file [index.js](spawner-functions/sbqTriggerCreateWorkerContainer/index.js) in `spawner-functions/sbqTriggerCreateWorkerContainer` folder, and update this line to point to the new image. 59 | ```javascript 60 | const IMAGE = "/go-worker:latest"; 61 | ``` 62 | 63 | ## Deployment Steps 64 | 65 | 1. Open and login to [Azure Cloud Shell](https://shell.azure.com). 66 | 67 | 2. Clone the repo. 68 | ```console 69 | git clone https://github.com/Azure-Samples/aci-event-driven-worker-queue.git 70 | 71 | cd aci-event-driven-worker-queue 72 | ``` 73 | 74 | 3. Create resource group. 75 | ```console 76 | az group create -l westus -n aci-event-driven 77 | ``` 78 | 79 | 4. Create a service principal. 80 | ```console 81 | az ad sp create-for-rbac -n aci-event-driven --role contributor 82 | ``` 83 | Output sample: 84 | ``` 85 | { 86 | "appId": "fb7c4111-2144-4489-8fd9-XXXXXXXXX", 87 | "displayName": "aci-event-driven", 88 | "name": "http://aci-event-driven", 89 | "password": "0fa91eda-261e-47ad-bb65-XXXXXXXX", 90 | "tenant": "3dad2b09-9e66-4eb8-9bef-XXXXXXX" 91 | } 92 | ``` 93 | 94 | 5. Cd into the `arm` directory and update the `azuredeploy.parameters.json` in the folder `arm` with the service principal credential created above (appId, password, tenant), and assign an unique name for the parameters `functionAppName` and `dnsNameLabel` (for the website). 95 | 96 | 6. Deploy the Azure resources with the ARM template. This will take a few minutes. 97 | ```console 98 | az group deployment create --template-file azuredeploy.json --parameters @azuredeploy.parameters.json -g aci-event-driven 99 | ``` 100 | Output sample 101 | ``` 102 | "outputs": { 103 | "fqdn": { 104 | "type": "String", 105 | "value": "web-servertmaalsmhtzqta.westus.azurecontainer.io" 106 | } 107 | } 108 | ``` 109 | > Note: The output `fqdn` is the URL of the ACI dashboard. 110 | 111 | 7. Download NPM packages. 112 | ```console 113 | cd ../spawner-functions 114 | 115 | npm install 116 | ``` 117 | 118 | 8. Compress the files inside the `spawner-functions` folder as a .zip file. 119 | ```console 120 | zip -r spawner-functions-compressed.zip . 121 | ``` 122 | 123 | 9. Set deployment credential if you don't have one or forget. 124 | >Note: All function and web apps in the subscription will be impacted since they share the same deployment credentials. 125 | 126 | ```console 127 | az webapp deployment user set --user-name --password 128 | ``` 129 | 130 | 9. Deploy the .zip file to Azure Functions, and type in the deployment user password when prompted by cURL. 131 | ```console 132 | curl -X POST -u --data-binary @"spawner-functions-compressed.zip" https://.scm.azurewebsites.net/api/zipdeploy 133 | ``` 134 | > Note: The `` is the `functionAppName` parameter you used for ARM template deployment previously. 135 | -------------------------------------------------------------------------------- /arm/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "client_id": { 6 | "value": "" 7 | }, 8 | "client_secret": { 9 | "value": "" 10 | }, 11 | "tenant": { 12 | "value": "" 13 | }, 14 | "webServerImage": { 15 | "value": "hubertsui/web-server" 16 | }, 17 | "functionAppName": { 18 | "value": "acidemofunctionapp" 19 | }, 20 | "dnsNameLabel": { 21 | "value": "acidemowebserver" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /go-worker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.9.2 as builder 2 | WORKDIR /go/src/github.com/samkreter/event-driven-aci 3 | COPY . /go/src/github.com/samkreter/event-driven-aci 4 | #RUN go get -u github.com/golang/dep/cmd/dep 5 | #RUN dep ensure 6 | # RUN go test ./... 7 | RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o worker . 8 | 9 | FROM alpine:latest 10 | RUN apk --update add ca-certificates 11 | WORKDIR /root/ 12 | COPY --from=builder /go/src/github.com/samkreter/event-driven-aci . 13 | CMD ["./worker"] 14 | -------------------------------------------------------------------------------- /go-worker/Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | branch = "v2" 6 | name = "gopkg.in/mgo.v2" 7 | packages = [ 8 | ".", 9 | "bson", 10 | "internal/json", 11 | "internal/sasl", 12 | "internal/scram" 13 | ] 14 | revision = "3f83fa5005286a7fe593b055f0d7771a7dce4655" 15 | 16 | [solve-meta] 17 | analyzer-name = "dep" 18 | analyzer-version = 1 19 | inputs-digest = "f6e466625d21d47bfbaf0ac269619cea8e2f0342460342ef2f67118f40d0e294" 20 | solver-name = "gps-cdcl" 21 | solver-version = 1 22 | -------------------------------------------------------------------------------- /go-worker/Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | 22 | 23 | [[constraint]] 24 | branch = "v2" 25 | name = "gopkg.in/mgo.v2" 26 | -------------------------------------------------------------------------------- /go-worker/Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | docker build -t pskreter/worker-container:latest . 3 | 4 | push: 5 | docker push pskreter/worker-container:latest 6 | 7 | test: 8 | docker run --rm -e CONTAINER_NAME=test -e MESSAGE=test1 -e DATABASE_URI=${MONGO_URI} --name worker-go pskreter/worker-container 9 | 10 | run: 11 | docker run --rm --name worker-containe pskreter/worker-container:latest -------------------------------------------------------------------------------- /go-worker/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/md5" 5 | "crypto/tls" 6 | "fmt" 7 | "log" 8 | "net" 9 | "os" 10 | "time" 11 | 12 | "gopkg.in/mgo.v2/bson" 13 | 14 | "gopkg.in/mgo.v2" 15 | ) 16 | 17 | // State store the current state of a container group in the mongo database 18 | // Current states include InProgress and Done 19 | type State struct { 20 | Name string `json:"name"` 21 | State string `json:"sate"` 22 | } 23 | 24 | func main() { 25 | 26 | work, ok := os.LookupEnv("MESSAGE") 27 | if !ok { 28 | log.Fatal("Env Variable MESSAGE Not Set.") 29 | } 30 | 31 | containerName, ok := os.LookupEnv("CONTAINER_NAME") 32 | if !ok { 33 | log.Fatal("Env Variable CONTAINER_NAME Not Set.") 34 | } 35 | 36 | //Make sure not not have the ssl=true param in the url 37 | mongoURI, ok := os.LookupEnv("DATABASE_URI") 38 | if !ok { 39 | log.Fatal("Env Variable DATABASE_URI Not Set.") 40 | } 41 | 42 | // Sanity checks 43 | log.Println("Processing work: ", work) 44 | log.Println("Container Name: ", containerName) 45 | 46 | dialInfo, err := mgo.ParseURL(mongoURI) 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | 51 | dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) { 52 | return tls.Dial("tcp", addr.String(), &tls.Config{}) 53 | } 54 | 55 | session, err := mgo.DialWithInfo(dialInfo) 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | defer session.Close() 60 | 61 | session.SetSafe(&mgo.Safe{}) 62 | 63 | c := session.DB("containerstate").C("containerstate") 64 | 65 | log.Println("Adding Recored to Databases") 66 | 67 | //Record container started the work 68 | err = c.Update(bson.M{"name": containerName}, bson.M{"$set": bson.M{"state": "InProgress"}}) 69 | if err != nil { 70 | log.Fatal(err) 71 | } 72 | 73 | var states []State 74 | err = c.Find(bson.M{}).All(&states) 75 | if err != nil { 76 | log.Fatal(err) 77 | } 78 | 79 | //Perfom some hashing as work 80 | stop := make(chan bool) 81 | t := []byte(work) 82 | 83 | go func() { 84 | hash := md5.New() 85 | for { 86 | select { 87 | case <-stop: 88 | return 89 | default: 90 | time.Sleep(time.Second * 1) 91 | for i := 0; i < 20; i++ { 92 | t = hash.Sum(t) 93 | fmt.Printf("%x\n", t) 94 | } 95 | } 96 | } 97 | }() 98 | 99 | time.Sleep(time.Second * 5) 100 | stop <- true 101 | 102 | time.Sleep(time.Second * 2) 103 | // Record finish work in the database 104 | c.Update(bson.M{"name": containerName}, bson.M{"$set": bson.M{"state": "Done", "output": fmt.Sprintf("%x\n", t)}}) 105 | } 106 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go_import_path: gopkg.in/mgo.v2 4 | 5 | addons: 6 | apt: 7 | packages: 8 | 9 | env: 10 | global: 11 | - BUCKET=https://niemeyer.s3.amazonaws.com 12 | matrix: 13 | - GO=1.4.1 MONGODB=x86_64-2.2.7 14 | - GO=1.4.1 MONGODB=x86_64-2.4.14 15 | - GO=1.4.1 MONGODB=x86_64-2.6.11 16 | - GO=1.4.1 MONGODB=x86_64-3.0.9 17 | - GO=1.4.1 MONGODB=x86_64-3.2.3-nojournal 18 | - GO=1.5.3 MONGODB=x86_64-3.0.9 19 | - GO=1.6 MONGODB=x86_64-3.0.9 20 | 21 | install: 22 | - eval "$(gimme $GO)" 23 | 24 | - wget $BUCKET/mongodb-linux-$MONGODB.tgz 25 | - tar xzvf mongodb-linux-$MONGODB.tgz 26 | - export PATH=$PWD/mongodb-linux-$MONGODB/bin:$PATH 27 | 28 | - wget $BUCKET/daemontools.tar.gz 29 | - tar xzvf daemontools.tar.gz 30 | - export PATH=$PWD/daemontools:$PATH 31 | 32 | - go get gopkg.in/check.v1 33 | - go get gopkg.in/yaml.v2 34 | - go get gopkg.in/tomb.v2 35 | 36 | before_script: 37 | - export NOIPV6=1 38 | - make startdb 39 | 40 | script: 41 | - (cd bson && go test -check.v) 42 | - go test -check.v -fast 43 | - (cd txn && go test -check.v) 44 | 45 | # vim:sw=4:ts=4:et 46 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/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 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/Makefile: -------------------------------------------------------------------------------- 1 | startdb: 2 | @harness/setup.sh start 3 | 4 | stopdb: 5 | @harness/setup.sh stop 6 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/README.md: -------------------------------------------------------------------------------- 1 | The MongoDB driver for Go 2 | ------------------------- 3 | 4 | Please go to [http://labix.org/mgo](http://labix.org/mgo) for all project details. 5 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/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 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/bson/json_test.go: -------------------------------------------------------------------------------- 1 | package bson_test 2 | 3 | import ( 4 | "gopkg.in/mgo.v2/bson" 5 | 6 | . "gopkg.in/check.v1" 7 | "reflect" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | type jsonTest struct { 13 | a interface{} // value encoded into JSON (optional) 14 | b string // JSON expected as output of , and used as input to 15 | c interface{} // Value expected from decoding , defaults to 16 | e string // error string, if decoding (b) should fail 17 | } 18 | 19 | var jsonTests = []jsonTest{ 20 | // $binary 21 | { 22 | a: []byte("foo"), 23 | b: `{"$binary":"Zm9v","$type":"0x0"}`, 24 | }, { 25 | a: bson.Binary{Kind: 2, Data: []byte("foo")}, 26 | b: `{"$binary":"Zm9v","$type":"0x2"}`, 27 | }, { 28 | b: `BinData(2,"Zm9v")`, 29 | c: bson.Binary{Kind: 2, Data: []byte("foo")}, 30 | }, 31 | 32 | // $date 33 | { 34 | a: time.Date(2016, 5, 15, 1, 2, 3, 4000000, time.UTC), 35 | b: `{"$date":"2016-05-15T01:02:03.004Z"}`, 36 | }, { 37 | b: `{"$date": {"$numberLong": "1002"}}`, 38 | c: time.Date(1970, 1, 1, 0, 0, 1, 2e6, time.UTC), 39 | }, { 40 | b: `ISODate("2016-05-15T01:02:03.004Z")`, 41 | c: time.Date(2016, 5, 15, 1, 2, 3, 4000000, time.UTC), 42 | }, { 43 | b: `new Date(1000)`, 44 | c: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), 45 | }, { 46 | b: `new Date("2016-05-15")`, 47 | c: time.Date(2016, 5, 15, 0, 0, 0, 0, time.UTC), 48 | }, 49 | 50 | // $timestamp 51 | { 52 | a: bson.MongoTimestamp(4294967298), 53 | b: `{"$timestamp":{"t":1,"i":2}}`, 54 | }, { 55 | b: `Timestamp(1, 2)`, 56 | c: bson.MongoTimestamp(4294967298), 57 | }, 58 | 59 | // $regex 60 | { 61 | a: bson.RegEx{"pattern", "options"}, 62 | b: `{"$regex":"pattern","$options":"options"}`, 63 | }, 64 | 65 | // $oid 66 | { 67 | a: bson.ObjectIdHex("0123456789abcdef01234567"), 68 | b: `{"$oid":"0123456789abcdef01234567"}`, 69 | }, { 70 | b: `ObjectId("0123456789abcdef01234567")`, 71 | c: bson.ObjectIdHex("0123456789abcdef01234567"), 72 | }, 73 | 74 | // $ref (no special type) 75 | { 76 | b: `DBRef("name", "id")`, 77 | c: map[string]interface{}{"$ref": "name", "$id": "id"}, 78 | }, 79 | 80 | // $numberLong 81 | { 82 | a: 123, 83 | b: `123`, 84 | }, { 85 | a: int64(9007199254740992), 86 | b: `{"$numberLong":9007199254740992}`, 87 | }, { 88 | a: int64(1<<53 + 1), 89 | b: `{"$numberLong":"9007199254740993"}`, 90 | }, { 91 | a: 1<<53 + 1, 92 | b: `{"$numberLong":"9007199254740993"}`, 93 | c: int64(9007199254740993), 94 | }, { 95 | b: `NumberLong(9007199254740992)`, 96 | c: int64(1 << 53), 97 | }, { 98 | b: `NumberLong("9007199254740993")`, 99 | c: int64(1<<53 + 1), 100 | }, 101 | 102 | // $minKey, $maxKey 103 | { 104 | a: bson.MinKey, 105 | b: `{"$minKey":1}`, 106 | }, { 107 | a: bson.MaxKey, 108 | b: `{"$maxKey":1}`, 109 | }, { 110 | b: `MinKey`, 111 | c: bson.MinKey, 112 | }, { 113 | b: `MaxKey`, 114 | c: bson.MaxKey, 115 | }, { 116 | b: `{"$minKey":0}`, 117 | e: `invalid $minKey object: {"$minKey":0}`, 118 | }, { 119 | b: `{"$maxKey":0}`, 120 | e: `invalid $maxKey object: {"$maxKey":0}`, 121 | }, 122 | 123 | { 124 | a: bson.Undefined, 125 | b: `{"$undefined":true}`, 126 | }, { 127 | b: `undefined`, 128 | c: bson.Undefined, 129 | }, { 130 | b: `{"v": undefined}`, 131 | c: struct{ V interface{} }{bson.Undefined}, 132 | }, 133 | 134 | // Unquoted keys and trailing commas 135 | { 136 | b: `{$foo: ["bar",],}`, 137 | c: map[string]interface{}{"$foo": []interface{}{"bar"}}, 138 | }, 139 | } 140 | 141 | func (s *S) TestJSON(c *C) { 142 | for i, item := range jsonTests { 143 | c.Logf("------------ (#%d)", i) 144 | c.Logf("A: %#v", item.a) 145 | c.Logf("B: %#v", item.b) 146 | 147 | if item.c == nil { 148 | item.c = item.a 149 | } else { 150 | c.Logf("C: %#v", item.c) 151 | } 152 | if item.e != "" { 153 | c.Logf("E: %s", item.e) 154 | } 155 | 156 | if item.a != nil { 157 | data, err := bson.MarshalJSON(item.a) 158 | c.Assert(err, IsNil) 159 | c.Logf("Dumped: %#v", string(data)) 160 | c.Assert(strings.TrimSuffix(string(data), "\n"), Equals, item.b) 161 | } 162 | 163 | var zero interface{} 164 | if item.c == nil { 165 | zero = &struct{}{} 166 | } else { 167 | zero = reflect.New(reflect.TypeOf(item.c)).Interface() 168 | } 169 | err := bson.UnmarshalJSON([]byte(item.b), zero) 170 | if item.e != "" { 171 | c.Assert(err, NotNil) 172 | c.Assert(err.Error(), Equals, item.e) 173 | continue 174 | } 175 | c.Assert(err, IsNil) 176 | zerov := reflect.ValueOf(zero) 177 | value := zerov.Interface() 178 | if zerov.Kind() == reflect.Ptr { 179 | value = zerov.Elem().Interface() 180 | } 181 | c.Logf("Loaded: %#v", value) 182 | c.Assert(value, DeepEquals, item.c) 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/bson/specdata/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ ! -d specifications ]; then 6 | git clone -b bson git@github.com:jyemin/specifications 7 | fi 8 | 9 | TESTFILE="../specdata_test.go" 10 | 11 | cat < $TESTFILE 12 | package bson_test 13 | 14 | var specTests = []string{ 15 | END 16 | 17 | for file in specifications/source/bson/tests/*.yml; do 18 | ( 19 | echo '`' 20 | cat $file 21 | echo -n '`,' 22 | ) >> $TESTFILE 23 | done 24 | 25 | echo '}' >> $TESTFILE 26 | 27 | gofmt -w $TESTFILE 28 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/bson/specdata_test.go: -------------------------------------------------------------------------------- 1 | package bson_test 2 | 3 | var specTests = []string{ 4 | ` 5 | --- 6 | description: "Array type" 7 | documents: 8 | - 9 | decoded: 10 | a : [] 11 | encoded: 0D000000046100050000000000 12 | - 13 | decoded: 14 | a: [10] 15 | encoded: 140000000461000C0000001030000A0000000000 16 | - 17 | # Decode an array that uses an empty string as the key 18 | decodeOnly : true 19 | decoded: 20 | a: [10] 21 | encoded: 130000000461000B00000010000A0000000000 22 | - 23 | # Decode an array that uses a non-numeric string as the key 24 | decodeOnly : true 25 | decoded: 26 | a: [10] 27 | encoded: 150000000461000D000000106162000A0000000000 28 | 29 | 30 | `, ` 31 | --- 32 | description: "Boolean type" 33 | documents: 34 | - 35 | encoded: "090000000862000100" 36 | decoded: { "b" : true } 37 | - 38 | encoded: "090000000862000000" 39 | decoded: { "b" : false } 40 | 41 | 42 | `, ` 43 | --- 44 | description: "Corrupted BSON" 45 | documents: 46 | - 47 | encoded: "09000000016600" 48 | error: "truncated double" 49 | - 50 | encoded: "09000000026600" 51 | error: "truncated string" 52 | - 53 | encoded: "09000000036600" 54 | error: "truncated document" 55 | - 56 | encoded: "09000000046600" 57 | error: "truncated array" 58 | - 59 | encoded: "09000000056600" 60 | error: "truncated binary" 61 | - 62 | encoded: "09000000076600" 63 | error: "truncated objectid" 64 | - 65 | encoded: "09000000086600" 66 | error: "truncated boolean" 67 | - 68 | encoded: "09000000096600" 69 | error: "truncated date" 70 | - 71 | encoded: "090000000b6600" 72 | error: "truncated regex" 73 | - 74 | encoded: "090000000c6600" 75 | error: "truncated db pointer" 76 | - 77 | encoded: "0C0000000d6600" 78 | error: "truncated javascript" 79 | - 80 | encoded: "0C0000000e6600" 81 | error: "truncated symbol" 82 | - 83 | encoded: "0C0000000f6600" 84 | error: "truncated javascript with scope" 85 | - 86 | encoded: "0C000000106600" 87 | error: "truncated int32" 88 | - 89 | encoded: "0C000000116600" 90 | error: "truncated timestamp" 91 | - 92 | encoded: "0C000000126600" 93 | error: "truncated int64" 94 | - 95 | encoded: "0400000000" 96 | error: basic 97 | - 98 | encoded: "0500000001" 99 | error: basic 100 | - 101 | encoded: "05000000" 102 | error: basic 103 | - 104 | encoded: "0700000002610078563412" 105 | error: basic 106 | - 107 | encoded: "090000001061000500" 108 | error: basic 109 | - 110 | encoded: "00000000000000000000" 111 | error: basic 112 | - 113 | encoded: "1300000002666f6f00040000006261720000" 114 | error: "basic" 115 | - 116 | encoded: "1800000003666f6f000f0000001062617200ffffff7f0000" 117 | error: basic 118 | - 119 | encoded: "1500000003666f6f000c0000000862617200010000" 120 | error: basic 121 | - 122 | encoded: "1c00000003666f6f001200000002626172000500000062617a000000" 123 | error: basic 124 | - 125 | encoded: "1000000002610004000000616263ff00" 126 | error: string is not null-terminated 127 | - 128 | encoded: "0c0000000200000000000000" 129 | error: bad_string_length 130 | - 131 | encoded: "120000000200ffffffff666f6f6261720000" 132 | error: bad_string_length 133 | - 134 | encoded: "0c0000000e00000000000000" 135 | error: bad_string_length 136 | - 137 | encoded: "120000000e00ffffffff666f6f6261720000" 138 | error: bad_string_length 139 | - 140 | encoded: "180000000c00fa5bd841d6585d9900" 141 | error: "" 142 | - 143 | encoded: "1e0000000c00ffffffff666f6f626172005259b56afa5bd841d6585d9900" 144 | error: bad_string_length 145 | - 146 | encoded: "0c0000000d00000000000000" 147 | error: bad_string_length 148 | - 149 | encoded: "0c0000000d00ffffffff0000" 150 | error: bad_string_length 151 | - 152 | encoded: "1c0000000f001500000000000000000c000000020001000000000000" 153 | error: bad_string_length 154 | - 155 | encoded: "1c0000000f0015000000ffffffff000c000000020001000000000000" 156 | error: bad_string_length 157 | - 158 | encoded: "1c0000000f001500000001000000000c000000020000000000000000" 159 | error: bad_string_length 160 | - 161 | encoded: "1c0000000f001500000001000000000c0000000200ffffffff000000" 162 | error: bad_string_length 163 | - 164 | encoded: "0E00000008616263646566676869707172737475" 165 | error: "Run-on CString" 166 | - 167 | encoded: "0100000000" 168 | error: "An object size that's too small to even include the object size, but is correctly encoded, along with a correct EOO (and no data)" 169 | - 170 | encoded: "1a0000000e74657374000c00000068656c6c6f20776f726c6400000500000000" 171 | error: "One object, but with object size listed smaller than it is in the data" 172 | - 173 | encoded: "05000000" 174 | error: "One object, missing the EOO at the end" 175 | - 176 | encoded: "0500000001" 177 | error: "One object, sized correctly, with a spot for an EOO, but the EOO is 0x01" 178 | - 179 | encoded: "05000000ff" 180 | error: "One object, sized correctly, with a spot for an EOO, but the EOO is 0xff" 181 | - 182 | encoded: "0500000070" 183 | error: "One object, sized correctly, with a spot for an EOO, but the EOO is 0x70" 184 | - 185 | encoded: "07000000000000" 186 | error: "Invalid BSON type low range" 187 | - 188 | encoded: "07000000800000" 189 | error: "Invalid BSON type high range" 190 | - 191 | encoded: "090000000862000200" 192 | error: "Invalid boolean value of 2" 193 | - 194 | encoded: "09000000086200ff00" 195 | error: "Invalid boolean value of -1" 196 | `, ` 197 | --- 198 | description: "Int32 type" 199 | documents: 200 | - 201 | decoded: 202 | i: -2147483648 203 | encoded: 0C0000001069000000008000 204 | - 205 | decoded: 206 | i: 2147483647 207 | encoded: 0C000000106900FFFFFF7F00 208 | - 209 | decoded: 210 | i: -1 211 | encoded: 0C000000106900FFFFFFFF00 212 | - 213 | decoded: 214 | i: 0 215 | encoded: 0C0000001069000000000000 216 | - 217 | decoded: 218 | i: 1 219 | encoded: 0C0000001069000100000000 220 | 221 | `, ` 222 | --- 223 | description: "String type" 224 | documents: 225 | - 226 | decoded: 227 | s : "" 228 | encoded: 0D000000027300010000000000 229 | - 230 | decoded: 231 | s: "a" 232 | encoded: 0E00000002730002000000610000 233 | - 234 | decoded: 235 | s: "This is a string" 236 | encoded: 1D0000000273001100000054686973206973206120737472696E670000 237 | - 238 | decoded: 239 | s: "κόσμε" 240 | encoded: 180000000273000C000000CEBAE1BDB9CF83CEBCCEB50000 241 | `} 242 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/dbtest/dbserver.go: -------------------------------------------------------------------------------- 1 | package dbtest 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "net" 7 | "os" 8 | "os/exec" 9 | "strconv" 10 | "time" 11 | 12 | "gopkg.in/mgo.v2" 13 | "gopkg.in/tomb.v2" 14 | ) 15 | 16 | // DBServer controls a MongoDB server process to be used within test suites. 17 | // 18 | // The test server is started when Session is called the first time and should 19 | // remain running for the duration of all tests, with the Wipe method being 20 | // called between tests (before each of them) to clear stored data. After all tests 21 | // are done, the Stop method should be called to stop the test server. 22 | // 23 | // Before the DBServer is used the SetPath method must be called to define 24 | // the location for the database files to be stored. 25 | type DBServer struct { 26 | session *mgo.Session 27 | output bytes.Buffer 28 | server *exec.Cmd 29 | dbpath string 30 | host string 31 | tomb tomb.Tomb 32 | } 33 | 34 | // SetPath defines the path to the directory where the database files will be 35 | // stored if it is started. The directory path itself is not created or removed 36 | // by the test helper. 37 | func (dbs *DBServer) SetPath(dbpath string) { 38 | dbs.dbpath = dbpath 39 | } 40 | 41 | func (dbs *DBServer) start() { 42 | if dbs.server != nil { 43 | panic("DBServer already started") 44 | } 45 | if dbs.dbpath == "" { 46 | panic("DBServer.SetPath must be called before using the server") 47 | } 48 | mgo.SetStats(true) 49 | l, err := net.Listen("tcp", "127.0.0.1:0") 50 | if err != nil { 51 | panic("unable to listen on a local address: " + err.Error()) 52 | } 53 | addr := l.Addr().(*net.TCPAddr) 54 | l.Close() 55 | dbs.host = addr.String() 56 | 57 | args := []string{ 58 | "--dbpath", dbs.dbpath, 59 | "--bind_ip", "127.0.0.1", 60 | "--port", strconv.Itoa(addr.Port), 61 | "--nssize", "1", 62 | "--noprealloc", 63 | "--smallfiles", 64 | "--nojournal", 65 | } 66 | dbs.tomb = tomb.Tomb{} 67 | dbs.server = exec.Command("mongod", args...) 68 | dbs.server.Stdout = &dbs.output 69 | dbs.server.Stderr = &dbs.output 70 | err = dbs.server.Start() 71 | if err != nil { 72 | panic(err) 73 | } 74 | dbs.tomb.Go(dbs.monitor) 75 | dbs.Wipe() 76 | } 77 | 78 | func (dbs *DBServer) monitor() error { 79 | dbs.server.Process.Wait() 80 | if dbs.tomb.Alive() { 81 | // Present some debugging information. 82 | fmt.Fprintf(os.Stderr, "---- mongod process died unexpectedly:\n") 83 | fmt.Fprintf(os.Stderr, "%s", dbs.output.Bytes()) 84 | fmt.Fprintf(os.Stderr, "---- mongod processes running right now:\n") 85 | cmd := exec.Command("/bin/sh", "-c", "ps auxw | grep mongod") 86 | cmd.Stdout = os.Stderr 87 | cmd.Stderr = os.Stderr 88 | cmd.Run() 89 | fmt.Fprintf(os.Stderr, "----------------------------------------\n") 90 | 91 | panic("mongod process died unexpectedly") 92 | } 93 | return nil 94 | } 95 | 96 | // Stop stops the test server process, if it is running. 97 | // 98 | // It's okay to call Stop multiple times. After the test server is 99 | // stopped it cannot be restarted. 100 | // 101 | // All database sessions must be closed before or while the Stop method 102 | // is running. Otherwise Stop will panic after a timeout informing that 103 | // there is a session leak. 104 | func (dbs *DBServer) Stop() { 105 | if dbs.session != nil { 106 | dbs.checkSessions() 107 | if dbs.session != nil { 108 | dbs.session.Close() 109 | dbs.session = nil 110 | } 111 | } 112 | if dbs.server != nil { 113 | dbs.tomb.Kill(nil) 114 | dbs.server.Process.Signal(os.Interrupt) 115 | select { 116 | case <-dbs.tomb.Dead(): 117 | case <-time.After(5 * time.Second): 118 | panic("timeout waiting for mongod process to die") 119 | } 120 | dbs.server = nil 121 | } 122 | } 123 | 124 | // Session returns a new session to the server. The returned session 125 | // must be closed after the test is done with it. 126 | // 127 | // The first Session obtained from a DBServer will start it. 128 | func (dbs *DBServer) Session() *mgo.Session { 129 | if dbs.server == nil { 130 | dbs.start() 131 | } 132 | if dbs.session == nil { 133 | mgo.ResetStats() 134 | var err error 135 | dbs.session, err = mgo.Dial(dbs.host + "/test") 136 | if err != nil { 137 | panic(err) 138 | } 139 | } 140 | return dbs.session.Copy() 141 | } 142 | 143 | // checkSessions ensures all mgo sessions opened were properly closed. 144 | // For slightly faster tests, it may be disabled setting the 145 | // environmnet variable CHECK_SESSIONS to 0. 146 | func (dbs *DBServer) checkSessions() { 147 | if check := os.Getenv("CHECK_SESSIONS"); check == "0" || dbs.server == nil || dbs.session == nil { 148 | return 149 | } 150 | dbs.session.Close() 151 | dbs.session = nil 152 | for i := 0; i < 100; i++ { 153 | stats := mgo.GetStats() 154 | if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 { 155 | return 156 | } 157 | time.Sleep(100 * time.Millisecond) 158 | } 159 | panic("There are mgo sessions still alive.") 160 | } 161 | 162 | // Wipe drops all created databases and their data. 163 | // 164 | // The MongoDB server remains running if it was prevoiusly running, 165 | // or stopped if it was previously stopped. 166 | // 167 | // All database sessions must be closed before or while the Wipe method 168 | // is running. Otherwise Wipe will panic after a timeout informing that 169 | // there is a session leak. 170 | func (dbs *DBServer) Wipe() { 171 | if dbs.server == nil || dbs.session == nil { 172 | return 173 | } 174 | dbs.checkSessions() 175 | sessionUnset := dbs.session == nil 176 | session := dbs.Session() 177 | defer session.Close() 178 | if sessionUnset { 179 | dbs.session.Close() 180 | dbs.session = nil 181 | } 182 | names, err := session.DatabaseNames() 183 | if err != nil { 184 | panic(err) 185 | } 186 | for _, name := range names { 187 | switch name { 188 | case "admin", "local", "config": 189 | default: 190 | err = session.DB(name).DropDatabase() 191 | if err != nil { 192 | panic(err) 193 | } 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/dbtest/dbserver_test.go: -------------------------------------------------------------------------------- 1 | package dbtest_test 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | "time" 7 | 8 | . "gopkg.in/check.v1" 9 | 10 | "gopkg.in/mgo.v2" 11 | "gopkg.in/mgo.v2/dbtest" 12 | ) 13 | 14 | type M map[string]interface{} 15 | 16 | func TestAll(t *testing.T) { 17 | TestingT(t) 18 | } 19 | 20 | type S struct { 21 | oldCheckSessions string 22 | } 23 | 24 | var _ = Suite(&S{}) 25 | 26 | func (s *S) SetUpTest(c *C) { 27 | s.oldCheckSessions = os.Getenv("CHECK_SESSIONS") 28 | os.Setenv("CHECK_SESSIONS", "") 29 | } 30 | 31 | func (s *S) TearDownTest(c *C) { 32 | os.Setenv("CHECK_SESSIONS", s.oldCheckSessions) 33 | } 34 | 35 | func (s *S) TestWipeData(c *C) { 36 | var server dbtest.DBServer 37 | server.SetPath(c.MkDir()) 38 | defer server.Stop() 39 | 40 | session := server.Session() 41 | err := session.DB("mydb").C("mycoll").Insert(M{"a": 1}) 42 | session.Close() 43 | c.Assert(err, IsNil) 44 | 45 | server.Wipe() 46 | 47 | session = server.Session() 48 | names, err := session.DatabaseNames() 49 | session.Close() 50 | c.Assert(err, IsNil) 51 | for _, name := range names { 52 | if name != "local" && name != "admin" { 53 | c.Fatalf("Wipe should have removed this database: %s", name) 54 | } 55 | } 56 | } 57 | 58 | func (s *S) TestStop(c *C) { 59 | var server dbtest.DBServer 60 | server.SetPath(c.MkDir()) 61 | defer server.Stop() 62 | 63 | // Server should not be running. 64 | process := server.ProcessTest() 65 | c.Assert(process, IsNil) 66 | 67 | session := server.Session() 68 | addr := session.LiveServers()[0] 69 | session.Close() 70 | 71 | // Server should be running now. 72 | process = server.ProcessTest() 73 | p, err := os.FindProcess(process.Pid) 74 | c.Assert(err, IsNil) 75 | p.Release() 76 | 77 | server.Stop() 78 | 79 | // Server should not be running anymore. 80 | session, err = mgo.DialWithTimeout(addr, 500*time.Millisecond) 81 | if session != nil { 82 | session.Close() 83 | c.Fatalf("Stop did not stop the server") 84 | } 85 | } 86 | 87 | func (s *S) TestCheckSessions(c *C) { 88 | var server dbtest.DBServer 89 | server.SetPath(c.MkDir()) 90 | defer server.Stop() 91 | 92 | session := server.Session() 93 | defer session.Close() 94 | c.Assert(server.Wipe, PanicMatches, "There are mgo sessions still alive.") 95 | } 96 | 97 | func (s *S) TestCheckSessionsDisabled(c *C) { 98 | var server dbtest.DBServer 99 | server.SetPath(c.MkDir()) 100 | defer server.Stop() 101 | 102 | os.Setenv("CHECK_SESSIONS", "0") 103 | 104 | // Should not panic, although it looks to Wipe like this session will leak. 105 | session := server.Session() 106 | defer session.Close() 107 | server.Wipe() 108 | } 109 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/dbtest/export_test.go: -------------------------------------------------------------------------------- 1 | package dbtest 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | func (dbs *DBServer) ProcessTest() *os.Process { 8 | if dbs.server == nil { 9 | return nil 10 | } 11 | return dbs.server.Process 12 | } 13 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/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 pool, 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 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/export_test.go: -------------------------------------------------------------------------------- 1 | package mgo 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | func HackPingDelay(newDelay time.Duration) (restore func()) { 8 | globalMutex.Lock() 9 | defer globalMutex.Unlock() 10 | 11 | oldDelay := pingDelay 12 | restore = func() { 13 | globalMutex.Lock() 14 | pingDelay = oldDelay 15 | globalMutex.Unlock() 16 | } 17 | pingDelay = newDelay 18 | return 19 | } 20 | 21 | func HackSyncSocketTimeout(newTimeout time.Duration) (restore func()) { 22 | globalMutex.Lock() 23 | defer globalMutex.Unlock() 24 | 25 | oldTimeout := syncSocketTimeout 26 | restore = func() { 27 | globalMutex.Lock() 28 | syncSocketTimeout = oldTimeout 29 | globalMutex.Unlock() 30 | } 31 | syncSocketTimeout = newTimeout 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/certs/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDLjCCAhYCAQcwDQYJKoZIhvcNAQELBQAwXDELMAkGA1UEBhMCR08xDDAKBgNV 3 | BAgMA01HTzEMMAoGA1UEBwwDTUdPMQwwCgYDVQQKDANNR08xDzANBgNVBAsMBlNl 4 | cnZlcjESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE1MDkyOTA4NDAzMFoYDzIxMTUw 5 | OTA1MDg0MDMwWjBcMQswCQYDVQQGEwJHTzEMMAoGA1UECAwDTUdPMQwwCgYDVQQH 6 | DANNR08xDDAKBgNVBAoMA01HTzEPMA0GA1UECwwGQ2xpZW50MRIwEAYDVQQDDAls 7 | b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0UiQhmT+H 8 | 4IIqrn8SMESDzvcl3rwImwUoRIHlmXkovCIZCbvBCJ1nAu6X5zIN89EPPOjfNrgZ 9 | 616wPgVV/YEQXp+D7+jTAsE5s8JepRXFdecResmvh/+0i2DSuI4QFsuyVAPM1O0I 10 | AQ5EKgr0weZZmsX6lhPD4uYehV4DxDE0i/8aTAlDoNgRCAJrYFMharRTDdY7bQzd 11 | 7ZYab/pK/3DSmOKxl/AFJ8Enmcj9w1bsvy0fgAgoGEBnBru80PRFpFiqk72TJkXO 12 | Hx7zcYFpegtKPbAreTCModaCnjP//fskCp4XJrkfH5+01NeeX/r1OfEbjgE/wzzx 13 | l8NaWnPCmxNfAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFwYpje3dCLDOIHYjd+5 14 | CpFOEb+bJsS4ryqm/NblTjIhCLo58hNpMsBqdJHRbHAFRCOE8fvY8yiWtdHeFZcW 15 | DgVRAXfHONLtN7faZaZQnhy/YzOhLfC/8dUMB0gQA8KXhBCPZqQmexE28AfkEO47 16 | PwICAxIWINfjm5VnFMkA3b7bDNLHon/pev2m7HqVQ3pRUJQNK3XgFOdDgRrnuXpR 17 | OKAfHORHVGTh1gf1DVwc0oM+0gnkSiJ1VG0n5pE3zhZ24fmZxu6JQ6X515W7APQI 18 | /nKVH+f1Fo+ustyTNLt8Bwxi1XmwT7IXwnkVSE9Ff6VejppXRF01V0aaWsa3kU3r 19 | z3A= 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/certs/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEAtFIkIZk/h+CCKq5/EjBEg873Jd68CJsFKESB5Zl5KLwiGQm7 3 | wQidZwLul+cyDfPRDzzo3za4GetesD4FVf2BEF6fg+/o0wLBObPCXqUVxXXnEXrJ 4 | r4f/tItg0riOEBbLslQDzNTtCAEORCoK9MHmWZrF+pYTw+LmHoVeA8QxNIv/GkwJ 5 | Q6DYEQgCa2BTIWq0Uw3WO20M3e2WGm/6Sv9w0pjisZfwBSfBJ5nI/cNW7L8tH4AI 6 | KBhAZwa7vND0RaRYqpO9kyZFzh8e83GBaXoLSj2wK3kwjKHWgp4z//37JAqeFya5 7 | Hx+ftNTXnl/69TnxG44BP8M88ZfDWlpzwpsTXwIDAQABAoIBADzCjOAxZkHfuZyu 8 | La0wTHXpkEfXdJ6ltagq5WY7P6MlOYwcRoK152vlhgXzZl9jL6ely4YjRwec0swq 9 | KdwezpV4fOGVPmuTuw45bx47HEnr/49ZQ4p9FgF9EYQPofbz53FQc/NaMACJcogv 10 | bn+osniw+VMFrOVNmGLiZ5p3Smk8zfXE7GRHO8CL5hpWLWO/aK236yytbfWOjM2f 11 | Pr76ICb26TPRNzYaYUEThU6DtgdLU8pLnJ6QKKaDsjn+zqQzRa+Nvc0c0K8gvWwA 12 | Afq7t0325+uMSwfpLgCOFldcaZQ5uvteJ0CAVRq1MvStnSHBmMzPlgS+NzsDm6lp 13 | QH5+rIkCgYEA5j3jrWsv7TueTNbk8Hr/Zwywc+fA2Ex0pBURBHlHyc6ahSXWSCqo 14 | DtvRGX0GDoK1lCfaIf1qb/DLlGaoHpkEeqcNhXQ+hHs+bZAxfbfBY9+ikit5ZTtl 15 | QN1tIlhaiyLDnwhkpi/hMw1tiouxJUf84Io61z0sCL4hyZSPCpjn0H0CgYEAyH6F 16 | Mwl+bCD3VDL/Dr5WSoOr2B/M3bF5SfvdStwy2IPcDJ716je1Ud/2qFCnKGgqvWhJ 17 | +HU15c7CjAWo7/pXq2/pEMD8fDKTYww4Hr4p6duEA7DpbOGkwcUX8u3eknxUWT9F 18 | jOSbTCvAxuDOC1K3AElyMxVVTNUrFFe8M84R9gsCgYBXmb6RkdG3WlKde7m5gaLB 19 | K4PLZabq5RQQBe/mmtpkfxYtiLrh1FEC7kG9h+MRDExX5V3KRugDVUOv3+shUSjy 20 | HbM4ToUm1NloyE78PTj4bfMl2CKlEJcyucy3H5S7kWuKi5/31wnA6d/+sa2huKUP 21 | Lai7kgu5+9VRJBPUfV7d5QKBgCnhk/13TDtWH5QtGu5/gBMMskbxTaA5xHZZ8H4E 22 | xXJJCRxx0Dje7jduK145itF8AQGT2W/XPC0HJciOHh4TE2EyfWMMjTF8dyFHmimB 23 | 28uIGWmT+Q7Pi9UWUMxkOAwtgIksGGE4F+CvexOQPjpLSwL6VKqrGCh2lwsm0J+Z 24 | ulLFAoGAKlC93c6XEj1A31c1+usdEhUe9BrmTqtSYLYpDNpeMLdZ3VctrAZuOQPZ 25 | 4A4gkkQkqqwZGBYYSEqwqiLU6MsBdHPPZ9u3JXLLOQuh1xGeaKylvHj7qx6iT0Xo 26 | I+FkJ6/3JeMgOina/+wlzD4oyQpqR4Mnh+TuLkDfQTgY+Lg0WPk= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/certs/client.pem: -------------------------------------------------------------------------------- 1 | To regenerate the key: 2 | 3 | openssl req -newkey rsa:2048 -new -x509 -days 36500 -nodes -out server.crt -keyout server.key 4 | cat server.key server.crt > server.pem 5 | openssl genrsa -out client.key 2048 6 | openssl req -key client.key -new -out client.req 7 | openssl x509 -req -in client.req -CA server.crt -CAkey server.key -days 36500 -CAserial file.srl -out client.crt 8 | cat client.key client.crt > client.pem 9 | 10 | -----BEGIN RSA PRIVATE KEY----- 11 | MIIEogIBAAKCAQEAtFIkIZk/h+CCKq5/EjBEg873Jd68CJsFKESB5Zl5KLwiGQm7 12 | wQidZwLul+cyDfPRDzzo3za4GetesD4FVf2BEF6fg+/o0wLBObPCXqUVxXXnEXrJ 13 | r4f/tItg0riOEBbLslQDzNTtCAEORCoK9MHmWZrF+pYTw+LmHoVeA8QxNIv/GkwJ 14 | Q6DYEQgCa2BTIWq0Uw3WO20M3e2WGm/6Sv9w0pjisZfwBSfBJ5nI/cNW7L8tH4AI 15 | KBhAZwa7vND0RaRYqpO9kyZFzh8e83GBaXoLSj2wK3kwjKHWgp4z//37JAqeFya5 16 | Hx+ftNTXnl/69TnxG44BP8M88ZfDWlpzwpsTXwIDAQABAoIBADzCjOAxZkHfuZyu 17 | La0wTHXpkEfXdJ6ltagq5WY7P6MlOYwcRoK152vlhgXzZl9jL6ely4YjRwec0swq 18 | KdwezpV4fOGVPmuTuw45bx47HEnr/49ZQ4p9FgF9EYQPofbz53FQc/NaMACJcogv 19 | bn+osniw+VMFrOVNmGLiZ5p3Smk8zfXE7GRHO8CL5hpWLWO/aK236yytbfWOjM2f 20 | Pr76ICb26TPRNzYaYUEThU6DtgdLU8pLnJ6QKKaDsjn+zqQzRa+Nvc0c0K8gvWwA 21 | Afq7t0325+uMSwfpLgCOFldcaZQ5uvteJ0CAVRq1MvStnSHBmMzPlgS+NzsDm6lp 22 | QH5+rIkCgYEA5j3jrWsv7TueTNbk8Hr/Zwywc+fA2Ex0pBURBHlHyc6ahSXWSCqo 23 | DtvRGX0GDoK1lCfaIf1qb/DLlGaoHpkEeqcNhXQ+hHs+bZAxfbfBY9+ikit5ZTtl 24 | QN1tIlhaiyLDnwhkpi/hMw1tiouxJUf84Io61z0sCL4hyZSPCpjn0H0CgYEAyH6F 25 | Mwl+bCD3VDL/Dr5WSoOr2B/M3bF5SfvdStwy2IPcDJ716je1Ud/2qFCnKGgqvWhJ 26 | +HU15c7CjAWo7/pXq2/pEMD8fDKTYww4Hr4p6duEA7DpbOGkwcUX8u3eknxUWT9F 27 | jOSbTCvAxuDOC1K3AElyMxVVTNUrFFe8M84R9gsCgYBXmb6RkdG3WlKde7m5gaLB 28 | K4PLZabq5RQQBe/mmtpkfxYtiLrh1FEC7kG9h+MRDExX5V3KRugDVUOv3+shUSjy 29 | HbM4ToUm1NloyE78PTj4bfMl2CKlEJcyucy3H5S7kWuKi5/31wnA6d/+sa2huKUP 30 | Lai7kgu5+9VRJBPUfV7d5QKBgCnhk/13TDtWH5QtGu5/gBMMskbxTaA5xHZZ8H4E 31 | xXJJCRxx0Dje7jduK145itF8AQGT2W/XPC0HJciOHh4TE2EyfWMMjTF8dyFHmimB 32 | 28uIGWmT+Q7Pi9UWUMxkOAwtgIksGGE4F+CvexOQPjpLSwL6VKqrGCh2lwsm0J+Z 33 | ulLFAoGAKlC93c6XEj1A31c1+usdEhUe9BrmTqtSYLYpDNpeMLdZ3VctrAZuOQPZ 34 | 4A4gkkQkqqwZGBYYSEqwqiLU6MsBdHPPZ9u3JXLLOQuh1xGeaKylvHj7qx6iT0Xo 35 | I+FkJ6/3JeMgOina/+wlzD4oyQpqR4Mnh+TuLkDfQTgY+Lg0WPk= 36 | -----END RSA PRIVATE KEY----- 37 | -----BEGIN CERTIFICATE----- 38 | MIIDLjCCAhYCAQcwDQYJKoZIhvcNAQELBQAwXDELMAkGA1UEBhMCR08xDDAKBgNV 39 | BAgMA01HTzEMMAoGA1UEBwwDTUdPMQwwCgYDVQQKDANNR08xDzANBgNVBAsMBlNl 40 | cnZlcjESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE1MDkyOTA4NDAzMFoYDzIxMTUw 41 | OTA1MDg0MDMwWjBcMQswCQYDVQQGEwJHTzEMMAoGA1UECAwDTUdPMQwwCgYDVQQH 42 | DANNR08xDDAKBgNVBAoMA01HTzEPMA0GA1UECwwGQ2xpZW50MRIwEAYDVQQDDAls 43 | b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0UiQhmT+H 44 | 4IIqrn8SMESDzvcl3rwImwUoRIHlmXkovCIZCbvBCJ1nAu6X5zIN89EPPOjfNrgZ 45 | 616wPgVV/YEQXp+D7+jTAsE5s8JepRXFdecResmvh/+0i2DSuI4QFsuyVAPM1O0I 46 | AQ5EKgr0weZZmsX6lhPD4uYehV4DxDE0i/8aTAlDoNgRCAJrYFMharRTDdY7bQzd 47 | 7ZYab/pK/3DSmOKxl/AFJ8Enmcj9w1bsvy0fgAgoGEBnBru80PRFpFiqk72TJkXO 48 | Hx7zcYFpegtKPbAreTCModaCnjP//fskCp4XJrkfH5+01NeeX/r1OfEbjgE/wzzx 49 | l8NaWnPCmxNfAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFwYpje3dCLDOIHYjd+5 50 | CpFOEb+bJsS4ryqm/NblTjIhCLo58hNpMsBqdJHRbHAFRCOE8fvY8yiWtdHeFZcW 51 | DgVRAXfHONLtN7faZaZQnhy/YzOhLfC/8dUMB0gQA8KXhBCPZqQmexE28AfkEO47 52 | PwICAxIWINfjm5VnFMkA3b7bDNLHon/pev2m7HqVQ3pRUJQNK3XgFOdDgRrnuXpR 53 | OKAfHORHVGTh1gf1DVwc0oM+0gnkSiJ1VG0n5pE3zhZ24fmZxu6JQ6X515W7APQI 54 | /nKVH+f1Fo+ustyTNLt8Bwxi1XmwT7IXwnkVSE9Ff6VejppXRF01V0aaWsa3kU3r 55 | z3A= 56 | -----END CERTIFICATE----- 57 | 58 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/certs/client.req: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICoTCCAYkCAQAwXDELMAkGA1UEBhMCR08xDDAKBgNVBAgMA01HTzEMMAoGA1UE 3 | BwwDTUdPMQwwCgYDVQQKDANNR08xDzANBgNVBAsMBkNsaWVudDESMBAGA1UEAwwJ 4 | bG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtFIkIZk/ 5 | h+CCKq5/EjBEg873Jd68CJsFKESB5Zl5KLwiGQm7wQidZwLul+cyDfPRDzzo3za4 6 | GetesD4FVf2BEF6fg+/o0wLBObPCXqUVxXXnEXrJr4f/tItg0riOEBbLslQDzNTt 7 | CAEORCoK9MHmWZrF+pYTw+LmHoVeA8QxNIv/GkwJQ6DYEQgCa2BTIWq0Uw3WO20M 8 | 3e2WGm/6Sv9w0pjisZfwBSfBJ5nI/cNW7L8tH4AIKBhAZwa7vND0RaRYqpO9kyZF 9 | zh8e83GBaXoLSj2wK3kwjKHWgp4z//37JAqeFya5Hx+ftNTXnl/69TnxG44BP8M8 10 | 8ZfDWlpzwpsTXwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAKbOFblIscxlXalV 11 | sEGNm2oz380RN2QoLhN6nKtAiv0jWm6iKhdAhOIQIeaRPhUP3cyi8bcBvLdMeQ3d 12 | ZYIByB55/R0VSP1vs4qkXJCQegHcpMpyuIzsMV8p3Q4lxzGKyKtPA6Bb5c49p8Sk 13 | ncD+LL4ymrMEia4cBPsHL9hhFOm4gqDacbU8+ETLTpuoSvUZiw7OwngqhE2r+kMv 14 | KDweq5TOPeb+ftKzQKrrfB+XVdBoTKYw6CwARpogbc0/7mvottVcJ/0yAgC1fBbM 15 | vupkohkXwKfjxKl6nKNL3R2GkzHQOh91hglAx5zyybKQn2YMM328Vk4X6csBg+pg 16 | tb1s0MA= 17 | -----END CERTIFICATE REQUEST----- 18 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/certs/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDjTCCAnWgAwIBAgIJAMW+wDfcdzC+MA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV 3 | BAYTAkdPMQwwCgYDVQQIDANNR08xDDAKBgNVBAcMA01HTzEMMAoGA1UECgwDTUdP 4 | MQ8wDQYDVQQLDAZTZXJ2ZXIxEjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0xNTA5Mjkw 5 | ODM0MTBaGA8yMTE1MDkwNTA4MzQxMFowXDELMAkGA1UEBhMCR08xDDAKBgNVBAgM 6 | A01HTzEMMAoGA1UEBwwDTUdPMQwwCgYDVQQKDANNR08xDzANBgNVBAsMBlNlcnZl 7 | cjESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 8 | CgKCAQEA/T5W1vTsAF+2gTXP1JKygjM7T/2BXHiJc6DRKVjlshTtPYuC3rpTddDm 9 | 6d86d17LWEo+T2bCT4MzZJhSGAun9peFvehdElRMr57xs7j5V1QYjwadMTBkLQuK 10 | IAg6cISN1KPUzpUTUKsWIsbx97sA0t0wiEPifROb7nfSMIVQsdz/c9LlY2UNYI+5 11 | GiU88iDGg2wrdsa3U+l2G2KSx/9uE3c5iFki6bdequLiWmBZ6rxfoaLe4gk1INji 12 | fKssNsn2i3uJ4i4Tmr3PUc4kxx0mMKuWK3HdlQsMqtpq++HQmHSvsPrbgcjl9HyP 13 | JiHDsoJ+4O5bbtcE51oQbLh1bZAhYwIDAQABo1AwTjAdBgNVHQ4EFgQUhku/u9Kd 14 | OAc1L0OR649vCCuQT+0wHwYDVR0jBBgwFoAUhku/u9KdOAc1L0OR649vCCuQT+0w 15 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAw7Bgw3hlWXWSZjLhnSOu 16 | 2mW/UJ2Sj31unHngmgtXwW/04cyzoULb+qmzPe/Z06QMgGIsku1jFBcu0JabQtUG 17 | TyalpfW77tfnvz238CYdImYwE9ZcIGuZGfhs6ySFN9XpW43B8YM7R8wTNPvOcSPw 18 | nfjqU6kueN4TTspQg9cKhDss5DcMTIdgJgLbITXhIsrCu6GlKOgtX3HrdMGpQX7s 19 | UoMXtZVG8pK32vxKWGTZ6DPqESeKjjq74NbYnB3H5U/kDU2dt7LF90C/Umdr9y+C 20 | W2OJb1WBrf6RTcbt8D6d7P9kOfLPOtyn/cbaA/pfXBMQMHqr7XNXzjnaNU+jB7hL 21 | yQ== 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/certs/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD9PlbW9OwAX7aB 3 | Nc/UkrKCMztP/YFceIlzoNEpWOWyFO09i4LeulN10Obp3zp3XstYSj5PZsJPgzNk 4 | mFIYC6f2l4W96F0SVEyvnvGzuPlXVBiPBp0xMGQtC4ogCDpwhI3Uo9TOlRNQqxYi 5 | xvH3uwDS3TCIQ+J9E5vud9IwhVCx3P9z0uVjZQ1gj7kaJTzyIMaDbCt2xrdT6XYb 6 | YpLH/24TdzmIWSLpt16q4uJaYFnqvF+hot7iCTUg2OJ8qyw2yfaLe4niLhOavc9R 7 | ziTHHSYwq5Yrcd2VCwyq2mr74dCYdK+w+tuByOX0fI8mIcOygn7g7ltu1wTnWhBs 8 | uHVtkCFjAgMBAAECggEASRAfRc1L+Z+jrAu2doIMdnwJdL6S//bW0UFolyFKw+I9 9 | wC/sBg6D3c3zkS4SVDZJPKPO7mGbVg1oWnGH3eAfCYoV0ACmOY+QwGp/GXcYmRVu 10 | MHWcDIEFpelaZHt7QNM9iEfsMd3YwMFblZUIYozVZADk66uKQMPTjS2Muur7qRSi 11 | wuVfSmsVZ5afH3B1Tr96BbmPsHrXLjvNpjO44k2wrnnSPQjUL7+YiZPvtnNW8Fby 12 | yuo2uoAyjg3+68PYZftOvvNneMsv1uyGlUs6Bk+DVWaqofIztWFdFZyXbHnK2PTk 13 | eGQt5EsL+RwIck5eoqd5vSE+KyzhhydL0zcpngVQoQKBgQD/Yelvholbz5NQtSy3 14 | ZoiW1y7hL1BKzvVNHuAMKJ5WOnj5szhjhKxt/wZ+hk0qcAmlV9WAPbf4izbEwPRC 15 | tnMBQzf1uBxqqbLL6WZ4YAyGrcX3UrT7GXsGfVT4zJjz7oYSw8aPircecw5V4exB 16 | xa4NF+ki8IycXSkHwvW2R56fRwKBgQD92xpxXtte/rUnmENbQmr0aKg7JEfMoih6 17 | MdX+f6mfgjMmqj+L4jPTI8/ql8HEy13SQS1534aDSHO+nBqBK5aHUCRMIgSLnTP9 18 | Xyx9Ngg03SZIkPfykqxQmnZgWkTPMhYS+K1Ao9FGVs8W5jVi7veyAdhHptAcxhP3 19 | IuxvrxVTBQKBgQCluMPiu0snaOwP04HRAZhhSgIB3tIbuXE1OnPpb/JPwmH+p25Q 20 | Jig+uN9d+4jXoRyhTv4c2fAoOS6xPwVCxWKbzyLhMTg/fx+ncy4rryhxvRJaDDGl 21 | QEO1Ul9xlFMs9/vI8YJIY5uxBrimwpStmbn4hSukoLSeQ1X802bfglpMwQKBgD8z 22 | GTY4Y20XBIrDAaHquy32EEwJEEcF6AXj+l7N8bDgfVOW9xMgUb6zH8RL29Xeu5Do 23 | 4SWCXL66fvZpbr/R1jwB28eIgJExpgvicfUKSqi+lhVi4hfmJDg8/FOopZDf61b1 24 | ykxZfHSCkDQnRAtJaylKBEpyYUWImtfgPfTgJfLxAoGAc8A/Tl2h/DsdTA+cA5d7 25 | 1e0l64m13ObruSWRczyru4hy8Yq6E/K2rOFw8cYCcFpy24NqNlk+2iXPLRpWm2zt 26 | 9R497zAPvhK/bfPXjvm0j/VjB44lvRTC9hby/RRMHy9UJk4o/UQaD+1IodxZovvk 27 | SruEA1+5bfBRMW0P+h7Qfe4= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/certs/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD9PlbW9OwAX7aB 3 | Nc/UkrKCMztP/YFceIlzoNEpWOWyFO09i4LeulN10Obp3zp3XstYSj5PZsJPgzNk 4 | mFIYC6f2l4W96F0SVEyvnvGzuPlXVBiPBp0xMGQtC4ogCDpwhI3Uo9TOlRNQqxYi 5 | xvH3uwDS3TCIQ+J9E5vud9IwhVCx3P9z0uVjZQ1gj7kaJTzyIMaDbCt2xrdT6XYb 6 | YpLH/24TdzmIWSLpt16q4uJaYFnqvF+hot7iCTUg2OJ8qyw2yfaLe4niLhOavc9R 7 | ziTHHSYwq5Yrcd2VCwyq2mr74dCYdK+w+tuByOX0fI8mIcOygn7g7ltu1wTnWhBs 8 | uHVtkCFjAgMBAAECggEASRAfRc1L+Z+jrAu2doIMdnwJdL6S//bW0UFolyFKw+I9 9 | wC/sBg6D3c3zkS4SVDZJPKPO7mGbVg1oWnGH3eAfCYoV0ACmOY+QwGp/GXcYmRVu 10 | MHWcDIEFpelaZHt7QNM9iEfsMd3YwMFblZUIYozVZADk66uKQMPTjS2Muur7qRSi 11 | wuVfSmsVZ5afH3B1Tr96BbmPsHrXLjvNpjO44k2wrnnSPQjUL7+YiZPvtnNW8Fby 12 | yuo2uoAyjg3+68PYZftOvvNneMsv1uyGlUs6Bk+DVWaqofIztWFdFZyXbHnK2PTk 13 | eGQt5EsL+RwIck5eoqd5vSE+KyzhhydL0zcpngVQoQKBgQD/Yelvholbz5NQtSy3 14 | ZoiW1y7hL1BKzvVNHuAMKJ5WOnj5szhjhKxt/wZ+hk0qcAmlV9WAPbf4izbEwPRC 15 | tnMBQzf1uBxqqbLL6WZ4YAyGrcX3UrT7GXsGfVT4zJjz7oYSw8aPircecw5V4exB 16 | xa4NF+ki8IycXSkHwvW2R56fRwKBgQD92xpxXtte/rUnmENbQmr0aKg7JEfMoih6 17 | MdX+f6mfgjMmqj+L4jPTI8/ql8HEy13SQS1534aDSHO+nBqBK5aHUCRMIgSLnTP9 18 | Xyx9Ngg03SZIkPfykqxQmnZgWkTPMhYS+K1Ao9FGVs8W5jVi7veyAdhHptAcxhP3 19 | IuxvrxVTBQKBgQCluMPiu0snaOwP04HRAZhhSgIB3tIbuXE1OnPpb/JPwmH+p25Q 20 | Jig+uN9d+4jXoRyhTv4c2fAoOS6xPwVCxWKbzyLhMTg/fx+ncy4rryhxvRJaDDGl 21 | QEO1Ul9xlFMs9/vI8YJIY5uxBrimwpStmbn4hSukoLSeQ1X802bfglpMwQKBgD8z 22 | GTY4Y20XBIrDAaHquy32EEwJEEcF6AXj+l7N8bDgfVOW9xMgUb6zH8RL29Xeu5Do 23 | 4SWCXL66fvZpbr/R1jwB28eIgJExpgvicfUKSqi+lhVi4hfmJDg8/FOopZDf61b1 24 | ykxZfHSCkDQnRAtJaylKBEpyYUWImtfgPfTgJfLxAoGAc8A/Tl2h/DsdTA+cA5d7 25 | 1e0l64m13ObruSWRczyru4hy8Yq6E/K2rOFw8cYCcFpy24NqNlk+2iXPLRpWm2zt 26 | 9R497zAPvhK/bfPXjvm0j/VjB44lvRTC9hby/RRMHy9UJk4o/UQaD+1IodxZovvk 27 | SruEA1+5bfBRMW0P+h7Qfe4= 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIIDjTCCAnWgAwIBAgIJAMW+wDfcdzC+MA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV 31 | BAYTAkdPMQwwCgYDVQQIDANNR08xDDAKBgNVBAcMA01HTzEMMAoGA1UECgwDTUdP 32 | MQ8wDQYDVQQLDAZTZXJ2ZXIxEjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0xNTA5Mjkw 33 | ODM0MTBaGA8yMTE1MDkwNTA4MzQxMFowXDELMAkGA1UEBhMCR08xDDAKBgNVBAgM 34 | A01HTzEMMAoGA1UEBwwDTUdPMQwwCgYDVQQKDANNR08xDzANBgNVBAsMBlNlcnZl 35 | cjESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 36 | CgKCAQEA/T5W1vTsAF+2gTXP1JKygjM7T/2BXHiJc6DRKVjlshTtPYuC3rpTddDm 37 | 6d86d17LWEo+T2bCT4MzZJhSGAun9peFvehdElRMr57xs7j5V1QYjwadMTBkLQuK 38 | IAg6cISN1KPUzpUTUKsWIsbx97sA0t0wiEPifROb7nfSMIVQsdz/c9LlY2UNYI+5 39 | GiU88iDGg2wrdsa3U+l2G2KSx/9uE3c5iFki6bdequLiWmBZ6rxfoaLe4gk1INji 40 | fKssNsn2i3uJ4i4Tmr3PUc4kxx0mMKuWK3HdlQsMqtpq++HQmHSvsPrbgcjl9HyP 41 | JiHDsoJ+4O5bbtcE51oQbLh1bZAhYwIDAQABo1AwTjAdBgNVHQ4EFgQUhku/u9Kd 42 | OAc1L0OR649vCCuQT+0wHwYDVR0jBBgwFoAUhku/u9KdOAc1L0OR649vCCuQT+0w 43 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAw7Bgw3hlWXWSZjLhnSOu 44 | 2mW/UJ2Sj31unHngmgtXwW/04cyzoULb+qmzPe/Z06QMgGIsku1jFBcu0JabQtUG 45 | TyalpfW77tfnvz238CYdImYwE9ZcIGuZGfhs6ySFN9XpW43B8YM7R8wTNPvOcSPw 46 | nfjqU6kueN4TTspQg9cKhDss5DcMTIdgJgLbITXhIsrCu6GlKOgtX3HrdMGpQX7s 47 | UoMXtZVG8pK32vxKWGTZ6DPqESeKjjq74NbYnB3H5U/kDU2dt7LF90C/Umdr9y+C 48 | W2OJb1WBrf6RTcbt8D6d7P9kOfLPOtyn/cbaA/pfXBMQMHqr7XNXzjnaNU+jB7hL 49 | yQ== 50 | -----END CERTIFICATE----- 51 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg1/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg1/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg1/db/mongod.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg1/db/mongod.lock -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg1/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg1/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONCOPTS \ 6 | --port 40101 \ 7 | --configsvr 8 | 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg2/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg2/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg2/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg2/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONCOPTS \ 6 | --port 40102 \ 7 | --configsvr 8 | 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg3/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg3/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg3/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/cfg3/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONCOPTS \ 6 | --port 40103 \ 7 | --configsvr \ 8 | --auth \ 9 | --keyFile=../../certs/keyfile 10 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db1/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db1/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db1/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db1/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | if [ x$NOIPV6 = x1 ]; then 6 | BINDIP="127.0.0.1" 7 | else 8 | BINDIP="127.0.0.1,::1" 9 | fi 10 | 11 | exec mongod $COMMONDOPTSNOIP \ 12 | --shardsvr \ 13 | --bind_ip=$BINDIP \ 14 | --port 40001 \ 15 | --ipv6 16 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db2/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db2/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db2/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db2/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --port 40002 \ 8 | --auth 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db3/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db3/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db3/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/db3/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --port 40003 \ 8 | --auth \ 9 | --sslMode preferSSL \ 10 | --sslCAFile ../../certs/server.pem \ 11 | --sslPEMKeyFile ../../certs/server.pem 12 | 13 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1a/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1a/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1a/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1a/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs1 \ 8 | --port 40011 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1b/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1b/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1b/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1b/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs1 \ 8 | --port 40012 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1c/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1c/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1c/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs1c/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs1 \ 8 | --port 40013 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2a/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2a/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2a/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2a/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs2 \ 8 | --port 40021 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2b/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2b/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2b/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2b/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs2 \ 8 | --port 40022 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2c/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2c/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2c/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs2c/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs2 \ 8 | --port 40023 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3a/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3a/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3a/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3a/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs3 \ 8 | --port 40031 \ 9 | --keyFile=../../certs/keyfile 10 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3b/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3b/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3b/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3b/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs3 \ 8 | --port 40032 \ 9 | --keyFile=../../certs/keyfile 10 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3c/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3c/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3c/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs3c/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs3 \ 8 | --port 40033 \ 9 | --keyFile=../../certs/keyfile 10 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs4a/db/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs4a/db/.empty -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs4a/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/rs4a/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongod $COMMONDOPTS \ 6 | --shardsvr \ 7 | --replSet rs4 \ 8 | --port 40041 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/s1/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/s1/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongos $COMMONSOPTS \ 6 | --port 40201 \ 7 | --configdb 127.0.0.1:40101 8 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/s2/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/s2/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongos $COMMONSOPTS \ 6 | --port 40202 \ 7 | --configdb 127.0.0.1:40102 8 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/s3/log/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec cat - > log.txt 4 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/daemons/s3/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ../.env 4 | 5 | exec mongos $COMMONSOPTS \ 6 | --port 40203 \ 7 | --configdb 127.0.0.1:40103 \ 8 | --keyFile=../../certs/keyfile 9 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/mongojs/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 | var db1 = new Mongo("localhost:40001") 5 | 6 | if (db1.getDB("admin").serverBuildInfo().OpenSSLVersion) { 7 | ports.push(40003) 8 | auth.push(40003) 9 | } 10 | 11 | for (var i in ports) { 12 | var port = ports[i] 13 | var server = "localhost:" + port 14 | var mongo = new Mongo("localhost:" + port) 15 | var admin = mongo.getDB("admin") 16 | 17 | for (var j in auth) { 18 | if (auth[j] == port) { 19 | admin.auth("root", "rapadura") 20 | admin.system.users.find().forEach(function(u) { 21 | if (u.user == "root" || u.user == "reader") { 22 | return; 23 | } 24 | if (typeof admin.dropUser == "function") { 25 | mongo.getDB(u.db).dropUser(u.user); 26 | } else { 27 | admin.removeUser(u.user); 28 | } 29 | }) 30 | break 31 | } 32 | } 33 | var result = admin.runCommand({"listDatabases": 1}) 34 | for (var j = 0; j != 100; j++) { 35 | if (typeof result.databases != "undefined" || notMaster(result)) { 36 | break 37 | } 38 | result = admin.runCommand({"listDatabases": 1}) 39 | } 40 | if (notMaster(result)) { 41 | continue 42 | } 43 | if (typeof result.databases == "undefined") { 44 | print("Could not list databases. Command result:") 45 | print(JSON.stringify(result)) 46 | quit(12) 47 | } 48 | var dbs = result.databases 49 | for (var j = 0; j != dbs.length; j++) { 50 | var db = dbs[j] 51 | switch (db.name) { 52 | case "admin": 53 | case "local": 54 | case "config": 55 | break 56 | default: 57 | mongo.getDB(db.name).dropDatabase() 58 | } 59 | } 60 | } 61 | 62 | function notMaster(result) { 63 | return typeof result.errmsg != "undefined" && (result.errmsg.indexOf("not master") >= 0 || result.errmsg.indexOf("no master found")) 64 | } 65 | 66 | // vim:ts=4:sw=4:et 67 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/mongojs/init.js: -------------------------------------------------------------------------------- 1 | //var settings = {heartbeatSleep: 0.05, heartbeatTimeout: 0.5} 2 | var settings = {}; 3 | 4 | // We know the master of the first set (pri=1), but not of the second. 5 | var rs1cfg = {_id: "rs1", 6 | members: [{_id: 1, host: "127.0.0.1:40011", priority: 1, tags: {rs1: "a"}}, 7 | {_id: 2, host: "127.0.0.1:40012", priority: 0, tags: {rs1: "b"}}, 8 | {_id: 3, host: "127.0.0.1:40013", priority: 0, tags: {rs1: "c"}}], 9 | settings: settings} 10 | var rs2cfg = {_id: "rs2", 11 | members: [{_id: 1, host: "127.0.0.1:40021", priority: 1, tags: {rs2: "a"}}, 12 | {_id: 2, host: "127.0.0.1:40022", priority: 1, tags: {rs2: "b"}}, 13 | {_id: 3, host: "127.0.0.1:40023", priority: 1, tags: {rs2: "c"}}], 14 | settings: settings} 15 | var rs3cfg = {_id: "rs3", 16 | members: [{_id: 1, host: "127.0.0.1:40031", priority: 1, tags: {rs3: "a"}}, 17 | {_id: 2, host: "127.0.0.1:40032", priority: 1, tags: {rs3: "b"}}, 18 | {_id: 3, host: "127.0.0.1:40033", priority: 1, tags: {rs3: "c"}}], 19 | settings: settings} 20 | 21 | for (var i = 0; i != 60; i++) { 22 | try { 23 | db1 = new Mongo("127.0.0.1:40001").getDB("admin") 24 | db2 = new Mongo("127.0.0.1:40002").getDB("admin") 25 | rs1a = new Mongo("127.0.0.1:40011").getDB("admin") 26 | rs2a = new Mongo("127.0.0.1:40021").getDB("admin") 27 | rs3a = new Mongo("127.0.0.1:40031").getDB("admin") 28 | break 29 | } catch(err) { 30 | print("Can't connect yet...") 31 | } 32 | sleep(1000) 33 | } 34 | 35 | function hasSSL() { 36 | return Boolean(db1.serverBuildInfo().OpenSSLVersion) 37 | } 38 | 39 | rs1a.runCommand({replSetInitiate: rs1cfg}) 40 | rs2a.runCommand({replSetInitiate: rs2cfg}) 41 | rs3a.runCommand({replSetInitiate: rs3cfg}) 42 | 43 | function configShards() { 44 | cfg1 = new Mongo("127.0.0.1:40201").getDB("admin") 45 | cfg1.runCommand({addshard: "127.0.0.1:40001"}) 46 | cfg1.runCommand({addshard: "rs1/127.0.0.1:40011"}) 47 | 48 | cfg2 = new Mongo("127.0.0.1:40202").getDB("admin") 49 | cfg2.runCommand({addshard: "rs2/127.0.0.1:40021"}) 50 | 51 | cfg3 = new Mongo("127.0.0.1:40203").getDB("admin") 52 | cfg3.runCommand({addshard: "rs3/127.0.0.1:40031"}) 53 | } 54 | 55 | function configAuth() { 56 | var addrs = ["127.0.0.1:40002", "127.0.0.1:40203", "127.0.0.1:40031"] 57 | if (hasSSL()) { 58 | addrs.push("127.0.0.1:40003") 59 | } 60 | for (var i in addrs) { 61 | print("Configuring auth for", addrs[i]) 62 | var db = new Mongo(addrs[i]).getDB("admin") 63 | var v = db.serverBuildInfo().versionArray 64 | var timedOut = false 65 | if (v < [2, 5]) { 66 | db.addUser("root", "rapadura") 67 | } else { 68 | try { 69 | db.createUser({user: "root", pwd: "rapadura", roles: ["root"]}) 70 | } catch (err) { 71 | // 3.2 consistently fails replication of creds on 40031 (config server) 72 | print("createUser command returned an error: " + err) 73 | if (String(err).indexOf("timed out") >= 0) { 74 | timedOut = true; 75 | } 76 | } 77 | } 78 | for (var i = 0; i < 60; i++) { 79 | var ok = db.auth("root", "rapadura") 80 | if (ok || !timedOut) { 81 | break 82 | } 83 | sleep(1000); 84 | } 85 | if (v >= [2, 6]) { 86 | db.createUser({user: "reader", pwd: "rapadura", roles: ["readAnyDatabase"]}) 87 | } else if (v >= [2, 4]) { 88 | db.addUser({user: "reader", pwd: "rapadura", roles: ["readAnyDatabase"]}) 89 | } else { 90 | db.addUser("reader", "rapadura", true) 91 | } 92 | } 93 | } 94 | 95 | function countHealthy(rs) { 96 | var status = rs.runCommand({replSetGetStatus: 1}) 97 | var count = 0 98 | var primary = 0 99 | if (typeof status.members != "undefined") { 100 | for (var i = 0; i != status.members.length; i++) { 101 | var m = status.members[i] 102 | if (m.health == 1 && (m.state == 1 || m.state == 2)) { 103 | count += 1 104 | if (m.state == 1) { 105 | primary = 1 106 | } 107 | } 108 | } 109 | } 110 | if (primary == 0) { 111 | count = 0 112 | } 113 | return count 114 | } 115 | 116 | var totalRSMembers = rs1cfg.members.length + rs2cfg.members.length + rs3cfg.members.length 117 | 118 | for (var i = 0; i != 60; i++) { 119 | var count = countHealthy(rs1a) + countHealthy(rs2a) + countHealthy(rs3a) 120 | print("Replica sets have", count, "healthy nodes.") 121 | if (count == totalRSMembers) { 122 | configShards() 123 | configAuth() 124 | quit(0) 125 | } 126 | sleep(1000) 127 | } 128 | 129 | print("Replica sets didn't sync up properly.") 130 | quit(12) 131 | 132 | // vim:ts=4:sw=4:et 133 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/mongojs/wait.js: -------------------------------------------------------------------------------- 1 | // We know the master of the first set (pri=1), but not of the second. 2 | var settings = {} 3 | var rs1cfg = {_id: "rs1", 4 | members: [{_id: 1, host: "127.0.0.1:40011", priority: 1}, 5 | {_id: 2, host: "127.0.0.1:40012", priority: 0}, 6 | {_id: 3, host: "127.0.0.1:40013", priority: 0}]} 7 | var rs2cfg = {_id: "rs2", 8 | members: [{_id: 1, host: "127.0.0.1:40021", priority: 1}, 9 | {_id: 2, host: "127.0.0.1:40022", priority: 1}, 10 | {_id: 3, host: "127.0.0.1:40023", priority: 0}]} 11 | var rs3cfg = {_id: "rs3", 12 | members: [{_id: 1, host: "127.0.0.1:40031", priority: 1}, 13 | {_id: 2, host: "127.0.0.1:40032", priority: 1}, 14 | {_id: 3, host: "127.0.0.1:40033", priority: 1}], 15 | settings: settings} 16 | 17 | for (var i = 0; i != 60; i++) { 18 | try { 19 | rs1a = new Mongo("127.0.0.1:40011").getDB("admin") 20 | rs2a = new Mongo("127.0.0.1:40021").getDB("admin") 21 | rs3a = new Mongo("127.0.0.1:40031").getDB("admin") 22 | rs3a.auth("root", "rapadura") 23 | db1 = new Mongo("127.0.0.1:40001").getDB("admin") 24 | db2 = new Mongo("127.0.0.1:40002").getDB("admin") 25 | break 26 | } catch(err) { 27 | print("Can't connect yet...") 28 | } 29 | sleep(1000) 30 | } 31 | 32 | function countHealthy(rs) { 33 | var status = rs.runCommand({replSetGetStatus: 1}) 34 | var count = 0 35 | var primary = 0 36 | if (typeof status.members != "undefined") { 37 | for (var i = 0; i != status.members.length; i++) { 38 | var m = status.members[i] 39 | if (m.health == 1 && (m.state == 1 || m.state == 2)) { 40 | count += 1 41 | if (m.state == 1) { 42 | primary = 1 43 | } 44 | } 45 | } 46 | } 47 | if (primary == 0) { 48 | count = 0 49 | } 50 | return count 51 | } 52 | 53 | var totalRSMembers = rs1cfg.members.length + rs2cfg.members.length + rs3cfg.members.length 54 | 55 | for (var i = 0; i != 90; i++) { 56 | var count = countHealthy(rs1a) + countHealthy(rs2a) + countHealthy(rs3a) 57 | print("Replica sets have", count, "healthy nodes.") 58 | if (count == totalRSMembers) { 59 | quit(0) 60 | } 61 | sleep(1000) 62 | } 63 | 64 | print("Replica sets didn't sync up properly.") 65 | quit(12) 66 | 67 | // vim:ts=4:sw=4:et 68 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/harness/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | LINE="---------------" 4 | 5 | start() { 6 | if [ -d _harness ]; then 7 | echo "Daemon setup already in place, stop it first." 8 | exit 1 9 | fi 10 | mkdir -p _harness 11 | cd _harness 12 | cp -a ../harness/daemons . 13 | cp -a ../harness/certs . 14 | echo keyfile > certs/keyfile 15 | chmod 600 certs/keyfile 16 | if ! mongod --help | grep -q -- --ssl; then 17 | rm -rf daemons/db3 18 | fi 19 | COUNT=$(ls daemons | wc -l) 20 | echo "Running daemons..." 21 | svscan daemons & 22 | SVSCANPID=$! 23 | echo $SVSCANPID > svscan.pid 24 | if ! kill -0 $SVSCANPID; then 25 | echo "Cannot execute svscan." 26 | exit 1 27 | fi 28 | echo "Starting $COUNT processes..." 29 | for i in $(seq 30); do 30 | UP=$(svstat daemons/* | grep ' up ' | grep -v ' [0-3] seconds' | wc -l) 31 | echo "$UP processes up..." 32 | if [ x$COUNT = x$UP ]; then 33 | echo "Running setup.js with mongo..." 34 | mongo --nodb ../harness/mongojs/init.js 35 | exit 0 36 | fi 37 | sleep 1 38 | done 39 | echo "Failed to start processes. svstat _harness/daemons/* output:" 40 | echo $LINE 41 | svstat daemons/* 42 | echo $LINE 43 | for DAEMON in daemons/*; do 44 | if $(svstat $DAEMON | grep ' up ' | grep ' [0-3] seconds' > /dev/null); then 45 | echo "Logs for _harness/$DAEMON:" 46 | echo $LINE 47 | cat $DAEMON/log/log.txt 48 | echo $LINE 49 | fi 50 | done 51 | exit 1 52 | } 53 | 54 | stop() { 55 | if [ -d _harness ]; then 56 | cd _harness 57 | if [ -f svscan.pid ]; then 58 | kill -9 $(cat svscan.pid) 2> /dev/null || true 59 | svc -dx daemons/* daemons/*/log > /dev/null 2>&1 || true 60 | COUNT=$(ls daemons | wc -l) 61 | echo "Shutting down $COUNT processes..." 62 | while true; do 63 | DOWN=$(svstat daemons/* | grep 'supervise not running' | wc -l) 64 | echo "$DOWN processes down..." 65 | if [ x$DOWN = x$COUNT ]; then 66 | break 67 | fi 68 | sleep 1 69 | done 70 | rm svscan.pid 71 | echo "Done." 72 | fi 73 | cd .. 74 | rm -rf _harness 75 | fi 76 | } 77 | 78 | 79 | if [ ! -f suite_test.go ]; then 80 | echo "This script must be run from within the source directory." 81 | exit 1 82 | fi 83 | 84 | case "$1" in 85 | 86 | start) 87 | start $2 88 | ;; 89 | 90 | stop) 91 | stop $2 92 | ;; 93 | 94 | esac 95 | 96 | # vim:ts=4:sw=4:et 97 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The Go Authors. 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 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 | // Large data benchmark. 6 | // The JSON data is a summary of agl's changes in the 7 | // go, webkit, and chromium open source projects. 8 | // We benchmark converting between the JSON form 9 | // and in-memory data structures. 10 | 11 | package json 12 | 13 | import ( 14 | "bytes" 15 | "compress/gzip" 16 | "io/ioutil" 17 | "os" 18 | "strings" 19 | "testing" 20 | ) 21 | 22 | type codeResponse struct { 23 | Tree *codeNode `json:"tree"` 24 | Username string `json:"username"` 25 | } 26 | 27 | type codeNode struct { 28 | Name string `json:"name"` 29 | Kids []*codeNode `json:"kids"` 30 | CLWeight float64 `json:"cl_weight"` 31 | Touches int `json:"touches"` 32 | MinT int64 `json:"min_t"` 33 | MaxT int64 `json:"max_t"` 34 | MeanT int64 `json:"mean_t"` 35 | } 36 | 37 | var codeJSON []byte 38 | var codeStruct codeResponse 39 | 40 | func codeInit() { 41 | f, err := os.Open("testdata/code.json.gz") 42 | if err != nil { 43 | panic(err) 44 | } 45 | defer f.Close() 46 | gz, err := gzip.NewReader(f) 47 | if err != nil { 48 | panic(err) 49 | } 50 | data, err := ioutil.ReadAll(gz) 51 | if err != nil { 52 | panic(err) 53 | } 54 | 55 | codeJSON = data 56 | 57 | if err := Unmarshal(codeJSON, &codeStruct); err != nil { 58 | panic("unmarshal code.json: " + err.Error()) 59 | } 60 | 61 | if data, err = Marshal(&codeStruct); err != nil { 62 | panic("marshal code.json: " + err.Error()) 63 | } 64 | 65 | if !bytes.Equal(data, codeJSON) { 66 | println("different lengths", len(data), len(codeJSON)) 67 | for i := 0; i < len(data) && i < len(codeJSON); i++ { 68 | if data[i] != codeJSON[i] { 69 | println("re-marshal: changed at byte", i) 70 | println("orig: ", string(codeJSON[i-10:i+10])) 71 | println("new: ", string(data[i-10:i+10])) 72 | break 73 | } 74 | } 75 | panic("re-marshal code.json: different result") 76 | } 77 | } 78 | 79 | func BenchmarkCodeEncoder(b *testing.B) { 80 | if codeJSON == nil { 81 | b.StopTimer() 82 | codeInit() 83 | b.StartTimer() 84 | } 85 | enc := NewEncoder(ioutil.Discard) 86 | for i := 0; i < b.N; i++ { 87 | if err := enc.Encode(&codeStruct); err != nil { 88 | b.Fatal("Encode:", err) 89 | } 90 | } 91 | b.SetBytes(int64(len(codeJSON))) 92 | } 93 | 94 | func BenchmarkCodeMarshal(b *testing.B) { 95 | if codeJSON == nil { 96 | b.StopTimer() 97 | codeInit() 98 | b.StartTimer() 99 | } 100 | for i := 0; i < b.N; i++ { 101 | if _, err := Marshal(&codeStruct); err != nil { 102 | b.Fatal("Marshal:", err) 103 | } 104 | } 105 | b.SetBytes(int64(len(codeJSON))) 106 | } 107 | 108 | func BenchmarkCodeDecoder(b *testing.B) { 109 | if codeJSON == nil { 110 | b.StopTimer() 111 | codeInit() 112 | b.StartTimer() 113 | } 114 | var buf bytes.Buffer 115 | dec := NewDecoder(&buf) 116 | var r codeResponse 117 | for i := 0; i < b.N; i++ { 118 | buf.Write(codeJSON) 119 | // hide EOF 120 | buf.WriteByte('\n') 121 | buf.WriteByte('\n') 122 | buf.WriteByte('\n') 123 | if err := dec.Decode(&r); err != nil { 124 | b.Fatal("Decode:", err) 125 | } 126 | } 127 | b.SetBytes(int64(len(codeJSON))) 128 | } 129 | 130 | func BenchmarkDecoderStream(b *testing.B) { 131 | b.StopTimer() 132 | var buf bytes.Buffer 133 | dec := NewDecoder(&buf) 134 | buf.WriteString(`"` + strings.Repeat("x", 1000000) + `"` + "\n\n\n") 135 | var x interface{} 136 | if err := dec.Decode(&x); err != nil { 137 | b.Fatal("Decode:", err) 138 | } 139 | ones := strings.Repeat(" 1\n", 300000) + "\n\n\n" 140 | b.StartTimer() 141 | for i := 0; i < b.N; i++ { 142 | if i%300000 == 0 { 143 | buf.WriteString(ones) 144 | } 145 | x = nil 146 | if err := dec.Decode(&x); err != nil || x != 1.0 { 147 | b.Fatalf("Decode: %v after %d", err, i) 148 | } 149 | } 150 | } 151 | 152 | func BenchmarkCodeUnmarshal(b *testing.B) { 153 | if codeJSON == nil { 154 | b.StopTimer() 155 | codeInit() 156 | b.StartTimer() 157 | } 158 | for i := 0; i < b.N; i++ { 159 | var r codeResponse 160 | if err := Unmarshal(codeJSON, &r); err != nil { 161 | b.Fatal("Unmarshal:", err) 162 | } 163 | } 164 | b.SetBytes(int64(len(codeJSON))) 165 | } 166 | 167 | func BenchmarkCodeUnmarshalReuse(b *testing.B) { 168 | if codeJSON == nil { 169 | b.StopTimer() 170 | codeInit() 171 | b.StartTimer() 172 | } 173 | var r codeResponse 174 | for i := 0; i < b.N; i++ { 175 | if err := Unmarshal(codeJSON, &r); err != nil { 176 | b.Fatal("Unmarshal:", err) 177 | } 178 | } 179 | } 180 | 181 | func BenchmarkUnmarshalString(b *testing.B) { 182 | data := []byte(`"hello, world"`) 183 | var s string 184 | 185 | for i := 0; i < b.N; i++ { 186 | if err := Unmarshal(data, &s); err != nil { 187 | b.Fatal("Unmarshal:", err) 188 | } 189 | } 190 | } 191 | 192 | func BenchmarkUnmarshalFloat64(b *testing.B) { 193 | var f float64 194 | data := []byte(`3.14`) 195 | 196 | for i := 0; i < b.N; i++ { 197 | if err := Unmarshal(data, &f); err != nil { 198 | b.Fatal("Unmarshal:", err) 199 | } 200 | } 201 | } 202 | 203 | func BenchmarkUnmarshalInt64(b *testing.B) { 204 | var x int64 205 | data := []byte(`3`) 206 | 207 | for i := 0; i < b.N; i++ { 208 | if err := Unmarshal(data, &x); err != nil { 209 | b.Fatal("Unmarshal:", err) 210 | } 211 | } 212 | } 213 | 214 | func BenchmarkIssue10335(b *testing.B) { 215 | b.ReportAllocs() 216 | var s struct{} 217 | j := []byte(`{"a":{ }}`) 218 | for n := 0; n < b.N; n++ { 219 | if err := Unmarshal(j, &s); err != nil { 220 | b.Fatal(err) 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 json_test 6 | 7 | import ( 8 | "bytes" 9 | "encoding/json" 10 | "fmt" 11 | "io" 12 | "log" 13 | "os" 14 | "strings" 15 | ) 16 | 17 | func ExampleMarshal() { 18 | type ColorGroup struct { 19 | ID int 20 | Name string 21 | Colors []string 22 | } 23 | group := ColorGroup{ 24 | ID: 1, 25 | Name: "Reds", 26 | Colors: []string{"Crimson", "Red", "Ruby", "Maroon"}, 27 | } 28 | b, err := json.Marshal(group) 29 | if err != nil { 30 | fmt.Println("error:", err) 31 | } 32 | os.Stdout.Write(b) 33 | // Output: 34 | // {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]} 35 | } 36 | 37 | func ExampleUnmarshal() { 38 | var jsonBlob = []byte(`[ 39 | {"Name": "Platypus", "Order": "Monotremata"}, 40 | {"Name": "Quoll", "Order": "Dasyuromorphia"} 41 | ]`) 42 | type Animal struct { 43 | Name string 44 | Order string 45 | } 46 | var animals []Animal 47 | err := json.Unmarshal(jsonBlob, &animals) 48 | if err != nil { 49 | fmt.Println("error:", err) 50 | } 51 | fmt.Printf("%+v", animals) 52 | // Output: 53 | // [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}] 54 | } 55 | 56 | // This example uses a Decoder to decode a stream of distinct JSON values. 57 | func ExampleDecoder() { 58 | const jsonStream = ` 59 | {"Name": "Ed", "Text": "Knock knock."} 60 | {"Name": "Sam", "Text": "Who's there?"} 61 | {"Name": "Ed", "Text": "Go fmt."} 62 | {"Name": "Sam", "Text": "Go fmt who?"} 63 | {"Name": "Ed", "Text": "Go fmt yourself!"} 64 | ` 65 | type Message struct { 66 | Name, Text string 67 | } 68 | dec := json.NewDecoder(strings.NewReader(jsonStream)) 69 | for { 70 | var m Message 71 | if err := dec.Decode(&m); err == io.EOF { 72 | break 73 | } else if err != nil { 74 | log.Fatal(err) 75 | } 76 | fmt.Printf("%s: %s\n", m.Name, m.Text) 77 | } 78 | // Output: 79 | // Ed: Knock knock. 80 | // Sam: Who's there? 81 | // Ed: Go fmt. 82 | // Sam: Go fmt who? 83 | // Ed: Go fmt yourself! 84 | } 85 | 86 | // This example uses a Decoder to decode a stream of distinct JSON values. 87 | func ExampleDecoder_Token() { 88 | const jsonStream = ` 89 | {"Message": "Hello", "Array": [1, 2, 3], "Null": null, "Number": 1.234} 90 | ` 91 | dec := json.NewDecoder(strings.NewReader(jsonStream)) 92 | for { 93 | t, err := dec.Token() 94 | if err == io.EOF { 95 | break 96 | } 97 | if err != nil { 98 | log.Fatal(err) 99 | } 100 | fmt.Printf("%T: %v", t, t) 101 | if dec.More() { 102 | fmt.Printf(" (more)") 103 | } 104 | fmt.Printf("\n") 105 | } 106 | // Output: 107 | // json.Delim: { (more) 108 | // string: Message (more) 109 | // string: Hello (more) 110 | // string: Array (more) 111 | // json.Delim: [ (more) 112 | // float64: 1 (more) 113 | // float64: 2 (more) 114 | // float64: 3 115 | // json.Delim: ] (more) 116 | // string: Null (more) 117 | // : (more) 118 | // string: Number (more) 119 | // float64: 1.234 120 | // json.Delim: } 121 | } 122 | 123 | // This example uses a Decoder to decode a streaming array of JSON objects. 124 | func ExampleDecoder_Decode_stream() { 125 | const jsonStream = ` 126 | [ 127 | {"Name": "Ed", "Text": "Knock knock."}, 128 | {"Name": "Sam", "Text": "Who's there?"}, 129 | {"Name": "Ed", "Text": "Go fmt."}, 130 | {"Name": "Sam", "Text": "Go fmt who?"}, 131 | {"Name": "Ed", "Text": "Go fmt yourself!"} 132 | ] 133 | ` 134 | type Message struct { 135 | Name, Text string 136 | } 137 | dec := json.NewDecoder(strings.NewReader(jsonStream)) 138 | 139 | // read open bracket 140 | t, err := dec.Token() 141 | if err != nil { 142 | log.Fatal(err) 143 | } 144 | fmt.Printf("%T: %v\n", t, t) 145 | 146 | var m Message 147 | // while the array contains values 148 | for dec.More() { 149 | 150 | // decode an array value (Message) 151 | err := dec.Decode(&m) 152 | if err != nil { 153 | log.Fatal(err) 154 | } 155 | 156 | fmt.Printf("%v: %v\n", m.Name, m.Text) 157 | } 158 | 159 | // read closing bracket 160 | t, err = dec.Token() 161 | if err != nil { 162 | log.Fatal(err) 163 | } 164 | fmt.Printf("%T: %v\n", t, t) 165 | 166 | // Output: 167 | // json.Delim: [ 168 | // Ed: Knock knock. 169 | // Sam: Who's there? 170 | // Ed: Go fmt. 171 | // Sam: Go fmt who? 172 | // Ed: Go fmt yourself! 173 | // json.Delim: ] 174 | 175 | } 176 | 177 | // This example uses RawMessage to delay parsing part of a JSON message. 178 | func ExampleRawMessage() { 179 | type Color struct { 180 | Space string 181 | Point json.RawMessage // delay parsing until we know the color space 182 | } 183 | type RGB struct { 184 | R uint8 185 | G uint8 186 | B uint8 187 | } 188 | type YCbCr struct { 189 | Y uint8 190 | Cb int8 191 | Cr int8 192 | } 193 | 194 | var j = []byte(`[ 195 | {"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}, 196 | {"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255}} 197 | ]`) 198 | var colors []Color 199 | err := json.Unmarshal(j, &colors) 200 | if err != nil { 201 | log.Fatalln("error:", err) 202 | } 203 | 204 | for _, c := range colors { 205 | var dst interface{} 206 | switch c.Space { 207 | case "RGB": 208 | dst = new(RGB) 209 | case "YCbCr": 210 | dst = new(YCbCr) 211 | } 212 | err := json.Unmarshal(c.Point, dst) 213 | if err != nil { 214 | log.Fatalln("error:", err) 215 | } 216 | fmt.Println(c.Space, dst) 217 | } 218 | // Output: 219 | // YCbCr &{255 0 -10} 220 | // RGB &{98 218 255} 221 | } 222 | 223 | func ExampleIndent() { 224 | type Road struct { 225 | Name string 226 | Number int 227 | } 228 | roads := []Road{ 229 | {"Diamond Fork", 29}, 230 | {"Sheep Creek", 51}, 231 | } 232 | 233 | b, err := json.Marshal(roads) 234 | if err != nil { 235 | log.Fatal(err) 236 | } 237 | 238 | var out bytes.Buffer 239 | json.Indent(&out, b, "=", "\t") 240 | out.WriteTo(os.Stdout) 241 | // Output: 242 | // [ 243 | // = { 244 | // = "Name": "Diamond Fork", 245 | // = "Number": 29 246 | // = }, 247 | // = { 248 | // = "Name": "Sheep Creek", 249 | // = "Number": 51 250 | // = } 251 | // =] 252 | } 253 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/extension.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | // Extension holds a set of additional rules to be used when unmarshaling 8 | // strict JSON or JSON-like content. 9 | type Extension struct { 10 | funcs map[string]funcExt 11 | consts map[string]interface{} 12 | keyed map[string]func([]byte) (interface{}, error) 13 | encode map[reflect.Type]func(v interface{}) ([]byte, error) 14 | 15 | unquotedKeys bool 16 | trailingCommas bool 17 | } 18 | 19 | type funcExt struct { 20 | key string 21 | args []string 22 | } 23 | 24 | // Extend changes the decoder behavior to consider the provided extension. 25 | func (dec *Decoder) Extend(ext *Extension) { dec.d.ext = *ext } 26 | 27 | // Extend changes the encoder behavior to consider the provided extension. 28 | func (enc *Encoder) Extend(ext *Extension) { enc.ext = *ext } 29 | 30 | // Extend includes in e the extensions defined in ext. 31 | func (e *Extension) Extend(ext *Extension) { 32 | for name, fext := range ext.funcs { 33 | e.DecodeFunc(name, fext.key, fext.args...) 34 | } 35 | for name, value := range ext.consts { 36 | e.DecodeConst(name, value) 37 | } 38 | for key, decode := range ext.keyed { 39 | e.DecodeKeyed(key, decode) 40 | } 41 | for typ, encode := range ext.encode { 42 | if e.encode == nil { 43 | e.encode = make(map[reflect.Type]func(v interface{}) ([]byte, error)) 44 | } 45 | e.encode[typ] = encode 46 | } 47 | } 48 | 49 | // DecodeFunc defines a function call that may be observed inside JSON content. 50 | // A function with the provided name will be unmarshaled as the document 51 | // {key: {args[0]: ..., args[N]: ...}}. 52 | func (e *Extension) DecodeFunc(name string, key string, args ...string) { 53 | if e.funcs == nil { 54 | e.funcs = make(map[string]funcExt) 55 | } 56 | e.funcs[name] = funcExt{key, args} 57 | } 58 | 59 | // DecodeConst defines a constant name that may be observed inside JSON content 60 | // and will be decoded with the provided value. 61 | func (e *Extension) DecodeConst(name string, value interface{}) { 62 | if e.consts == nil { 63 | e.consts = make(map[string]interface{}) 64 | } 65 | e.consts[name] = value 66 | } 67 | 68 | // DecodeKeyed defines a key that when observed as the first element inside a 69 | // JSON document triggers the decoding of that document via the provided 70 | // decode function. 71 | func (e *Extension) DecodeKeyed(key string, decode func(data []byte) (interface{}, error)) { 72 | if e.keyed == nil { 73 | e.keyed = make(map[string]func([]byte) (interface{}, error)) 74 | } 75 | e.keyed[key] = decode 76 | } 77 | 78 | // DecodeUnquotedKeys defines whether to accept map keys that are unquoted strings. 79 | func (e *Extension) DecodeUnquotedKeys(accept bool) { 80 | e.unquotedKeys = accept 81 | } 82 | 83 | // DecodeTrailingCommas defines whether to accept trailing commas in maps and arrays. 84 | func (e *Extension) DecodeTrailingCommas(accept bool) { 85 | e.trailingCommas = accept 86 | } 87 | 88 | // EncodeType registers a function to encode values with the same type of the 89 | // provided sample. 90 | func (e *Extension) EncodeType(sample interface{}, encode func(v interface{}) ([]byte, error)) { 91 | if e.encode == nil { 92 | e.encode = make(map[reflect.Type]func(v interface{}) ([]byte, error)) 93 | } 94 | e.encode[reflect.TypeOf(sample)] = encode 95 | } 96 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/extension_test.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "reflect" 7 | "strconv" 8 | "testing" 9 | ) 10 | 11 | type funcN struct { 12 | Arg1 int `json:"arg1"` 13 | Arg2 int `json:"arg2"` 14 | } 15 | 16 | type funcs struct { 17 | Func2 *funcN `json:"$func2"` 18 | Func1 *funcN `json:"$func1"` 19 | } 20 | 21 | type funcsText struct { 22 | Func1 jsonText `json:"$func1"` 23 | Func2 jsonText `json:"$func2"` 24 | } 25 | 26 | type jsonText struct { 27 | json string 28 | } 29 | 30 | func (jt *jsonText) UnmarshalJSON(data []byte) error { 31 | jt.json = string(data) 32 | return nil 33 | } 34 | 35 | type nestedText struct { 36 | F jsonText 37 | B bool 38 | } 39 | 40 | type unquotedKey struct { 41 | S string `json:"$k_1"` 42 | } 43 | 44 | var ext Extension 45 | 46 | type keyed string 47 | 48 | func decodeKeyed(data []byte) (interface{}, error) { 49 | return keyed(data), nil 50 | } 51 | 52 | type keyedType struct { 53 | K keyed 54 | I int 55 | } 56 | 57 | type docint int 58 | 59 | type const1Type struct{} 60 | 61 | var const1 = new(const1Type) 62 | 63 | func init() { 64 | ext.DecodeFunc("Func1", "$func1") 65 | ext.DecodeFunc("Func2", "$func2", "arg1", "arg2") 66 | ext.DecodeFunc("Func3", "$func3", "arg1") 67 | ext.DecodeFunc("new Func4", "$func4", "arg1") 68 | 69 | ext.DecodeConst("Const1", const1) 70 | 71 | ext.DecodeKeyed("$key1", decodeKeyed) 72 | ext.DecodeKeyed("$func3", decodeKeyed) 73 | 74 | ext.EncodeType(docint(0), func(v interface{}) ([]byte, error) { 75 | s := `{"$docint": ` + strconv.Itoa(int(v.(docint))) + `}` 76 | return []byte(s), nil 77 | }) 78 | 79 | ext.DecodeUnquotedKeys(true) 80 | ext.DecodeTrailingCommas(true) 81 | } 82 | 83 | type extDecodeTest struct { 84 | in string 85 | ptr interface{} 86 | out interface{} 87 | err error 88 | 89 | noext bool 90 | } 91 | 92 | var extDecodeTests = []extDecodeTest{ 93 | // Functions 94 | {in: `Func1()`, ptr: new(interface{}), out: map[string]interface{}{ 95 | "$func1": map[string]interface{}{}, 96 | }}, 97 | {in: `{"v": Func1()}`, ptr: new(interface{}), out: map[string]interface{}{ 98 | "v": map[string]interface{}{"$func1": map[string]interface{}{}}, 99 | }}, 100 | {in: `Func2(1)`, ptr: new(interface{}), out: map[string]interface{}{ 101 | "$func2": map[string]interface{}{"arg1": float64(1)}, 102 | }}, 103 | {in: `Func2(1, 2)`, ptr: new(interface{}), out: map[string]interface{}{ 104 | "$func2": map[string]interface{}{"arg1": float64(1), "arg2": float64(2)}, 105 | }}, 106 | {in: `Func2(Func1())`, ptr: new(interface{}), out: map[string]interface{}{ 107 | "$func2": map[string]interface{}{"arg1": map[string]interface{}{"$func1": map[string]interface{}{}}}, 108 | }}, 109 | {in: `Func2(1, 2, 3)`, ptr: new(interface{}), err: fmt.Errorf("json: too many arguments for function Func2")}, 110 | {in: `BadFunc()`, ptr: new(interface{}), err: fmt.Errorf(`json: unknown function "BadFunc"`)}, 111 | 112 | {in: `Func1()`, ptr: new(funcs), out: funcs{Func1: &funcN{}}}, 113 | {in: `Func2(1)`, ptr: new(funcs), out: funcs{Func2: &funcN{Arg1: 1}}}, 114 | {in: `Func2(1, 2)`, ptr: new(funcs), out: funcs{Func2: &funcN{Arg1: 1, Arg2: 2}}}, 115 | 116 | {in: `Func2(1, 2, 3)`, ptr: new(funcs), err: fmt.Errorf("json: too many arguments for function Func2")}, 117 | {in: `BadFunc()`, ptr: new(funcs), err: fmt.Errorf(`json: unknown function "BadFunc"`)}, 118 | 119 | {in: `Func2(1)`, ptr: new(jsonText), out: jsonText{"Func2(1)"}}, 120 | {in: `Func2(1, 2)`, ptr: new(funcsText), out: funcsText{Func2: jsonText{"Func2(1, 2)"}}}, 121 | {in: `{"f": Func2(1, 2), "b": true}`, ptr: new(nestedText), out: nestedText{jsonText{"Func2(1, 2)"}, true}}, 122 | 123 | {in: `Func1()`, ptr: new(struct{}), out: struct{}{}}, 124 | 125 | // Functions with "new" prefix 126 | {in: `new Func4(1)`, ptr: new(interface{}), out: map[string]interface{}{ 127 | "$func4": map[string]interface{}{"arg1": float64(1)}, 128 | }}, 129 | 130 | // Constants 131 | {in: `Const1`, ptr: new(interface{}), out: const1}, 132 | {in: `{"c": Const1}`, ptr: new(struct{ C *const1Type }), out: struct{ C *const1Type }{const1}}, 133 | 134 | // Keyed documents 135 | {in: `{"v": {"$key1": 1}}`, ptr: new(interface{}), out: map[string]interface{}{"v": keyed(`{"$key1": 1}`)}}, 136 | {in: `{"k": {"$key1": 1}}`, ptr: new(keyedType), out: keyedType{K: keyed(`{"$key1": 1}`)}}, 137 | {in: `{"i": {"$key1": 1}}`, ptr: new(keyedType), err: &UnmarshalTypeError{"object", reflect.TypeOf(0), 18}}, 138 | 139 | // Keyed function documents 140 | {in: `{"v": Func3()}`, ptr: new(interface{}), out: map[string]interface{}{"v": keyed(`Func3()`)}}, 141 | {in: `{"k": Func3()}`, ptr: new(keyedType), out: keyedType{K: keyed(`Func3()`)}}, 142 | {in: `{"i": Func3()}`, ptr: new(keyedType), err: &UnmarshalTypeError{"object", reflect.TypeOf(0), 13}}, 143 | 144 | // Unquoted keys 145 | {in: `{$k_1: "bar"}`, ptr: new(interface{}), out: map[string]interface{}{"$k_1": "bar"}}, 146 | {in: `{$k_1: "bar"}`, ptr: new(unquotedKey), out: unquotedKey{"bar"}}, 147 | 148 | {in: `{$k_1: "bar"}`, noext: true, ptr: new(interface{}), 149 | err: &SyntaxError{"invalid character '$' looking for beginning of object key string", 2}}, 150 | {in: `{$k_1: "bar"}`, noext: true, ptr: new(unquotedKey), 151 | err: &SyntaxError{"invalid character '$' looking for beginning of object key string", 2}}, 152 | 153 | // Trailing commas 154 | {in: `{"k": "v",}`, ptr: new(interface{}), out: map[string]interface{}{"k": "v"}}, 155 | {in: `{"k": "v",}`, ptr: new(struct{}), out: struct{}{}}, 156 | {in: `["v",]`, ptr: new(interface{}), out: []interface{}{"v"}}, 157 | 158 | {in: `{"k": "v",}`, noext: true, ptr: new(interface{}), 159 | err: &SyntaxError{"invalid character '}' looking for beginning of object key string", 11}}, 160 | {in: `{"k": "v",}`, noext: true, ptr: new(struct{}), 161 | err: &SyntaxError{"invalid character '}' looking for beginning of object key string", 11}}, 162 | {in: `["a",]`, noext: true, ptr: new(interface{}), 163 | err: &SyntaxError{"invalid character ']' looking for beginning of value", 6}}, 164 | } 165 | 166 | type extEncodeTest struct { 167 | in interface{} 168 | out string 169 | err error 170 | } 171 | 172 | var extEncodeTests = []extEncodeTest{ 173 | {in: docint(13), out: "{\"$docint\":13}\n"}, 174 | } 175 | 176 | func TestExtensionDecode(t *testing.T) { 177 | for i, tt := range extDecodeTests { 178 | in := []byte(tt.in) 179 | 180 | // v = new(right-type) 181 | v := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 182 | dec := NewDecoder(bytes.NewReader(in)) 183 | if !tt.noext { 184 | dec.Extend(&ext) 185 | } 186 | if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) { 187 | t.Errorf("#%d: %v, want %v", i, err, tt.err) 188 | continue 189 | } else if err != nil { 190 | continue 191 | } 192 | if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { 193 | t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) 194 | data, _ := Marshal(v.Elem().Interface()) 195 | t.Logf("%s", string(data)) 196 | data, _ = Marshal(tt.out) 197 | t.Logf("%s", string(data)) 198 | continue 199 | } 200 | } 201 | } 202 | 203 | func TestExtensionEncode(t *testing.T) { 204 | var buf bytes.Buffer 205 | for i, tt := range extEncodeTests { 206 | buf.Truncate(0) 207 | enc := NewEncoder(&buf) 208 | enc.Extend(&ext) 209 | err := enc.Encode(tt.in) 210 | if !reflect.DeepEqual(err, tt.err) { 211 | t.Errorf("#%d: %v, want %v", i, err, tt.err) 212 | continue 213 | } 214 | if buf.String() != tt.out { 215 | t.Errorf("#%d: mismatch\nhave: %q\nwant: %q", i, buf.String(), tt.out) 216 | } 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/fold.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 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 json 6 | 7 | import ( 8 | "bytes" 9 | "unicode/utf8" 10 | ) 11 | 12 | const ( 13 | caseMask = ^byte(0x20) // Mask to ignore case in ASCII. 14 | kelvin = '\u212a' 15 | smallLongEss = '\u017f' 16 | ) 17 | 18 | // foldFunc returns one of four different case folding equivalence 19 | // functions, from most general (and slow) to fastest: 20 | // 21 | // 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 22 | // 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') 23 | // 3) asciiEqualFold, no special, but includes non-letters (including _) 24 | // 4) simpleLetterEqualFold, no specials, no non-letters. 25 | // 26 | // The letters S and K are special because they map to 3 runes, not just 2: 27 | // * S maps to s and to U+017F 'ſ' Latin small letter long s 28 | // * k maps to K and to U+212A 'K' Kelvin sign 29 | // See https://play.golang.org/p/tTxjOc0OGo 30 | // 31 | // The returned function is specialized for matching against s and 32 | // should only be given s. It's not curried for performance reasons. 33 | func foldFunc(s []byte) func(s, t []byte) bool { 34 | nonLetter := false 35 | special := false // special letter 36 | for _, b := range s { 37 | if b >= utf8.RuneSelf { 38 | return bytes.EqualFold 39 | } 40 | upper := b & caseMask 41 | if upper < 'A' || upper > 'Z' { 42 | nonLetter = true 43 | } else if upper == 'K' || upper == 'S' { 44 | // See above for why these letters are special. 45 | special = true 46 | } 47 | } 48 | if special { 49 | return equalFoldRight 50 | } 51 | if nonLetter { 52 | return asciiEqualFold 53 | } 54 | return simpleLetterEqualFold 55 | } 56 | 57 | // equalFoldRight is a specialization of bytes.EqualFold when s is 58 | // known to be all ASCII (including punctuation), but contains an 's', 59 | // 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. 60 | // See comments on foldFunc. 61 | func equalFoldRight(s, t []byte) bool { 62 | for _, sb := range s { 63 | if len(t) == 0 { 64 | return false 65 | } 66 | tb := t[0] 67 | if tb < utf8.RuneSelf { 68 | if sb != tb { 69 | sbUpper := sb & caseMask 70 | if 'A' <= sbUpper && sbUpper <= 'Z' { 71 | if sbUpper != tb&caseMask { 72 | return false 73 | } 74 | } else { 75 | return false 76 | } 77 | } 78 | t = t[1:] 79 | continue 80 | } 81 | // sb is ASCII and t is not. t must be either kelvin 82 | // sign or long s; sb must be s, S, k, or K. 83 | tr, size := utf8.DecodeRune(t) 84 | switch sb { 85 | case 's', 'S': 86 | if tr != smallLongEss { 87 | return false 88 | } 89 | case 'k', 'K': 90 | if tr != kelvin { 91 | return false 92 | } 93 | default: 94 | return false 95 | } 96 | t = t[size:] 97 | 98 | } 99 | if len(t) > 0 { 100 | return false 101 | } 102 | return true 103 | } 104 | 105 | // asciiEqualFold is a specialization of bytes.EqualFold for use when 106 | // s is all ASCII (but may contain non-letters) and contains no 107 | // special-folding letters. 108 | // See comments on foldFunc. 109 | func asciiEqualFold(s, t []byte) bool { 110 | if len(s) != len(t) { 111 | return false 112 | } 113 | for i, sb := range s { 114 | tb := t[i] 115 | if sb == tb { 116 | continue 117 | } 118 | if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { 119 | if sb&caseMask != tb&caseMask { 120 | return false 121 | } 122 | } else { 123 | return false 124 | } 125 | } 126 | return true 127 | } 128 | 129 | // simpleLetterEqualFold is a specialization of bytes.EqualFold for 130 | // use when s is all ASCII letters (no underscores, etc) and also 131 | // doesn't contain 'k', 'K', 's', or 'S'. 132 | // See comments on foldFunc. 133 | func simpleLetterEqualFold(s, t []byte) bool { 134 | if len(s) != len(t) { 135 | return false 136 | } 137 | for i, b := range s { 138 | if b&caseMask != t[i]&caseMask { 139 | return false 140 | } 141 | } 142 | return true 143 | } 144 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/fold_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 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 json 6 | 7 | import ( 8 | "bytes" 9 | "strings" 10 | "testing" 11 | "unicode/utf8" 12 | ) 13 | 14 | var foldTests = []struct { 15 | fn func(s, t []byte) bool 16 | s, t string 17 | want bool 18 | }{ 19 | {equalFoldRight, "", "", true}, 20 | {equalFoldRight, "a", "a", true}, 21 | {equalFoldRight, "", "a", false}, 22 | {equalFoldRight, "a", "", false}, 23 | {equalFoldRight, "a", "A", true}, 24 | {equalFoldRight, "AB", "ab", true}, 25 | {equalFoldRight, "AB", "ac", false}, 26 | {equalFoldRight, "sbkKc", "ſbKKc", true}, 27 | {equalFoldRight, "SbKkc", "ſbKKc", true}, 28 | {equalFoldRight, "SbKkc", "ſbKK", false}, 29 | {equalFoldRight, "e", "é", false}, 30 | {equalFoldRight, "s", "S", true}, 31 | 32 | {simpleLetterEqualFold, "", "", true}, 33 | {simpleLetterEqualFold, "abc", "abc", true}, 34 | {simpleLetterEqualFold, "abc", "ABC", true}, 35 | {simpleLetterEqualFold, "abc", "ABCD", false}, 36 | {simpleLetterEqualFold, "abc", "xxx", false}, 37 | 38 | {asciiEqualFold, "a_B", "A_b", true}, 39 | {asciiEqualFold, "aa@", "aa`", false}, // verify 0x40 and 0x60 aren't case-equivalent 40 | } 41 | 42 | func TestFold(t *testing.T) { 43 | for i, tt := range foldTests { 44 | if got := tt.fn([]byte(tt.s), []byte(tt.t)); got != tt.want { 45 | t.Errorf("%d. %q, %q = %v; want %v", i, tt.s, tt.t, got, tt.want) 46 | } 47 | truth := strings.EqualFold(tt.s, tt.t) 48 | if truth != tt.want { 49 | t.Errorf("strings.EqualFold doesn't agree with case %d", i) 50 | } 51 | } 52 | } 53 | 54 | func TestFoldAgainstUnicode(t *testing.T) { 55 | const bufSize = 5 56 | buf1 := make([]byte, 0, bufSize) 57 | buf2 := make([]byte, 0, bufSize) 58 | var runes []rune 59 | for i := 0x20; i <= 0x7f; i++ { 60 | runes = append(runes, rune(i)) 61 | } 62 | runes = append(runes, kelvin, smallLongEss) 63 | 64 | funcs := []struct { 65 | name string 66 | fold func(s, t []byte) bool 67 | letter bool // must be ASCII letter 68 | simple bool // must be simple ASCII letter (not 'S' or 'K') 69 | }{ 70 | { 71 | name: "equalFoldRight", 72 | fold: equalFoldRight, 73 | }, 74 | { 75 | name: "asciiEqualFold", 76 | fold: asciiEqualFold, 77 | simple: true, 78 | }, 79 | { 80 | name: "simpleLetterEqualFold", 81 | fold: simpleLetterEqualFold, 82 | simple: true, 83 | letter: true, 84 | }, 85 | } 86 | 87 | for _, ff := range funcs { 88 | for _, r := range runes { 89 | if r >= utf8.RuneSelf { 90 | continue 91 | } 92 | if ff.letter && !isASCIILetter(byte(r)) { 93 | continue 94 | } 95 | if ff.simple && (r == 's' || r == 'S' || r == 'k' || r == 'K') { 96 | continue 97 | } 98 | for _, r2 := range runes { 99 | buf1 := append(buf1[:0], 'x') 100 | buf2 := append(buf2[:0], 'x') 101 | buf1 = buf1[:1+utf8.EncodeRune(buf1[1:bufSize], r)] 102 | buf2 = buf2[:1+utf8.EncodeRune(buf2[1:bufSize], r2)] 103 | buf1 = append(buf1, 'x') 104 | buf2 = append(buf2, 'x') 105 | want := bytes.EqualFold(buf1, buf2) 106 | if got := ff.fold(buf1, buf2); got != want { 107 | t.Errorf("%s(%q, %q) = %v; want %v", ff.name, buf1, buf2, got, want) 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | func isASCIILetter(b byte) bool { 115 | return ('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') 116 | } 117 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/indent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 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 json 6 | 7 | import "bytes" 8 | 9 | // Compact appends to dst the JSON-encoded src with 10 | // insignificant space characters elided. 11 | func Compact(dst *bytes.Buffer, src []byte) error { 12 | return compact(dst, src, false) 13 | } 14 | 15 | func compact(dst *bytes.Buffer, src []byte, escape bool) error { 16 | origLen := dst.Len() 17 | var scan scanner 18 | scan.reset() 19 | start := 0 20 | for i, c := range src { 21 | if escape && (c == '<' || c == '>' || c == '&') { 22 | if start < i { 23 | dst.Write(src[start:i]) 24 | } 25 | dst.WriteString(`\u00`) 26 | dst.WriteByte(hex[c>>4]) 27 | dst.WriteByte(hex[c&0xF]) 28 | start = i + 1 29 | } 30 | // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9). 31 | if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 { 32 | if start < i { 33 | dst.Write(src[start:i]) 34 | } 35 | dst.WriteString(`\u202`) 36 | dst.WriteByte(hex[src[i+2]&0xF]) 37 | start = i + 3 38 | } 39 | v := scan.step(&scan, c) 40 | if v >= scanSkipSpace { 41 | if v == scanError { 42 | break 43 | } 44 | if start < i { 45 | dst.Write(src[start:i]) 46 | } 47 | start = i + 1 48 | } 49 | } 50 | if scan.eof() == scanError { 51 | dst.Truncate(origLen) 52 | return scan.err 53 | } 54 | if start < len(src) { 55 | dst.Write(src[start:]) 56 | } 57 | return nil 58 | } 59 | 60 | func newline(dst *bytes.Buffer, prefix, indent string, depth int) { 61 | dst.WriteByte('\n') 62 | dst.WriteString(prefix) 63 | for i := 0; i < depth; i++ { 64 | dst.WriteString(indent) 65 | } 66 | } 67 | 68 | // Indent appends to dst an indented form of the JSON-encoded src. 69 | // Each element in a JSON object or array begins on a new, 70 | // indented line beginning with prefix followed by one or more 71 | // copies of indent according to the indentation nesting. 72 | // The data appended to dst does not begin with the prefix nor 73 | // any indentation, to make it easier to embed inside other formatted JSON data. 74 | // Although leading space characters (space, tab, carriage return, newline) 75 | // at the beginning of src are dropped, trailing space characters 76 | // at the end of src are preserved and copied to dst. 77 | // For example, if src has no trailing spaces, neither will dst; 78 | // if src ends in a trailing newline, so will dst. 79 | func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error { 80 | origLen := dst.Len() 81 | var scan scanner 82 | scan.reset() 83 | needIndent := false 84 | depth := 0 85 | for _, c := range src { 86 | scan.bytes++ 87 | v := scan.step(&scan, c) 88 | if v == scanSkipSpace { 89 | continue 90 | } 91 | if v == scanError { 92 | break 93 | } 94 | if needIndent && v != scanEndObject && v != scanEndArray { 95 | needIndent = false 96 | depth++ 97 | newline(dst, prefix, indent, depth) 98 | } 99 | 100 | // Emit semantically uninteresting bytes 101 | // (in particular, punctuation in strings) unmodified. 102 | if v == scanContinue { 103 | dst.WriteByte(c) 104 | continue 105 | } 106 | 107 | // Add spacing around real punctuation. 108 | switch c { 109 | case '{', '[': 110 | // delay indent so that empty object and array are formatted as {} and []. 111 | needIndent = true 112 | dst.WriteByte(c) 113 | 114 | case ',': 115 | dst.WriteByte(c) 116 | newline(dst, prefix, indent, depth) 117 | 118 | case ':': 119 | dst.WriteByte(c) 120 | dst.WriteByte(' ') 121 | 122 | case '}', ']': 123 | if needIndent { 124 | // suppress indent in empty object/array 125 | needIndent = false 126 | } else { 127 | depth-- 128 | newline(dst, prefix, indent, depth) 129 | } 130 | dst.WriteByte(c) 131 | 132 | default: 133 | dst.WriteByte(c) 134 | } 135 | } 136 | if scan.eof() == scanError { 137 | dst.Truncate(origLen) 138 | return scan.err 139 | } 140 | return nil 141 | } 142 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/number_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 json 6 | 7 | import ( 8 | "regexp" 9 | "testing" 10 | ) 11 | 12 | func TestNumberIsValid(t *testing.T) { 13 | // From: http://stackoverflow.com/a/13340826 14 | var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`) 15 | 16 | validTests := []string{ 17 | "0", 18 | "-0", 19 | "1", 20 | "-1", 21 | "0.1", 22 | "-0.1", 23 | "1234", 24 | "-1234", 25 | "12.34", 26 | "-12.34", 27 | "12E0", 28 | "12E1", 29 | "12e34", 30 | "12E-0", 31 | "12e+1", 32 | "12e-34", 33 | "-12E0", 34 | "-12E1", 35 | "-12e34", 36 | "-12E-0", 37 | "-12e+1", 38 | "-12e-34", 39 | "1.2E0", 40 | "1.2E1", 41 | "1.2e34", 42 | "1.2E-0", 43 | "1.2e+1", 44 | "1.2e-34", 45 | "-1.2E0", 46 | "-1.2E1", 47 | "-1.2e34", 48 | "-1.2E-0", 49 | "-1.2e+1", 50 | "-1.2e-34", 51 | "0E0", 52 | "0E1", 53 | "0e34", 54 | "0E-0", 55 | "0e+1", 56 | "0e-34", 57 | "-0E0", 58 | "-0E1", 59 | "-0e34", 60 | "-0E-0", 61 | "-0e+1", 62 | "-0e-34", 63 | } 64 | 65 | for _, test := range validTests { 66 | if !isValidNumber(test) { 67 | t.Errorf("%s should be valid", test) 68 | } 69 | 70 | var f float64 71 | if err := Unmarshal([]byte(test), &f); err != nil { 72 | t.Errorf("%s should be valid but Unmarshal failed: %v", test, err) 73 | } 74 | 75 | if !jsonNumberRegexp.MatchString(test) { 76 | t.Errorf("%s should be valid but regexp does not match", test) 77 | } 78 | } 79 | 80 | invalidTests := []string{ 81 | "", 82 | "invalid", 83 | "1.0.1", 84 | "1..1", 85 | "-1-2", 86 | "012a42", 87 | "01.2", 88 | "012", 89 | "12E12.12", 90 | "1e2e3", 91 | "1e+-2", 92 | "1e--23", 93 | "1e", 94 | "e1", 95 | "1e+", 96 | "1ea", 97 | "1a", 98 | "1.a", 99 | "1.", 100 | "01", 101 | "1.e1", 102 | } 103 | 104 | for _, test := range invalidTests { 105 | if isValidNumber(test) { 106 | t.Errorf("%s should be invalid", test) 107 | } 108 | 109 | var f float64 110 | if err := Unmarshal([]byte(test), &f); err == nil { 111 | t.Errorf("%s should be invalid but unmarshal wrote %v", test, f) 112 | } 113 | 114 | if jsonNumberRegexp.MatchString(test) { 115 | t.Errorf("%s should be invalid but matches regexp", test) 116 | } 117 | } 118 | } 119 | 120 | func BenchmarkNumberIsValid(b *testing.B) { 121 | s := "-61657.61667E+61673" 122 | for i := 0; i < b.N; i++ { 123 | isValidNumber(s) 124 | } 125 | } 126 | 127 | func BenchmarkNumberIsValidRegexp(b *testing.B) { 128 | var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`) 129 | s := "-61657.61667E+61673" 130 | for i := 0; i < b.N; i++ { 131 | jsonNumberRegexp.MatchString(s) 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/tagkey_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 json 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | type basicLatin2xTag struct { 12 | V string `json:"$%-/"` 13 | } 14 | 15 | type basicLatin3xTag struct { 16 | V string `json:"0123456789"` 17 | } 18 | 19 | type basicLatin4xTag struct { 20 | V string `json:"ABCDEFGHIJKLMO"` 21 | } 22 | 23 | type basicLatin5xTag struct { 24 | V string `json:"PQRSTUVWXYZ_"` 25 | } 26 | 27 | type basicLatin6xTag struct { 28 | V string `json:"abcdefghijklmno"` 29 | } 30 | 31 | type basicLatin7xTag struct { 32 | V string `json:"pqrstuvwxyz"` 33 | } 34 | 35 | type miscPlaneTag struct { 36 | V string `json:"色は匂へど"` 37 | } 38 | 39 | type percentSlashTag struct { 40 | V string `json:"text/html%"` // https://golang.org/issue/2718 41 | } 42 | 43 | type punctuationTag struct { 44 | V string `json:"!#$%&()*+-./:<=>?@[]^_{|}~"` // https://golang.org/issue/3546 45 | } 46 | 47 | type emptyTag struct { 48 | W string 49 | } 50 | 51 | type misnamedTag struct { 52 | X string `jsom:"Misnamed"` 53 | } 54 | 55 | type badFormatTag struct { 56 | Y string `:"BadFormat"` 57 | } 58 | 59 | type badCodeTag struct { 60 | Z string `json:" !\"#&'()*+,."` 61 | } 62 | 63 | type spaceTag struct { 64 | Q string `json:"With space"` 65 | } 66 | 67 | type unicodeTag struct { 68 | W string `json:"Ελλάδα"` 69 | } 70 | 71 | var structTagObjectKeyTests = []struct { 72 | raw interface{} 73 | value string 74 | key string 75 | }{ 76 | {basicLatin2xTag{"2x"}, "2x", "$%-/"}, 77 | {basicLatin3xTag{"3x"}, "3x", "0123456789"}, 78 | {basicLatin4xTag{"4x"}, "4x", "ABCDEFGHIJKLMO"}, 79 | {basicLatin5xTag{"5x"}, "5x", "PQRSTUVWXYZ_"}, 80 | {basicLatin6xTag{"6x"}, "6x", "abcdefghijklmno"}, 81 | {basicLatin7xTag{"7x"}, "7x", "pqrstuvwxyz"}, 82 | {miscPlaneTag{"いろはにほへと"}, "いろはにほへと", "色は匂へど"}, 83 | {emptyTag{"Pour Moi"}, "Pour Moi", "W"}, 84 | {misnamedTag{"Animal Kingdom"}, "Animal Kingdom", "X"}, 85 | {badFormatTag{"Orfevre"}, "Orfevre", "Y"}, 86 | {badCodeTag{"Reliable Man"}, "Reliable Man", "Z"}, 87 | {percentSlashTag{"brut"}, "brut", "text/html%"}, 88 | {punctuationTag{"Union Rags"}, "Union Rags", "!#$%&()*+-./:<=>?@[]^_{|}~"}, 89 | {spaceTag{"Perreddu"}, "Perreddu", "With space"}, 90 | {unicodeTag{"Loukanikos"}, "Loukanikos", "Ελλάδα"}, 91 | } 92 | 93 | func TestStructTagObjectKey(t *testing.T) { 94 | for _, tt := range structTagObjectKeyTests { 95 | b, err := Marshal(tt.raw) 96 | if err != nil { 97 | t.Fatalf("Marshal(%#q) failed: %v", tt.raw, err) 98 | } 99 | var f interface{} 100 | err = Unmarshal(b, &f) 101 | if err != nil { 102 | t.Fatalf("Unmarshal(%#q) failed: %v", b, err) 103 | } 104 | for i, v := range f.(map[string]interface{}) { 105 | switch i { 106 | case tt.key: 107 | if s, ok := v.(string); !ok || s != tt.value { 108 | t.Fatalf("Unexpected value: %#q, want %v", s, tt.value) 109 | } 110 | default: 111 | t.Fatalf("Unexpected key: %#q, from %#q", i, b) 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/tags.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 json 6 | 7 | import ( 8 | "strings" 9 | ) 10 | 11 | // tagOptions is the string following a comma in a struct field's "json" 12 | // tag, or the empty string. It does not include the leading comma. 13 | type tagOptions string 14 | 15 | // parseTag splits a struct field's json tag into its name and 16 | // comma-separated options. 17 | func parseTag(tag string) (string, tagOptions) { 18 | if idx := strings.Index(tag, ","); idx != -1 { 19 | return tag[:idx], tagOptions(tag[idx+1:]) 20 | } 21 | return tag, tagOptions("") 22 | } 23 | 24 | // Contains reports whether a comma-separated list of options 25 | // contains a particular substr flag. substr must be surrounded by a 26 | // string boundary or commas. 27 | func (o tagOptions) Contains(optionName string) bool { 28 | if len(o) == 0 { 29 | return false 30 | } 31 | s := string(o) 32 | for s != "" { 33 | var next string 34 | i := strings.Index(s, ",") 35 | if i >= 0 { 36 | s, next = s[:i], s[i+1:] 37 | } 38 | if s == optionName { 39 | return true 40 | } 41 | s = next 42 | } 43 | return false 44 | } 45 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/tags_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 json 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | func TestTagParsing(t *testing.T) { 12 | name, opts := parseTag("field,foobar,foo") 13 | if name != "field" { 14 | t.Fatalf("name = %q, want field", name) 15 | } 16 | for _, tt := range []struct { 17 | opt string 18 | want bool 19 | }{ 20 | {"foobar", true}, 21 | {"foo", true}, 22 | {"bar", false}, 23 | } { 24 | if opts.Contains(tt.opt) != tt.want { 25 | t.Errorf("Contains(%q) = %v", tt.opt, !tt.want) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/json/testdata/code.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/internal/json/testdata/code.json.gz -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/sasl/sasl.c: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static int mgo_sasl_simple(void *context, int id, const char **result, unsigned int *len) 9 | { 10 | if (!result) { 11 | return SASL_BADPARAM; 12 | } 13 | switch (id) { 14 | case SASL_CB_USER: 15 | *result = (char *)context; 16 | break; 17 | case SASL_CB_AUTHNAME: 18 | *result = (char *)context; 19 | break; 20 | case SASL_CB_LANGUAGE: 21 | *result = NULL; 22 | break; 23 | default: 24 | return SASL_BADPARAM; 25 | } 26 | if (len) { 27 | *len = *result ? strlen(*result) : 0; 28 | } 29 | return SASL_OK; 30 | } 31 | 32 | typedef int (*callback)(void); 33 | 34 | static int mgo_sasl_secret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **result) 35 | { 36 | if (!conn || !result || id != SASL_CB_PASS) { 37 | return SASL_BADPARAM; 38 | } 39 | *result = (sasl_secret_t *)context; 40 | return SASL_OK; 41 | } 42 | 43 | sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password) 44 | { 45 | sasl_callback_t *cb = malloc(4 * sizeof(sasl_callback_t)); 46 | int n = 0; 47 | 48 | size_t len = strlen(password); 49 | sasl_secret_t *secret = (sasl_secret_t*)malloc(sizeof(sasl_secret_t) + len); 50 | if (!secret) { 51 | free(cb); 52 | return NULL; 53 | } 54 | strcpy((char *)secret->data, password); 55 | secret->len = len; 56 | 57 | cb[n].id = SASL_CB_PASS; 58 | cb[n].proc = (callback)&mgo_sasl_secret; 59 | cb[n].context = secret; 60 | n++; 61 | 62 | cb[n].id = SASL_CB_USER; 63 | cb[n].proc = (callback)&mgo_sasl_simple; 64 | cb[n].context = (char*)username; 65 | n++; 66 | 67 | cb[n].id = SASL_CB_AUTHNAME; 68 | cb[n].proc = (callback)&mgo_sasl_simple; 69 | cb[n].context = (char*)username; 70 | n++; 71 | 72 | cb[n].id = SASL_CB_LIST_END; 73 | cb[n].proc = NULL; 74 | cb[n].context = NULL; 75 | 76 | return cb; 77 | } 78 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/sasl/sasl.go: -------------------------------------------------------------------------------- 1 | // Package sasl is an implementation detail of the mgo package. 2 | // 3 | // This package is not meant to be used by itself. 4 | // 5 | 6 | // +build !windows 7 | 8 | package sasl 9 | 10 | // #cgo LDFLAGS: -lsasl2 11 | // 12 | // struct sasl_conn {}; 13 | // 14 | // #include 15 | // #include 16 | // 17 | // sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password); 18 | // 19 | import "C" 20 | 21 | import ( 22 | "fmt" 23 | "strings" 24 | "sync" 25 | "unsafe" 26 | ) 27 | 28 | type saslStepper interface { 29 | Step(serverData []byte) (clientData []byte, done bool, err error) 30 | Close() 31 | } 32 | 33 | type saslSession struct { 34 | conn *C.sasl_conn_t 35 | step int 36 | mech string 37 | 38 | cstrings []*C.char 39 | callbacks *C.sasl_callback_t 40 | } 41 | 42 | var initError error 43 | var initOnce sync.Once 44 | 45 | func initSASL() { 46 | rc := C.sasl_client_init(nil) 47 | if rc != C.SASL_OK { 48 | initError = saslError(rc, nil, "cannot initialize SASL library") 49 | } 50 | } 51 | 52 | func New(username, password, mechanism, service, host string) (saslStepper, error) { 53 | initOnce.Do(initSASL) 54 | if initError != nil { 55 | return nil, initError 56 | } 57 | 58 | ss := &saslSession{mech: mechanism} 59 | if service == "" { 60 | service = "mongodb" 61 | } 62 | if i := strings.Index(host, ":"); i >= 0 { 63 | host = host[:i] 64 | } 65 | ss.callbacks = C.mgo_sasl_callbacks(ss.cstr(username), ss.cstr(password)) 66 | rc := C.sasl_client_new(ss.cstr(service), ss.cstr(host), nil, nil, ss.callbacks, 0, &ss.conn) 67 | if rc != C.SASL_OK { 68 | ss.Close() 69 | return nil, saslError(rc, nil, "cannot create new SASL client") 70 | } 71 | return ss, nil 72 | } 73 | 74 | func (ss *saslSession) cstr(s string) *C.char { 75 | cstr := C.CString(s) 76 | ss.cstrings = append(ss.cstrings, cstr) 77 | return cstr 78 | } 79 | 80 | func (ss *saslSession) Close() { 81 | for _, cstr := range ss.cstrings { 82 | C.free(unsafe.Pointer(cstr)) 83 | } 84 | ss.cstrings = nil 85 | 86 | if ss.callbacks != nil { 87 | C.free(unsafe.Pointer(ss.callbacks)) 88 | } 89 | 90 | // The documentation of SASL dispose makes it clear that this should only 91 | // be done when the connection is done, not when the authentication phase 92 | // is done, because an encryption layer may have been negotiated. 93 | // Even then, we'll do this for now, because it's simpler and prevents 94 | // keeping track of this state for every socket. If it breaks, we'll fix it. 95 | C.sasl_dispose(&ss.conn) 96 | } 97 | 98 | func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) { 99 | ss.step++ 100 | if ss.step > 10 { 101 | return nil, false, fmt.Errorf("too many SASL steps without authentication") 102 | } 103 | var cclientData *C.char 104 | var cclientDataLen C.uint 105 | var rc C.int 106 | if ss.step == 1 { 107 | var mechanism *C.char // ignored - must match cred 108 | rc = C.sasl_client_start(ss.conn, ss.cstr(ss.mech), nil, &cclientData, &cclientDataLen, &mechanism) 109 | } else { 110 | var cserverData *C.char 111 | var cserverDataLen C.uint 112 | if len(serverData) > 0 { 113 | cserverData = (*C.char)(unsafe.Pointer(&serverData[0])) 114 | cserverDataLen = C.uint(len(serverData)) 115 | } 116 | rc = C.sasl_client_step(ss.conn, cserverData, cserverDataLen, nil, &cclientData, &cclientDataLen) 117 | } 118 | if cclientData != nil && cclientDataLen > 0 { 119 | clientData = C.GoBytes(unsafe.Pointer(cclientData), C.int(cclientDataLen)) 120 | } 121 | if rc == C.SASL_OK { 122 | return clientData, true, nil 123 | } 124 | if rc == C.SASL_CONTINUE { 125 | return clientData, false, nil 126 | } 127 | return nil, false, saslError(rc, ss.conn, "cannot establish SASL session") 128 | } 129 | 130 | func saslError(rc C.int, conn *C.sasl_conn_t, msg string) error { 131 | var detail string 132 | if conn == nil { 133 | detail = C.GoString(C.sasl_errstring(rc, nil, nil)) 134 | } else { 135 | detail = C.GoString(C.sasl_errdetail(conn)) 136 | } 137 | return fmt.Errorf(msg + ": " + detail) 138 | } 139 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.c: -------------------------------------------------------------------------------- 1 | #include "sasl_windows.h" 2 | 3 | static const LPSTR SSPI_PACKAGE_NAME = "kerberos"; 4 | 5 | SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle *cred_handle, char *username, char *password, char *domain) 6 | { 7 | SEC_WINNT_AUTH_IDENTITY auth_identity; 8 | SECURITY_INTEGER ignored; 9 | 10 | auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; 11 | auth_identity.User = (LPSTR) username; 12 | auth_identity.UserLength = strlen(username); 13 | auth_identity.Password = NULL; 14 | auth_identity.PasswordLength = 0; 15 | if(password){ 16 | auth_identity.Password = (LPSTR) password; 17 | auth_identity.PasswordLength = strlen(password); 18 | } 19 | auth_identity.Domain = (LPSTR) domain; 20 | auth_identity.DomainLength = strlen(domain); 21 | return call_sspi_acquire_credentials_handle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_identity, NULL, NULL, cred_handle, &ignored); 22 | } 23 | 24 | int sspi_step(CredHandle *cred_handle, int has_context, CtxtHandle *context, PVOID buffer, ULONG buffer_length, PVOID *out_buffer, ULONG *out_buffer_length, char *target) 25 | { 26 | SecBufferDesc inbuf; 27 | SecBuffer in_bufs[1]; 28 | SecBufferDesc outbuf; 29 | SecBuffer out_bufs[1]; 30 | 31 | if (has_context > 0) { 32 | // If we already have a context, we now have data to send. 33 | // Put this data in an inbuf. 34 | inbuf.ulVersion = SECBUFFER_VERSION; 35 | inbuf.cBuffers = 1; 36 | inbuf.pBuffers = in_bufs; 37 | in_bufs[0].pvBuffer = buffer; 38 | in_bufs[0].cbBuffer = buffer_length; 39 | in_bufs[0].BufferType = SECBUFFER_TOKEN; 40 | } 41 | 42 | outbuf.ulVersion = SECBUFFER_VERSION; 43 | outbuf.cBuffers = 1; 44 | outbuf.pBuffers = out_bufs; 45 | out_bufs[0].pvBuffer = NULL; 46 | out_bufs[0].cbBuffer = 0; 47 | out_bufs[0].BufferType = SECBUFFER_TOKEN; 48 | 49 | ULONG context_attr = 0; 50 | 51 | int ret = call_sspi_initialize_security_context(cred_handle, 52 | has_context > 0 ? context : NULL, 53 | (LPSTR) target, 54 | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_MUTUAL_AUTH, 55 | 0, 56 | SECURITY_NETWORK_DREP, 57 | has_context > 0 ? &inbuf : NULL, 58 | 0, 59 | context, 60 | &outbuf, 61 | &context_attr, 62 | NULL); 63 | 64 | *out_buffer = malloc(out_bufs[0].cbBuffer); 65 | *out_buffer_length = out_bufs[0].cbBuffer; 66 | memcpy(*out_buffer, out_bufs[0].pvBuffer, *out_buffer_length); 67 | 68 | return ret; 69 | } 70 | 71 | int sspi_send_client_authz_id(CtxtHandle *context, PVOID *buffer, ULONG *buffer_length, char *user_plus_realm) 72 | { 73 | SecPkgContext_Sizes sizes; 74 | SECURITY_STATUS status = call_sspi_query_context_attributes(context, SECPKG_ATTR_SIZES, &sizes); 75 | 76 | if (status != SEC_E_OK) { 77 | return status; 78 | } 79 | 80 | size_t user_plus_realm_length = strlen(user_plus_realm); 81 | int msgSize = 4 + user_plus_realm_length; 82 | char *msg = malloc((sizes.cbSecurityTrailer + msgSize + sizes.cbBlockSize) * sizeof(char)); 83 | msg[sizes.cbSecurityTrailer + 0] = 1; 84 | msg[sizes.cbSecurityTrailer + 1] = 0; 85 | msg[sizes.cbSecurityTrailer + 2] = 0; 86 | msg[sizes.cbSecurityTrailer + 3] = 0; 87 | memcpy(&msg[sizes.cbSecurityTrailer + 4], user_plus_realm, user_plus_realm_length); 88 | 89 | SecBuffer wrapBufs[3]; 90 | SecBufferDesc wrapBufDesc; 91 | wrapBufDesc.cBuffers = 3; 92 | wrapBufDesc.pBuffers = wrapBufs; 93 | wrapBufDesc.ulVersion = SECBUFFER_VERSION; 94 | 95 | wrapBufs[0].cbBuffer = sizes.cbSecurityTrailer; 96 | wrapBufs[0].BufferType = SECBUFFER_TOKEN; 97 | wrapBufs[0].pvBuffer = msg; 98 | 99 | wrapBufs[1].cbBuffer = msgSize; 100 | wrapBufs[1].BufferType = SECBUFFER_DATA; 101 | wrapBufs[1].pvBuffer = msg + sizes.cbSecurityTrailer; 102 | 103 | wrapBufs[2].cbBuffer = sizes.cbBlockSize; 104 | wrapBufs[2].BufferType = SECBUFFER_PADDING; 105 | wrapBufs[2].pvBuffer = msg + sizes.cbSecurityTrailer + msgSize; 106 | 107 | status = call_sspi_encrypt_message(context, SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0); 108 | if (status != SEC_E_OK) { 109 | free(msg); 110 | return status; 111 | } 112 | 113 | *buffer_length = wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer; 114 | *buffer = malloc(*buffer_length); 115 | 116 | memcpy(*buffer, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer); 117 | memcpy(*buffer + wrapBufs[0].cbBuffer, wrapBufs[1].pvBuffer, wrapBufs[1].cbBuffer); 118 | memcpy(*buffer + wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer, wrapBufs[2].pvBuffer, wrapBufs[2].cbBuffer); 119 | 120 | free(msg); 121 | return SEC_E_OK; 122 | } 123 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.go: -------------------------------------------------------------------------------- 1 | package sasl 2 | 3 | // #include "sasl_windows.h" 4 | import "C" 5 | 6 | import ( 7 | "fmt" 8 | "strings" 9 | "sync" 10 | "unsafe" 11 | ) 12 | 13 | type saslStepper interface { 14 | Step(serverData []byte) (clientData []byte, done bool, err error) 15 | Close() 16 | } 17 | 18 | type saslSession struct { 19 | // Credentials 20 | mech string 21 | service string 22 | host string 23 | userPlusRealm string 24 | target string 25 | domain string 26 | 27 | // Internal state 28 | authComplete bool 29 | errored bool 30 | step int 31 | 32 | // C internal state 33 | credHandle C.CredHandle 34 | context C.CtxtHandle 35 | hasContext C.int 36 | 37 | // Keep track of pointers we need to explicitly free 38 | stringsToFree []*C.char 39 | } 40 | 41 | var initError error 42 | var initOnce sync.Once 43 | 44 | func initSSPI() { 45 | rc := C.load_secur32_dll() 46 | if rc != 0 { 47 | initError = fmt.Errorf("Error loading libraries: %v", rc) 48 | } 49 | } 50 | 51 | func New(username, password, mechanism, service, host string) (saslStepper, error) { 52 | initOnce.Do(initSSPI) 53 | ss := &saslSession{mech: mechanism, hasContext: 0, userPlusRealm: username} 54 | if service == "" { 55 | service = "mongodb" 56 | } 57 | if i := strings.Index(host, ":"); i >= 0 { 58 | host = host[:i] 59 | } 60 | ss.service = service 61 | ss.host = host 62 | 63 | usernameComponents := strings.Split(username, "@") 64 | if len(usernameComponents) < 2 { 65 | return nil, fmt.Errorf("Username '%v' doesn't contain a realm!", username) 66 | } 67 | user := usernameComponents[0] 68 | ss.domain = usernameComponents[1] 69 | ss.target = fmt.Sprintf("%s/%s", ss.service, ss.host) 70 | 71 | var status C.SECURITY_STATUS 72 | // Step 0: call AcquireCredentialsHandle to get a nice SSPI CredHandle 73 | if len(password) > 0 { 74 | status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), ss.cstr(password), ss.cstr(ss.domain)) 75 | } else { 76 | status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), nil, ss.cstr(ss.domain)) 77 | } 78 | if status != C.SEC_E_OK { 79 | ss.errored = true 80 | return nil, fmt.Errorf("Couldn't create new SSPI client, error code %v", status) 81 | } 82 | return ss, nil 83 | } 84 | 85 | func (ss *saslSession) cstr(s string) *C.char { 86 | cstr := C.CString(s) 87 | ss.stringsToFree = append(ss.stringsToFree, cstr) 88 | return cstr 89 | } 90 | 91 | func (ss *saslSession) Close() { 92 | for _, cstr := range ss.stringsToFree { 93 | C.free(unsafe.Pointer(cstr)) 94 | } 95 | } 96 | 97 | func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) { 98 | ss.step++ 99 | if ss.step > 10 { 100 | return nil, false, fmt.Errorf("too many SSPI steps without authentication") 101 | } 102 | var buffer C.PVOID 103 | var bufferLength C.ULONG 104 | var outBuffer C.PVOID 105 | var outBufferLength C.ULONG 106 | if len(serverData) > 0 { 107 | buffer = (C.PVOID)(unsafe.Pointer(&serverData[0])) 108 | bufferLength = C.ULONG(len(serverData)) 109 | } 110 | var status C.int 111 | if ss.authComplete { 112 | // Step 3: last bit of magic to use the correct server credentials 113 | status = C.sspi_send_client_authz_id(&ss.context, &outBuffer, &outBufferLength, ss.cstr(ss.userPlusRealm)) 114 | } else { 115 | // Step 1 + Step 2: set up security context with the server and TGT 116 | status = C.sspi_step(&ss.credHandle, ss.hasContext, &ss.context, buffer, bufferLength, &outBuffer, &outBufferLength, ss.cstr(ss.target)) 117 | } 118 | if outBuffer != C.PVOID(nil) { 119 | defer C.free(unsafe.Pointer(outBuffer)) 120 | } 121 | if status != C.SEC_E_OK && status != C.SEC_I_CONTINUE_NEEDED { 122 | ss.errored = true 123 | return nil, false, ss.handleSSPIErrorCode(status) 124 | } 125 | 126 | clientData = C.GoBytes(unsafe.Pointer(outBuffer), C.int(outBufferLength)) 127 | if status == C.SEC_E_OK { 128 | ss.authComplete = true 129 | return clientData, true, nil 130 | } else { 131 | ss.hasContext = 1 132 | return clientData, false, nil 133 | } 134 | } 135 | 136 | func (ss *saslSession) handleSSPIErrorCode(code C.int) error { 137 | switch { 138 | case code == C.SEC_E_TARGET_UNKNOWN: 139 | return fmt.Errorf("Target %v@%v not found", ss.target, ss.domain) 140 | } 141 | return fmt.Errorf("Unknown error doing step %v, error code %v", ss.step, code) 142 | } 143 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "sspi_windows.h" 4 | 5 | SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle* cred_handle, char* username, char* password, char* domain); 6 | int sspi_step(CredHandle* cred_handle, int has_context, CtxtHandle* context, PVOID buffer, ULONG buffer_length, PVOID* out_buffer, ULONG* out_buffer_length, char* target); 7 | int sspi_send_client_authz_id(CtxtHandle* context, PVOID* buffer, ULONG* buffer_length, char* user_plus_realm); 8 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/sasl/sspi_windows.c: -------------------------------------------------------------------------------- 1 | // Code adapted from the NodeJS kerberos library: 2 | // 3 | // https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.c 4 | // 5 | // Under the terms of the Apache License, Version 2.0: 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | #include 10 | 11 | #include "sspi_windows.h" 12 | 13 | static HINSTANCE sspi_secur32_dll = NULL; 14 | 15 | int load_secur32_dll() 16 | { 17 | sspi_secur32_dll = LoadLibrary("secur32.dll"); 18 | if (sspi_secur32_dll == NULL) { 19 | return GetLastError(); 20 | } 21 | return 0; 22 | } 23 | 24 | SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo) 25 | { 26 | if (sspi_secur32_dll == NULL) { 27 | return -1; 28 | } 29 | encryptMessage_fn pfn_encryptMessage = (encryptMessage_fn) GetProcAddress(sspi_secur32_dll, "EncryptMessage"); 30 | if (!pfn_encryptMessage) { 31 | return -2; 32 | } 33 | return (*pfn_encryptMessage)(phContext, fQOP, pMessage, MessageSeqNo); 34 | } 35 | 36 | SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle( 37 | LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, 38 | void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, 39 | PCredHandle phCredential, PTimeStamp ptsExpiry) 40 | { 41 | if (sspi_secur32_dll == NULL) { 42 | return -1; 43 | } 44 | acquireCredentialsHandle_fn pfn_acquireCredentialsHandle; 45 | #ifdef _UNICODE 46 | pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleW"); 47 | #else 48 | pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleA"); 49 | #endif 50 | if (!pfn_acquireCredentialsHandle) { 51 | return -2; 52 | } 53 | return (*pfn_acquireCredentialsHandle)( 54 | pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData, 55 | pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); 56 | } 57 | 58 | SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context( 59 | PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, 60 | unsigned long fContextReq, unsigned long Reserved1, unsigned long TargetDataRep, 61 | PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext, 62 | PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry) 63 | { 64 | if (sspi_secur32_dll == NULL) { 65 | return -1; 66 | } 67 | initializeSecurityContext_fn pfn_initializeSecurityContext; 68 | #ifdef _UNICODE 69 | pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextW"); 70 | #else 71 | pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextA"); 72 | #endif 73 | if (!pfn_initializeSecurityContext) { 74 | return -2; 75 | } 76 | return (*pfn_initializeSecurityContext)( 77 | phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, 78 | pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); 79 | } 80 | 81 | SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes(PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer) 82 | { 83 | if (sspi_secur32_dll == NULL) { 84 | return -1; 85 | } 86 | queryContextAttributes_fn pfn_queryContextAttributes; 87 | #ifdef _UNICODE 88 | pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesW"); 89 | #else 90 | pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesA"); 91 | #endif 92 | if (!pfn_queryContextAttributes) { 93 | return -2; 94 | } 95 | return (*pfn_queryContextAttributes)(phContext, ulAttribute, pBuffer); 96 | } 97 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/sasl/sspi_windows.h: -------------------------------------------------------------------------------- 1 | // Code adapted from the NodeJS kerberos library: 2 | // 3 | // https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.h 4 | // 5 | // Under the terms of the Apache License, Version 2.0: 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | #ifndef SSPI_WINDOWS_H 10 | #define SSPI_WINDOWS_H 11 | 12 | #define SECURITY_WIN32 1 13 | 14 | #include 15 | #include 16 | 17 | int load_secur32_dll(); 18 | 19 | SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo); 20 | 21 | typedef DWORD (WINAPI *encryptMessage_fn)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo); 22 | 23 | SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle( 24 | LPSTR pszPrincipal, // Name of principal 25 | LPSTR pszPackage, // Name of package 26 | unsigned long fCredentialUse, // Flags indicating use 27 | void *pvLogonId, // Pointer to logon ID 28 | void *pAuthData, // Package specific data 29 | SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func 30 | void *pvGetKeyArgument, // Value to pass to GetKey() 31 | PCredHandle phCredential, // (out) Cred Handle 32 | PTimeStamp ptsExpiry // (out) Lifetime (optional) 33 | ); 34 | 35 | typedef DWORD (WINAPI *acquireCredentialsHandle_fn)( 36 | LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, 37 | void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, 38 | PCredHandle phCredential, PTimeStamp ptsExpiry 39 | ); 40 | 41 | SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context( 42 | PCredHandle phCredential, // Cred to base context 43 | PCtxtHandle phContext, // Existing context (OPT) 44 | LPSTR pszTargetName, // Name of target 45 | unsigned long fContextReq, // Context Requirements 46 | unsigned long Reserved1, // Reserved, MBZ 47 | unsigned long TargetDataRep, // Data rep of target 48 | PSecBufferDesc pInput, // Input Buffers 49 | unsigned long Reserved2, // Reserved, MBZ 50 | PCtxtHandle phNewContext, // (out) New Context handle 51 | PSecBufferDesc pOutput, // (inout) Output Buffers 52 | unsigned long *pfContextAttr, // (out) Context attrs 53 | PTimeStamp ptsExpiry // (out) Life span (OPT) 54 | ); 55 | 56 | typedef DWORD (WINAPI *initializeSecurityContext_fn)( 57 | PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, unsigned long fContextReq, 58 | unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, 59 | PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry); 60 | 61 | SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes( 62 | PCtxtHandle phContext, // Context to query 63 | unsigned long ulAttribute, // Attribute to query 64 | void *pBuffer // Buffer for attributes 65 | ); 66 | 67 | typedef DWORD (WINAPI *queryContextAttributes_fn)( 68 | PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer); 69 | 70 | #endif // SSPI_WINDOWS_H 71 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/internal/scram/scram_test.go: -------------------------------------------------------------------------------- 1 | package scram_test 2 | 3 | import ( 4 | "crypto/sha1" 5 | "testing" 6 | 7 | . "gopkg.in/check.v1" 8 | "gopkg.in/mgo.v2/internal/scram" 9 | "strings" 10 | ) 11 | 12 | var _ = Suite(&S{}) 13 | 14 | func Test(t *testing.T) { TestingT(t) } 15 | 16 | type S struct{} 17 | 18 | var tests = [][]string{{ 19 | "U: user pencil", 20 | "N: fyko+d2lbbFgONRv9qkxdawL", 21 | "C: n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL", 22 | "S: r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096", 23 | "C: c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=", 24 | "S: v=rmF9pqV8S7suAoZWja4dJRkFsKQ=", 25 | }, { 26 | "U: root fe8c89e308ec08763df36333cbf5d3a2", 27 | "N: OTcxNDk5NjM2MzE5", 28 | "C: n,,n=root,r=OTcxNDk5NjM2MzE5", 29 | "S: r=OTcxNDk5NjM2MzE581Ra3provgG0iDsMkDiIAlrh4532dDLp,s=XRDkVrFC9JuL7/F4tG0acQ==,i=10000", 30 | "C: c=biws,r=OTcxNDk5NjM2MzE581Ra3provgG0iDsMkDiIAlrh4532dDLp,p=6y1jp9R7ETyouTXS9fW9k5UHdBc=", 31 | "S: v=LBnd9dUJRxdqZiEq91NKP3z/bHA=", 32 | }} 33 | 34 | func (s *S) TestExamples(c *C) { 35 | for _, steps := range tests { 36 | if len(steps) < 2 || len(steps[0]) < 3 || !strings.HasPrefix(steps[0], "U: ") { 37 | c.Fatalf("Invalid test: %#v", steps) 38 | } 39 | auth := strings.Fields(steps[0][3:]) 40 | client := scram.NewClient(sha1.New, auth[0], auth[1]) 41 | first, done := true, false 42 | c.Logf("-----") 43 | c.Logf("%s", steps[0]) 44 | for _, step := range steps[1:] { 45 | c.Logf("%s", step) 46 | switch step[:3] { 47 | case "N: ": 48 | client.SetNonce([]byte(step[3:])) 49 | case "C: ": 50 | if first { 51 | first = false 52 | done = client.Step(nil) 53 | } 54 | c.Assert(done, Equals, false) 55 | c.Assert(client.Err(), IsNil) 56 | c.Assert(string(client.Out()), Equals, step[3:]) 57 | case "S: ": 58 | first = false 59 | done = client.Step([]byte(step[3:])) 60 | default: 61 | panic("invalid test line: " + step) 62 | } 63 | } 64 | c.Assert(done, Equals, true) 65 | c.Assert(client.Err(), IsNil) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/log.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver 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 | 27 | package mgo 28 | 29 | import ( 30 | "fmt" 31 | "sync" 32 | ) 33 | 34 | // --------------------------------------------------------------------------- 35 | // Logging integration. 36 | 37 | // Avoid importing the log type information unnecessarily. There's a small cost 38 | // associated with using an interface rather than the type. Depending on how 39 | // often the logger is plugged in, it would be worth using the type instead. 40 | type log_Logger interface { 41 | Output(calldepth int, s string) error 42 | } 43 | 44 | var ( 45 | globalLogger log_Logger 46 | globalDebug bool 47 | globalMutex sync.Mutex 48 | ) 49 | 50 | // RACE WARNING: There are known data races when logging, which are manually 51 | // silenced when the race detector is in use. These data races won't be 52 | // observed in typical use, because logging is supposed to be set up once when 53 | // the application starts. Having raceDetector as a constant, the compiler 54 | // should elide the locks altogether in actual use. 55 | 56 | // Specify the *log.Logger object where log messages should be sent to. 57 | func SetLogger(logger log_Logger) { 58 | if raceDetector { 59 | globalMutex.Lock() 60 | defer globalMutex.Unlock() 61 | } 62 | globalLogger = logger 63 | } 64 | 65 | // Enable the delivery of debug messages to the logger. Only meaningful 66 | // if a logger is also set. 67 | func SetDebug(debug bool) { 68 | if raceDetector { 69 | globalMutex.Lock() 70 | defer globalMutex.Unlock() 71 | } 72 | globalDebug = debug 73 | } 74 | 75 | func log(v ...interface{}) { 76 | if raceDetector { 77 | globalMutex.Lock() 78 | defer globalMutex.Unlock() 79 | } 80 | if globalLogger != nil { 81 | globalLogger.Output(2, fmt.Sprint(v...)) 82 | } 83 | } 84 | 85 | func logln(v ...interface{}) { 86 | if raceDetector { 87 | globalMutex.Lock() 88 | defer globalMutex.Unlock() 89 | } 90 | if globalLogger != nil { 91 | globalLogger.Output(2, fmt.Sprintln(v...)) 92 | } 93 | } 94 | 95 | func logf(format string, v ...interface{}) { 96 | if raceDetector { 97 | globalMutex.Lock() 98 | defer globalMutex.Unlock() 99 | } 100 | if globalLogger != nil { 101 | globalLogger.Output(2, fmt.Sprintf(format, v...)) 102 | } 103 | } 104 | 105 | func debug(v ...interface{}) { 106 | if raceDetector { 107 | globalMutex.Lock() 108 | defer globalMutex.Unlock() 109 | } 110 | if globalDebug && globalLogger != nil { 111 | globalLogger.Output(2, fmt.Sprint(v...)) 112 | } 113 | } 114 | 115 | func debugln(v ...interface{}) { 116 | if raceDetector { 117 | globalMutex.Lock() 118 | defer globalMutex.Unlock() 119 | } 120 | if globalDebug && globalLogger != nil { 121 | globalLogger.Output(2, fmt.Sprintln(v...)) 122 | } 123 | } 124 | 125 | func debugf(format string, v ...interface{}) { 126 | if raceDetector { 127 | globalMutex.Lock() 128 | defer globalMutex.Unlock() 129 | } 130 | if globalDebug && globalLogger != nil { 131 | globalLogger.Output(2, fmt.Sprintf(format, v...)) 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/queue.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver 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 | 27 | package mgo 28 | 29 | type queue struct { 30 | elems []interface{} 31 | nelems, popi, pushi int 32 | } 33 | 34 | func (q *queue) Len() int { 35 | return q.nelems 36 | } 37 | 38 | func (q *queue) Push(elem interface{}) { 39 | //debugf("Pushing(pushi=%d popi=%d cap=%d): %#v\n", 40 | // q.pushi, q.popi, len(q.elems), elem) 41 | if q.nelems == len(q.elems) { 42 | q.expand() 43 | } 44 | q.elems[q.pushi] = elem 45 | q.nelems++ 46 | q.pushi = (q.pushi + 1) % len(q.elems) 47 | //debugf(" Pushed(pushi=%d popi=%d cap=%d): %#v\n", 48 | // q.pushi, q.popi, len(q.elems), elem) 49 | } 50 | 51 | func (q *queue) Pop() (elem interface{}) { 52 | //debugf("Popping(pushi=%d popi=%d cap=%d)\n", 53 | // q.pushi, q.popi, len(q.elems)) 54 | if q.nelems == 0 { 55 | return nil 56 | } 57 | elem = q.elems[q.popi] 58 | q.elems[q.popi] = nil // Help GC. 59 | q.nelems-- 60 | q.popi = (q.popi + 1) % len(q.elems) 61 | //debugf(" Popped(pushi=%d popi=%d cap=%d): %#v\n", 62 | // q.pushi, q.popi, len(q.elems), elem) 63 | return elem 64 | } 65 | 66 | func (q *queue) expand() { 67 | curcap := len(q.elems) 68 | var newcap int 69 | if curcap == 0 { 70 | newcap = 8 71 | } else if curcap < 1024 { 72 | newcap = curcap * 2 73 | } else { 74 | newcap = curcap + (curcap / 4) 75 | } 76 | elems := make([]interface{}, newcap) 77 | 78 | if q.popi == 0 { 79 | copy(elems, q.elems) 80 | q.pushi = curcap 81 | } else { 82 | newpopi := newcap - (curcap - q.popi) 83 | copy(elems, q.elems[:q.popi]) 84 | copy(elems[newpopi:], q.elems[q.popi:]) 85 | q.popi = newpopi 86 | } 87 | for i := range q.elems { 88 | q.elems[i] = nil // Help GC. 89 | } 90 | q.elems = elems 91 | } 92 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/queue_test.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver 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 | 27 | package mgo 28 | 29 | import ( 30 | . "gopkg.in/check.v1" 31 | ) 32 | 33 | type QS struct{} 34 | 35 | var _ = Suite(&QS{}) 36 | 37 | func (s *QS) TestSequentialGrowth(c *C) { 38 | q := queue{} 39 | n := 2048 40 | for i := 0; i != n; i++ { 41 | q.Push(i) 42 | } 43 | for i := 0; i != n; i++ { 44 | c.Assert(q.Pop(), Equals, i) 45 | } 46 | } 47 | 48 | var queueTestLists = [][]int{ 49 | // {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 50 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 51 | 52 | // {8, 9, 10, 11, ... 2, 3, 4, 5, 6, 7} 53 | {0, 1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, 10, 11}, 54 | 55 | // {8, 9, 10, 11, ... 2, 3, 4, 5, 6, 7} 56 | {0, 1, 2, 3, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11}, 57 | 58 | // {0, 1, 2, 3, 4, 5, 6, 7, 8} 59 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 60 | -1, -1, -1, -1, -1, -1, -1, -1, -1, 61 | 0, 1, 2, 3, 4, 5, 6, 7, 8}, 62 | } 63 | 64 | func (s *QS) TestQueueTestLists(c *C) { 65 | test := []int{} 66 | testi := 0 67 | reset := func() { 68 | test = test[0:0] 69 | testi = 0 70 | } 71 | push := func(i int) { 72 | test = append(test, i) 73 | } 74 | pop := func() (i int) { 75 | if testi == len(test) { 76 | return -1 77 | } 78 | i = test[testi] 79 | testi++ 80 | return 81 | } 82 | 83 | for _, list := range queueTestLists { 84 | reset() 85 | q := queue{} 86 | for _, n := range list { 87 | if n == -1 { 88 | c.Assert(q.Pop(), Equals, pop(), Commentf("With list %#v", list)) 89 | } else { 90 | q.Push(n) 91 | push(n) 92 | } 93 | } 94 | 95 | for n := pop(); n != -1; n = pop() { 96 | c.Assert(q.Pop(), Equals, n, Commentf("With list %#v", list)) 97 | } 98 | 99 | c.Assert(q.Pop(), Equals, nil, Commentf("With list %#v", list)) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/raceoff.go: -------------------------------------------------------------------------------- 1 | // +build !race 2 | 3 | package mgo 4 | 5 | const raceDetector = false 6 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/raceon.go: -------------------------------------------------------------------------------- 1 | // +build race 2 | 3 | package mgo 4 | 5 | const raceDetector = true 6 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/saslimpl.go: -------------------------------------------------------------------------------- 1 | //+build sasl 2 | 3 | package mgo 4 | 5 | import ( 6 | "gopkg.in/mgo.v2/internal/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 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/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 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/stats.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver 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 | 27 | package mgo 28 | 29 | import ( 30 | "sync" 31 | ) 32 | 33 | var stats *Stats 34 | var statsMutex sync.Mutex 35 | 36 | func SetStats(enabled bool) { 37 | statsMutex.Lock() 38 | if enabled { 39 | if stats == nil { 40 | stats = &Stats{} 41 | } 42 | } else { 43 | stats = nil 44 | } 45 | statsMutex.Unlock() 46 | } 47 | 48 | func GetStats() (snapshot Stats) { 49 | statsMutex.Lock() 50 | snapshot = *stats 51 | statsMutex.Unlock() 52 | return 53 | } 54 | 55 | func ResetStats() { 56 | statsMutex.Lock() 57 | debug("Resetting stats") 58 | old := stats 59 | stats = &Stats{} 60 | // These are absolute values: 61 | stats.Clusters = old.Clusters 62 | stats.SocketsInUse = old.SocketsInUse 63 | stats.SocketsAlive = old.SocketsAlive 64 | stats.SocketRefs = old.SocketRefs 65 | statsMutex.Unlock() 66 | return 67 | } 68 | 69 | type Stats struct { 70 | Clusters int 71 | MasterConns int 72 | SlaveConns int 73 | SentOps int 74 | ReceivedOps int 75 | ReceivedDocs int 76 | SocketsAlive int 77 | SocketsInUse int 78 | SocketRefs int 79 | } 80 | 81 | func (stats *Stats) cluster(delta int) { 82 | if stats != nil { 83 | statsMutex.Lock() 84 | stats.Clusters += delta 85 | statsMutex.Unlock() 86 | } 87 | } 88 | 89 | func (stats *Stats) conn(delta int, master bool) { 90 | if stats != nil { 91 | statsMutex.Lock() 92 | if master { 93 | stats.MasterConns += delta 94 | } else { 95 | stats.SlaveConns += delta 96 | } 97 | statsMutex.Unlock() 98 | } 99 | } 100 | 101 | func (stats *Stats) sentOps(delta int) { 102 | if stats != nil { 103 | statsMutex.Lock() 104 | stats.SentOps += delta 105 | statsMutex.Unlock() 106 | } 107 | } 108 | 109 | func (stats *Stats) receivedOps(delta int) { 110 | if stats != nil { 111 | statsMutex.Lock() 112 | stats.ReceivedOps += delta 113 | statsMutex.Unlock() 114 | } 115 | } 116 | 117 | func (stats *Stats) receivedDocs(delta int) { 118 | if stats != nil { 119 | statsMutex.Lock() 120 | stats.ReceivedDocs += delta 121 | statsMutex.Unlock() 122 | } 123 | } 124 | 125 | func (stats *Stats) socketsInUse(delta int) { 126 | if stats != nil { 127 | statsMutex.Lock() 128 | stats.SocketsInUse += delta 129 | statsMutex.Unlock() 130 | } 131 | } 132 | 133 | func (stats *Stats) socketsAlive(delta int) { 134 | if stats != nil { 135 | statsMutex.Lock() 136 | stats.SocketsAlive += delta 137 | statsMutex.Unlock() 138 | } 139 | } 140 | 141 | func (stats *Stats) socketRefs(delta int) { 142 | if stats != nil { 143 | statsMutex.Lock() 144 | stats.SocketRefs += delta 145 | statsMutex.Unlock() 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/suite_test.go: -------------------------------------------------------------------------------- 1 | // mgo - MongoDB driver 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 | 27 | package mgo_test 28 | 29 | import ( 30 | "bytes" 31 | "errors" 32 | "flag" 33 | "fmt" 34 | "net" 35 | "os/exec" 36 | "runtime" 37 | "strconv" 38 | "testing" 39 | "time" 40 | 41 | . "gopkg.in/check.v1" 42 | "gopkg.in/mgo.v2" 43 | "gopkg.in/mgo.v2/bson" 44 | ) 45 | 46 | var fast = flag.Bool("fast", false, "Skip slow tests") 47 | 48 | type M bson.M 49 | 50 | type cLogger C 51 | 52 | func (c *cLogger) Output(calldepth int, s string) error { 53 | ns := time.Now().UnixNano() 54 | t := float64(ns%100e9) / 1e9 55 | ((*C)(c)).Logf("[LOG] %.05f %s", t, s) 56 | return nil 57 | } 58 | 59 | func TestAll(t *testing.T) { 60 | TestingT(t) 61 | } 62 | 63 | type S struct { 64 | session *mgo.Session 65 | stopped bool 66 | build mgo.BuildInfo 67 | frozen []string 68 | } 69 | 70 | func (s *S) versionAtLeast(v ...int) (result bool) { 71 | for i := range v { 72 | if i == len(s.build.VersionArray) { 73 | return false 74 | } 75 | if s.build.VersionArray[i] != v[i] { 76 | return s.build.VersionArray[i] >= v[i] 77 | } 78 | } 79 | return true 80 | } 81 | 82 | var _ = Suite(&S{}) 83 | 84 | func (s *S) SetUpSuite(c *C) { 85 | mgo.SetDebug(true) 86 | mgo.SetStats(true) 87 | s.StartAll() 88 | 89 | session, err := mgo.Dial("localhost:40001") 90 | c.Assert(err, IsNil) 91 | s.build, err = session.BuildInfo() 92 | c.Check(err, IsNil) 93 | session.Close() 94 | } 95 | 96 | func (s *S) SetUpTest(c *C) { 97 | err := run("mongo --nodb harness/mongojs/dropall.js") 98 | if err != nil { 99 | panic(err.Error()) 100 | } 101 | mgo.SetLogger((*cLogger)(c)) 102 | mgo.ResetStats() 103 | } 104 | 105 | func (s *S) TearDownTest(c *C) { 106 | if s.stopped { 107 | s.Stop(":40201") 108 | s.Stop(":40202") 109 | s.Stop(":40203") 110 | s.StartAll() 111 | } 112 | for _, host := range s.frozen { 113 | if host != "" { 114 | s.Thaw(host) 115 | } 116 | } 117 | var stats mgo.Stats 118 | for i := 0; ; i++ { 119 | stats = mgo.GetStats() 120 | if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 { 121 | break 122 | } 123 | if i == 20 { 124 | c.Fatal("Test left sockets in a dirty state") 125 | } 126 | c.Logf("Waiting for sockets to die: %d in use, %d alive", stats.SocketsInUse, stats.SocketsAlive) 127 | time.Sleep(500 * time.Millisecond) 128 | } 129 | for i := 0; ; i++ { 130 | stats = mgo.GetStats() 131 | if stats.Clusters == 0 { 132 | break 133 | } 134 | if i == 60 { 135 | c.Fatal("Test left clusters alive") 136 | } 137 | c.Logf("Waiting for clusters to die: %d alive", stats.Clusters) 138 | time.Sleep(1 * time.Second) 139 | } 140 | } 141 | 142 | func (s *S) Stop(host string) { 143 | // Give a moment for slaves to sync and avoid getting rollback issues. 144 | panicOnWindows() 145 | time.Sleep(2 * time.Second) 146 | err := run("svc -d _harness/daemons/" + supvName(host)) 147 | if err != nil { 148 | panic(err) 149 | } 150 | s.stopped = true 151 | } 152 | 153 | func (s *S) pid(host string) int { 154 | // Note recent releases of lsof force 'f' to be present in the output (WTF?). 155 | cmd := exec.Command("lsof", "-iTCP:"+hostPort(host), "-sTCP:LISTEN", "-Fpf") 156 | output, err := cmd.CombinedOutput() 157 | if err != nil { 158 | panic(err) 159 | } 160 | pidstr := string(bytes.Fields(output[1:])[0]) 161 | pid, err := strconv.Atoi(pidstr) 162 | if err != nil { 163 | panic(fmt.Errorf("cannot convert pid to int: %q, command line: %q", pidstr, cmd.Args)) 164 | } 165 | return pid 166 | } 167 | 168 | func (s *S) Freeze(host string) { 169 | err := stop(s.pid(host)) 170 | if err != nil { 171 | panic(err) 172 | } 173 | s.frozen = append(s.frozen, host) 174 | } 175 | 176 | func (s *S) Thaw(host string) { 177 | err := cont(s.pid(host)) 178 | if err != nil { 179 | panic(err) 180 | } 181 | for i, frozen := range s.frozen { 182 | if frozen == host { 183 | s.frozen[i] = "" 184 | } 185 | } 186 | } 187 | 188 | func (s *S) StartAll() { 189 | if s.stopped { 190 | // Restart any stopped nodes. 191 | run("svc -u _harness/daemons/*") 192 | err := run("mongo --nodb harness/mongojs/wait.js") 193 | if err != nil { 194 | panic(err) 195 | } 196 | s.stopped = false 197 | } 198 | } 199 | 200 | func run(command string) error { 201 | var output []byte 202 | var err error 203 | if runtime.GOOS == "windows" { 204 | output, err = exec.Command("cmd", "/C", command).CombinedOutput() 205 | } else { 206 | output, err = exec.Command("/bin/sh", "-c", command).CombinedOutput() 207 | } 208 | 209 | if err != nil { 210 | msg := fmt.Sprintf("Failed to execute: %s: %s\n%s", command, err.Error(), string(output)) 211 | return errors.New(msg) 212 | } 213 | return nil 214 | } 215 | 216 | var supvNames = map[string]string{ 217 | "40001": "db1", 218 | "40002": "db2", 219 | "40011": "rs1a", 220 | "40012": "rs1b", 221 | "40013": "rs1c", 222 | "40021": "rs2a", 223 | "40022": "rs2b", 224 | "40023": "rs2c", 225 | "40031": "rs3a", 226 | "40032": "rs3b", 227 | "40033": "rs3c", 228 | "40041": "rs4a", 229 | "40101": "cfg1", 230 | "40102": "cfg2", 231 | "40103": "cfg3", 232 | "40201": "s1", 233 | "40202": "s2", 234 | "40203": "s3", 235 | } 236 | 237 | // supvName returns the daemon name for the given host address. 238 | func supvName(host string) string { 239 | host, port, err := net.SplitHostPort(host) 240 | if err != nil { 241 | panic(err) 242 | } 243 | name, ok := supvNames[port] 244 | if !ok { 245 | panic("Unknown host: " + host) 246 | } 247 | return name 248 | } 249 | 250 | func hostPort(host string) string { 251 | _, port, err := net.SplitHostPort(host) 252 | if err != nil { 253 | panic(err) 254 | } 255 | return port 256 | } 257 | 258 | func panicOnWindows() { 259 | if runtime.GOOS == "windows" { 260 | panic("the test suite is not yet fully supported on Windows") 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/syscall_test.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package mgo_test 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | func stop(pid int) (err error) { 10 | return syscall.Kill(pid, syscall.SIGSTOP) 11 | } 12 | 13 | func cont(pid int) (err error) { 14 | return syscall.Kill(pid, syscall.SIGCONT) 15 | } 16 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/syscall_windows_test.go: -------------------------------------------------------------------------------- 1 | package mgo_test 2 | 3 | func stop(pid int) (err error) { 4 | panicOnWindows() // Always does. 5 | return nil 6 | } 7 | 8 | func cont(pid int) (err error) { 9 | panicOnWindows() // Always does. 10 | return nil 11 | } 12 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/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(sc*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 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/txn/debug.go: -------------------------------------------------------------------------------- 1 | package txn 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "sort" 7 | "sync/atomic" 8 | 9 | "gopkg.in/mgo.v2/bson" 10 | ) 11 | 12 | var ( 13 | debugEnabled bool 14 | logger log_Logger 15 | ) 16 | 17 | type log_Logger interface { 18 | Output(calldepth int, s string) error 19 | } 20 | 21 | // Specify the *log.Logger where logged messages should be sent to. 22 | func SetLogger(l log_Logger) { 23 | logger = l 24 | } 25 | 26 | // SetDebug enables or disables debugging. 27 | func SetDebug(debug bool) { 28 | debugEnabled = debug 29 | } 30 | 31 | var ErrChaos = fmt.Errorf("interrupted by chaos") 32 | 33 | var debugId uint32 34 | 35 | func debugPrefix() string { 36 | d := atomic.AddUint32(&debugId, 1) - 1 37 | s := make([]byte, 0, 10) 38 | for i := uint(0); i < 8; i++ { 39 | s = append(s, "abcdefghijklmnop"[(d>>(4*i))&0xf]) 40 | if d>>(4*(i+1)) == 0 { 41 | break 42 | } 43 | } 44 | s = append(s, ')', ' ') 45 | return string(s) 46 | } 47 | 48 | func logf(format string, args ...interface{}) { 49 | if logger != nil { 50 | logger.Output(2, fmt.Sprintf(format, argsForLog(args)...)) 51 | } 52 | } 53 | 54 | func debugf(format string, args ...interface{}) { 55 | if debugEnabled && logger != nil { 56 | logger.Output(2, fmt.Sprintf(format, argsForLog(args)...)) 57 | } 58 | } 59 | 60 | func argsForLog(args []interface{}) []interface{} { 61 | for i, arg := range args { 62 | switch v := arg.(type) { 63 | case bson.ObjectId: 64 | args[i] = v.Hex() 65 | case []bson.ObjectId: 66 | lst := make([]string, len(v)) 67 | for j, id := range v { 68 | lst[j] = id.Hex() 69 | } 70 | args[i] = lst 71 | case map[docKey][]bson.ObjectId: 72 | buf := &bytes.Buffer{} 73 | var dkeys docKeys 74 | for dkey := range v { 75 | dkeys = append(dkeys, dkey) 76 | } 77 | sort.Sort(dkeys) 78 | for i, dkey := range dkeys { 79 | if i > 0 { 80 | buf.WriteByte(' ') 81 | } 82 | buf.WriteString(fmt.Sprintf("%v: {", dkey)) 83 | for j, id := range v[dkey] { 84 | if j > 0 { 85 | buf.WriteByte(' ') 86 | } 87 | buf.WriteString(id.Hex()) 88 | } 89 | buf.WriteByte('}') 90 | } 91 | args[i] = buf.String() 92 | case map[docKey][]int64: 93 | buf := &bytes.Buffer{} 94 | var dkeys docKeys 95 | for dkey := range v { 96 | dkeys = append(dkeys, dkey) 97 | } 98 | sort.Sort(dkeys) 99 | for i, dkey := range dkeys { 100 | if i > 0 { 101 | buf.WriteByte(' ') 102 | } 103 | buf.WriteString(fmt.Sprintf("%v: %v", dkey, v[dkey])) 104 | } 105 | args[i] = buf.String() 106 | } 107 | } 108 | return args 109 | } 110 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/txn/dockey_test.go: -------------------------------------------------------------------------------- 1 | package txn 2 | 3 | import ( 4 | "sort" 5 | 6 | . "gopkg.in/check.v1" 7 | ) 8 | 9 | type DocKeySuite struct{} 10 | 11 | var _ = Suite(&DocKeySuite{}) 12 | 13 | type T struct { 14 | A int 15 | B string 16 | } 17 | 18 | type T2 struct { 19 | A int 20 | B string 21 | } 22 | 23 | type T3 struct { 24 | A int 25 | B string 26 | } 27 | 28 | type T4 struct { 29 | A int 30 | B string 31 | } 32 | 33 | type T5 struct { 34 | F int 35 | Q string 36 | } 37 | 38 | type T6 struct { 39 | A int 40 | B string 41 | } 42 | 43 | type T7 struct { 44 | A bool 45 | B float64 46 | } 47 | 48 | type T8 struct { 49 | A int 50 | B string 51 | } 52 | 53 | type T9 struct { 54 | A int 55 | B string 56 | C bool 57 | } 58 | 59 | type T10 struct { 60 | C int `bson:"a"` 61 | D string `bson:"b,omitempty"` 62 | } 63 | 64 | type T11 struct { 65 | C int 66 | D string 67 | } 68 | 69 | type T12 struct { 70 | S string 71 | } 72 | 73 | type T13 struct { 74 | p, q, r bool 75 | S string 76 | } 77 | 78 | var docKeysTests = [][]docKeys{ 79 | {{ 80 | {"c", 1}, 81 | {"c", 5}, 82 | {"c", 2}, 83 | }, { 84 | {"c", 1}, 85 | {"c", 2}, 86 | {"c", 5}, 87 | }}, {{ 88 | {"c", "foo"}, 89 | {"c", "bar"}, 90 | {"c", "bob"}, 91 | }, { 92 | {"c", "bar"}, 93 | {"c", "bob"}, 94 | {"c", "foo"}, 95 | }}, {{ 96 | {"c", 0.2}, 97 | {"c", 0.07}, 98 | {"c", 0.9}, 99 | }, { 100 | {"c", 0.07}, 101 | {"c", 0.2}, 102 | {"c", 0.9}, 103 | }}, {{ 104 | {"c", true}, 105 | {"c", false}, 106 | {"c", true}, 107 | }, { 108 | {"c", false}, 109 | {"c", true}, 110 | {"c", true}, 111 | }}, {{ 112 | {"c", T{1, "b"}}, 113 | {"c", T{1, "a"}}, 114 | {"c", T{0, "b"}}, 115 | {"c", T{0, "a"}}, 116 | }, { 117 | {"c", T{0, "a"}}, 118 | {"c", T{0, "b"}}, 119 | {"c", T{1, "a"}}, 120 | {"c", T{1, "b"}}, 121 | }}, {{ 122 | {"c", T{1, "a"}}, 123 | {"c", T{0, "a"}}, 124 | }, { 125 | {"c", T{0, "a"}}, 126 | {"c", T{1, "a"}}, 127 | }}, {{ 128 | {"c", T3{0, "b"}}, 129 | {"c", T2{1, "b"}}, 130 | {"c", T3{1, "a"}}, 131 | {"c", T2{0, "a"}}, 132 | }, { 133 | {"c", T2{0, "a"}}, 134 | {"c", T3{0, "b"}}, 135 | {"c", T3{1, "a"}}, 136 | {"c", T2{1, "b"}}, 137 | }}, {{ 138 | {"c", T5{1, "b"}}, 139 | {"c", T4{1, "b"}}, 140 | {"c", T5{0, "a"}}, 141 | {"c", T4{0, "a"}}, 142 | }, { 143 | {"c", T4{0, "a"}}, 144 | {"c", T5{0, "a"}}, 145 | {"c", T4{1, "b"}}, 146 | {"c", T5{1, "b"}}, 147 | }}, {{ 148 | {"c", T6{1, "b"}}, 149 | {"c", T7{true, 0.2}}, 150 | {"c", T6{0, "a"}}, 151 | {"c", T7{false, 0.04}}, 152 | }, { 153 | {"c", T6{0, "a"}}, 154 | {"c", T6{1, "b"}}, 155 | {"c", T7{false, 0.04}}, 156 | {"c", T7{true, 0.2}}, 157 | }}, {{ 158 | {"c", T9{1, "b", true}}, 159 | {"c", T8{1, "b"}}, 160 | {"c", T9{0, "a", false}}, 161 | {"c", T8{0, "a"}}, 162 | }, { 163 | {"c", T9{0, "a", false}}, 164 | {"c", T8{0, "a"}}, 165 | {"c", T9{1, "b", true}}, 166 | {"c", T8{1, "b"}}, 167 | }}, {{ 168 | {"b", 2}, 169 | {"a", 5}, 170 | {"c", 2}, 171 | {"b", 1}, 172 | }, { 173 | {"a", 5}, 174 | {"b", 1}, 175 | {"b", 2}, 176 | {"c", 2}, 177 | }}, {{ 178 | {"c", T11{1, "a"}}, 179 | {"c", T11{1, "a"}}, 180 | {"c", T10{1, "a"}}, 181 | }, { 182 | {"c", T10{1, "a"}}, 183 | {"c", T11{1, "a"}}, 184 | {"c", T11{1, "a"}}, 185 | }}, {{ 186 | {"c", T12{"a"}}, 187 | {"c", T13{false, true, false, "a"}}, 188 | {"c", T12{"b"}}, 189 | {"c", T13{false, true, false, "b"}}, 190 | }, { 191 | {"c", T12{"a"}}, 192 | {"c", T13{false, true, false, "a"}}, 193 | {"c", T12{"b"}}, 194 | {"c", T13{false, true, false, "b"}}, 195 | }}, 196 | } 197 | 198 | func (s *DocKeySuite) TestSort(c *C) { 199 | for _, test := range docKeysTests { 200 | keys := test[0] 201 | expected := test[1] 202 | sort.Sort(keys) 203 | c.Check(keys, DeepEquals, expected) 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/txn/output.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/go-worker/vendor/gopkg.in/mgo.v2/txn/output.txt -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/txn/tarjan.go: -------------------------------------------------------------------------------- 1 | package txn 2 | 3 | import ( 4 | "gopkg.in/mgo.v2/bson" 5 | "sort" 6 | ) 7 | 8 | func tarjanSort(successors map[bson.ObjectId][]bson.ObjectId) [][]bson.ObjectId { 9 | // http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm 10 | data := &tarjanData{ 11 | successors: successors, 12 | nodes: make([]tarjanNode, 0, len(successors)), 13 | index: make(map[bson.ObjectId]int, len(successors)), 14 | } 15 | 16 | for id := range successors { 17 | id := bson.ObjectId(string(id)) 18 | if _, seen := data.index[id]; !seen { 19 | data.strongConnect(id) 20 | } 21 | } 22 | 23 | // Sort connected components to stabilize the algorithm. 24 | for _, ids := range data.output { 25 | if len(ids) > 1 { 26 | sort.Sort(idList(ids)) 27 | } 28 | } 29 | return data.output 30 | } 31 | 32 | type tarjanData struct { 33 | successors map[bson.ObjectId][]bson.ObjectId 34 | output [][]bson.ObjectId 35 | 36 | nodes []tarjanNode 37 | stack []bson.ObjectId 38 | index map[bson.ObjectId]int 39 | } 40 | 41 | type tarjanNode struct { 42 | lowlink int 43 | stacked bool 44 | } 45 | 46 | type idList []bson.ObjectId 47 | 48 | func (l idList) Len() int { return len(l) } 49 | func (l idList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } 50 | func (l idList) Less(i, j int) bool { return l[i] < l[j] } 51 | 52 | func (data *tarjanData) strongConnect(id bson.ObjectId) *tarjanNode { 53 | index := len(data.nodes) 54 | data.index[id] = index 55 | data.stack = append(data.stack, id) 56 | data.nodes = append(data.nodes, tarjanNode{index, true}) 57 | node := &data.nodes[index] 58 | 59 | for _, succid := range data.successors[id] { 60 | succindex, seen := data.index[succid] 61 | if !seen { 62 | succnode := data.strongConnect(succid) 63 | if succnode.lowlink < node.lowlink { 64 | node.lowlink = succnode.lowlink 65 | } 66 | } else if data.nodes[succindex].stacked { 67 | // Part of the current strongly-connected component. 68 | if succindex < node.lowlink { 69 | node.lowlink = succindex 70 | } 71 | } 72 | } 73 | 74 | if node.lowlink == index { 75 | // Root node; pop stack and output new 76 | // strongly-connected component. 77 | var scc []bson.ObjectId 78 | i := len(data.stack) - 1 79 | for { 80 | stackid := data.stack[i] 81 | stackindex := data.index[stackid] 82 | data.nodes[stackindex].stacked = false 83 | scc = append(scc, stackid) 84 | if stackindex == index { 85 | break 86 | } 87 | i-- 88 | } 89 | data.stack = data.stack[:i] 90 | data.output = append(data.output, scc) 91 | } 92 | 93 | return node 94 | } 95 | -------------------------------------------------------------------------------- /go-worker/vendor/gopkg.in/mgo.v2/txn/tarjan_test.go: -------------------------------------------------------------------------------- 1 | package txn 2 | 3 | import ( 4 | "fmt" 5 | "gopkg.in/mgo.v2/bson" 6 | . "gopkg.in/check.v1" 7 | ) 8 | 9 | type TarjanSuite struct{} 10 | 11 | var _ = Suite(TarjanSuite{}) 12 | 13 | func bid(n int) bson.ObjectId { 14 | return bson.ObjectId(fmt.Sprintf("%024d", n)) 15 | } 16 | 17 | func bids(ns ...int) (ids []bson.ObjectId) { 18 | for _, n := range ns { 19 | ids = append(ids, bid(n)) 20 | } 21 | return 22 | } 23 | 24 | func (TarjanSuite) TestExample(c *C) { 25 | successors := map[bson.ObjectId][]bson.ObjectId{ 26 | bid(1): bids(2, 3), 27 | bid(2): bids(1, 5), 28 | bid(3): bids(4), 29 | bid(4): bids(3, 5), 30 | bid(5): bids(6), 31 | bid(6): bids(7), 32 | bid(7): bids(8), 33 | bid(8): bids(6, 9), 34 | bid(9): bids(), 35 | } 36 | 37 | c.Assert(tarjanSort(successors), DeepEquals, [][]bson.ObjectId{ 38 | bids(9), 39 | bids(6, 7, 8), 40 | bids(5), 41 | bids(3, 4), 42 | bids(1, 2), 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /images/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/images/diagram.png -------------------------------------------------------------------------------- /spawner-functions/host.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /spawner-functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spawner-functions", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@azure/arm-containerinstance": "^8.1.0", 13 | "@azure/identity": "^2.0.4", 14 | "mongodb": "^3.0.7" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spawner-functions/sbqTriggerCreateWorkerContainer/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": [ 3 | { 4 | "name": "mySbMsg", 5 | "type": "serviceBusTrigger", 6 | "direction": "in", 7 | "queueName": "createqueue", 8 | "connection": "servicebus_connectionString", 9 | "accessRights": "Listen" 10 | } 11 | ], 12 | "disabled": false 13 | } -------------------------------------------------------------------------------- /spawner-functions/sbqTriggerCreateWorkerContainer/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var { ClientSecretCredential } = require("@azure/identity"); 4 | var { ContainerInstanceManagementClient } = require("@azure/arm-containerinstance"); 5 | 6 | var clientId = process.env.client_id, 7 | secret = process.env.client_secret, 8 | domain = process.env.tenant, 9 | subscriptionId = process.env.subscription_id, 10 | db_connection = process.env.CUSTOMCONNSTR_CosmosDB, 11 | resourceGroupName = process.env.resourceGroup; 12 | 13 | var db_user = db_connection.slice(10, db_connection.indexOf(':',10)); 14 | var db_pwd = db_connection.slice(db_connection.indexOf(':',10) + 1, db_connection.indexOf('@')); 15 | var db_uri = 'mongodb://' + db_connection.slice(db_connection.indexOf('@')+1) + '&ssl=true'; 16 | 17 | const db_name = "containerstate"; 18 | const IMAGE = "hubertsui/go-worker:latest"; 19 | const MongoClient = require('mongodb').MongoClient; 20 | 21 | module.exports = function(context, mySbMsg) { 22 | if ( !mySbMsg || mySbMsg.length == 0){ 23 | context.done('JavaScript ServiceBus queue message is empty'); 24 | return; 25 | } 26 | 27 | mySbMsg = mySbMsg.replace(/: u'/g,": '").replace(/'/g,"\""); 28 | context.log.info('service bus message', mySbMsg); 29 | var sbMsgObj = JSON.parse(mySbMsg); 30 | if ( !sbMsgObj || !sbMsgObj.hasOwnProperty('name')){ 31 | let errMsg = 'JavaScript ServiceBus queue message has no container name.' 32 | context.log.error(errMsg); 33 | context.done(errMsg); 34 | return; 35 | } 36 | 37 | context.log('JavaScript ServiceBus queue trigger function processed message', mySbMsg); 38 | try{ 39 | context.log.info("got credentials"); 40 | const credentials = new ClientSecretCredential(domain,clientId,secret); 41 | 42 | let client = new ContainerInstanceManagementClient(credentials,subscriptionId); 43 | let containerName = sbMsgObj.name; 44 | let containerMsg = sbMsgObj.input; 45 | 46 | let containerGroup = { 47 | containers: [ 48 | { 49 | name: containerName, 50 | environmentVariables: [ 51 | { 52 | name: "MESSAGE", 53 | value: containerMsg 54 | }, 55 | { 56 | name: "CONTAINER_NAME", 57 | value: containerName 58 | }, 59 | { 60 | name: "DATABASE_URI", 61 | value: db_connection 62 | }], 63 | image: IMAGE, 64 | ports: [ 65 | { 66 | "port": 80 67 | } 68 | ], 69 | resources: { 70 | requests: { 71 | cpu: 1, 72 | memoryInGB: 1.5 73 | } 74 | }, 75 | } 76 | ], 77 | restartPolicy: "Never", 78 | ipAddress: { 79 | ports: [{ port: 80 }] 80 | }, 81 | osType: "Linux", 82 | location: "East US" 83 | }; 84 | 85 | context.log.info("creating container"); 86 | client.containerGroups.beginCreateOrUpdateAndWait(resourceGroupName, containerName, containerGroup) 87 | .then( (cgroup) => { 88 | context.log(cgroup); 89 | context.done(); 90 | }).catch((err) => { 91 | context.log('created container error', err); 92 | MongoClient.connect(db_uri, { auth:{ user: db_user , password: db_pwd }}, function(dbError, client) { 93 | if (dbError){ 94 | context.log(dbError); 95 | context.done(err); 96 | return; 97 | } 98 | 99 | context.log("Connected to cosmosdb server"); 100 | 101 | let db = client.db(db_name); 102 | let col = db.collection(db_name); 103 | col.updateMany({name: containerName }, {$set: { state: "Error", message: JSON.stringify(err) }}, function(dbUpdateError, r){ 104 | if (dbUpdateError){ 105 | context.log(dbUpdateError); 106 | } 107 | client.close(); 108 | context.done(err) 109 | }) 110 | }); 111 | }); 112 | }catch(err){ 113 | console.log(err); 114 | } 115 | 116 | }; -------------------------------------------------------------------------------- /spawner-functions/sbqTriggerDeleteWorkerContainer/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": [ 3 | { 4 | "name": "mySbMsg", 5 | "type": "serviceBusTrigger", 6 | "direction": "in", 7 | "queueName": "deletequeue", 8 | "connection": "servicebus_connectionString", 9 | "accessRights": "Listen" 10 | } 11 | ], 12 | "disabled": false 13 | } -------------------------------------------------------------------------------- /spawner-functions/sbqTriggerDeleteWorkerContainer/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var { ClientSecretCredential } = require("@azure/identity"); 4 | var { ContainerInstanceManagementClient } = require("@azure/arm-containerinstance"); 5 | 6 | var clientId = process.env.client_id, 7 | secret = process.env.client_secret, 8 | domain = process.env.tenant, 9 | subscriptionId = process.env.subscription_id, 10 | resourceGroupName = process.env.resourceGroup; 11 | 12 | module.exports = function(context, mySbMsg) { 13 | context.log('JavaScript ServiceBus queue trigger function processed message', mySbMsg); 14 | const credentials = new ClientSecretCredential(domain,clientId,secret); 15 | let client = new ContainerInstanceManagementClient(credentials,subscriptionId); 16 | let containerGroupName = mySbMsg; 17 | 18 | client.containerGroups.beginDeleteAndWait(resourceGroupName,containerGroupName) 19 | .then( (cgroup) => { 20 | context.log(cgroup) 21 | }).catch((err) => { 22 | context.log(err); 23 | return; 24 | }); 25 | 26 | context.done(); 27 | }; -------------------------------------------------------------------------------- /spawner/.dockerignore: -------------------------------------------------------------------------------- 1 | config/ 2 | .env -------------------------------------------------------------------------------- /spawner/Dockerfile: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------------------- 2 | # Copyright (c) Microsoft Corporation. All rights reserved. 3 | # Licensed under the MIT License. See License.txt in the project root for license information. 4 | # ----------------------------------------------------------------------------------- 5 | 6 | FROM python 7 | 8 | COPY requirements.txt / 9 | 10 | RUN pip install -r /requirements.txt 11 | 12 | COPY . /app 13 | WORKDIR /app 14 | 15 | CMD [ "python", "run.py" ] 16 | 17 | 18 | -------------------------------------------------------------------------------- /spawner/Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | docker build -t pskreter/spawner:latest . 3 | 4 | push: 5 | docker push pskreter/spawner:latest 6 | 7 | run: 8 | docker run --rm --name spawner pskreter/spawner 9 | 10 | rund: 11 | docker run --rm -d --name spawner pskreter/spawner -------------------------------------------------------------------------------- /spawner/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/spawner/config/__init__.py -------------------------------------------------------------------------------- /spawner/config/config.py: -------------------------------------------------------------------------------- 1 | from azure.identity import DefaultAzureCredential 2 | import os 3 | 4 | class AzureContext(object): 5 | """Azure Security Context. 6 | 7 | remarks: 8 | This is a helper to combine service principal credentials with the subscription id. 9 | Notice that the client is using default Azure credentials. 10 | To make default credentials work, ensure that environment variables 'Azure_Client_ID', 11 | 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials. 12 | """ 13 | 14 | def __init__(self, subscription_id): 15 | self.credentials = DefaultAzureCredential() 16 | self.subscription_id = subscription_id 17 | 18 | 19 | azure_context = AzureContext( 20 | subscription_id = os.getenv("AZURE_SUBSCRIPTION_ID") 21 | ) 22 | 23 | #ACI Specific configurations 24 | ACI_CONFIG = { 25 | "subscriptionId": os.getenv("AZURE_SUBSCRIPTION_ID"), 26 | "resourceGroup": os.getenv("AZURE_RESOURCE_GROUP"), 27 | "location": os.getenv("AZURE_LOCATION") 28 | } 29 | 30 | #CosmosMongoDb without the ssl 31 | DATABASE_URI = os.getenv("COSMOS_CONNECTION_STRING") 32 | 33 | queueConf = { 34 | 'queue_name': os.getenv("SERVICE_BUS_CREATE_QUEUE"), 35 | 'delete_queue_name': os.getenv("SERVICE_BUS_DELETE_QUEUE"), 36 | 'connstr': os.getenv('SERVICE_BUS_CONNECTION_STR') 37 | } 38 | -------------------------------------------------------------------------------- /spawner/create-aci.sh: -------------------------------------------------------------------------------- 1 | az container create \ 2 | -g aciherodemo \ 3 | -n spawner \ 4 | --image pskreter/spawner:prod \ 5 | --azure-file-volume-account-name $STORAGE_NAME \ 6 | --azure-file-volume-account-key $STORAGE_KEY \ 7 | --azure-file-volume-share-name $SHARE_NAME \ 8 | --azure-file-volume-mount-path /app/config/ -------------------------------------------------------------------------------- /spawner/example-config.py: -------------------------------------------------------------------------------- 1 | from azure.identity import DefaultAzureCredential 2 | 3 | class AzureContext(object): 4 | """Azure Security Context. 5 | 6 | remarks: 7 | This is a helper to combine service principal credentials with the subscription id. 8 | Notice that the client is using default Azure credentials. 9 | To make default credentials work, ensure that environment variables 'Azure_Client_ID', 10 | 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials. 11 | """ 12 | 13 | def __init__(self, subscription_id): 14 | self.credentials = DefaultAzureCredential() 15 | self.subscription_id = subscription_id 16 | 17 | 18 | azure_context = AzureContext( 19 | subscription_id = '' 20 | ) 21 | 22 | #ACI Specific configurations 23 | ACI_CONFIG = { 24 | "subscriptionId": "", 25 | "resourceGroup": "", 26 | "location": "" 27 | } 28 | 29 | #CosmosMongoDb without the ssl 30 | DATABASE_URI = "" 31 | 32 | queueConf = { 33 | 'queue_name': '', 34 | 'connstr': '' 35 | } 36 | -------------------------------------------------------------------------------- /spawner/requirements.txt: -------------------------------------------------------------------------------- 1 | azure-common==1.1.27 2 | azure-mgmt-resource==20.0.0 3 | azure-mgmt-containerinstance==9.1.0 4 | azure-servicebus>=7.3.4 -------------------------------------------------------------------------------- /spawner/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import random 4 | import string 5 | import sys 6 | from collections import deque 7 | from config.config import queueConf, azure_context, DATABASE_URI, ACI_CONFIG 8 | from azure.servicebus import ServiceBusClient, ServiceBusReceiveMode 9 | from azure.mgmt.resource import ResourceManagementClient 10 | from azure.mgmt.containerinstance import ContainerInstanceManagementClient 11 | from azure.mgmt.containerinstance.models import (ContainerGroup, Container, ContainerPort, Port, IpAddress, EnvironmentVariable, 12 | ResourceRequirements, ResourceRequests, ContainerGroupNetworkProtocol, OperatingSystemTypes) 13 | 14 | resource_client = ResourceManagementClient(azure_context.credentials, azure_context.subscription_id) 15 | client = ContainerInstanceManagementClient(azure_context.credentials, azure_context.subscription_id) 16 | 17 | 18 | servicebus_client = ServiceBusClient.from_connection_string(conn_str=queueConf['connstr']) 19 | 20 | 21 | BASE_NAMES = deque(["anders", "wenjun", "robbie", "robin", "allen", "tony", "xiaofeng", "tingting", "harry", "chen"]) 22 | NAMES_COUNTER = 0 23 | IMAGE = "pskreter/worker-container:latest" 24 | 25 | 26 | def main(): 27 | sys.stdout.write("Starting Work Cycle...\n") # same as print 28 | sys.stdout.flush() 29 | while True: 30 | try: 31 | receiver = servicebus_client.get_queue_receiver(queueConf['queue_name'], receive_mode=ServiceBusReceiveMode.RECEIVE_AND_DELETE) 32 | for message in receiver: 33 | raw_amqp_message = message.raw_amqp_message 34 | work = raw_amqp_message.body 35 | container_name = get_container_name() 36 | env_vars = create_env_vars(work, DATABASE_URI, container_name) 37 | sys.stdout.write("Creating container: " + container_name + " with work: " + work + '\n') # same as print 38 | sys.stdout.flush() 39 | create_container_group(ACI_CONFIG['resourceGroup'], container_name, ACI_CONFIG['location'], IMAGE, env_vars) 40 | 41 | except KeyboardInterrupt: 42 | pass 43 | 44 | 45 | def create_env_vars(msg, database_uri, container_name): 46 | msg_var = EnvironmentVariable(name = "MESSAGE", value = msg) 47 | database_var = EnvironmentVariable(name = "DATABASE_URI", value = database_uri) 48 | container_name_var = EnvironmentVariable(name = "CONTAINER_NAME", value = container_name) 49 | 50 | return [msg_var, database_var, container_name_var] 51 | 52 | 53 | def get_container_name(): 54 | random_string = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(7)) 55 | name = BASE_NAMES.popleft() 56 | BASE_NAMES.append(name) 57 | return name + "-" + random_string 58 | 59 | 60 | def create_container_group(resource_group_name, name, location, image, env_vars): 61 | 62 | # setup default values 63 | port = 80 64 | container_resource_requirements = None 65 | command = None 66 | 67 | # set memory and cpu 68 | container_resource_requests = ResourceRequests(memory_in_gb = 3.5, cpu = 2) 69 | container_resource_requirements = ResourceRequirements(requests = container_resource_requests) 70 | 71 | container = Container(name = name, 72 | image = image, 73 | resources = container_resource_requirements, 74 | command = command, 75 | ports = [ContainerPort(port=port)], 76 | environment_variables = env_vars) 77 | 78 | # defaults for container group 79 | cgroup_os_type = OperatingSystemTypes.linux 80 | cgroup_ip_address = IpAddress(ports = [Port(protocol=ContainerGroupNetworkProtocol.tcp, port = port)], type="Public") 81 | image_registry_credentials = None 82 | 83 | cgroup = ContainerGroup(location = location, 84 | containers = [container], 85 | os_type = cgroup_os_type, 86 | ip_address = cgroup_ip_address, 87 | image_registry_credentials = image_registry_credentials) 88 | 89 | client.container_groups.begin_create_or_update(resource_group_name, name, cgroup) 90 | 91 | 92 | if __name__ == '__main__': 93 | main() 94 | -------------------------------------------------------------------------------- /spawner/test.py: -------------------------------------------------------------------------------- 1 | from config.config import queueConf 2 | 3 | 4 | print(queueConf) -------------------------------------------------------------------------------- /web-server/.dockerignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /web-server/Dockerfile: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------------------- 2 | # Copyright (c) Microsoft Corporation. All rights reserved. 3 | # Licensed under the MIT License. See License.txt in the project root for license information. 4 | # ----------------------------------------------------------------------------------- 5 | 6 | FROM python:2.7 7 | 8 | COPY requirements.txt / 9 | 10 | RUN pip install -r /requirements.txt 11 | 12 | COPY . /app 13 | WORKDIR /app 14 | 15 | CMD [ "python", "run.py" ] 16 | 17 | 18 | -------------------------------------------------------------------------------- /web-server/Makefile: -------------------------------------------------------------------------------- 1 | brun: 2 | docker build -t pskreter/web-server:latest . 3 | docker run --rm -p 8000:8000 pskreter/web-server:latest 4 | 5 | build: 6 | docker build -t pskreter/web-server:latest . 7 | 8 | push: 9 | docker push pskreter/web-server:latest 10 | 11 | run: 12 | docker run --rm -p 8000:8000 pskreter/web-server:latest 13 | 14 | dev: 15 | docker run -it --rm -p 8000:8000 -v ${PWD}:/app pskreter/web-server:latest /bin/bash -------------------------------------------------------------------------------- /web-server/aci-create.sh: -------------------------------------------------------------------------------- 1 | az container create \ 2 | -g msazure-aciaks-temp \ 3 | -n web-server \ 4 | --image hubertsui/web-server \ 5 | --dns-name-label msazurebatchdev\ 6 | --ip-address public \ 7 | --ports 80 -------------------------------------------------------------------------------- /web-server/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-event-driven-worker-queue/dc861d00a4b816c5ca09281a90f2d845dfb20724/web-server/config/__init__.py -------------------------------------------------------------------------------- /web-server/config/config.py: -------------------------------------------------------------------------------- 1 | from azure.identity import DefaultAzureCredential 2 | import os 3 | 4 | class AzureContext(object): 5 | """Azure Security Context. 6 | 7 | remarks: 8 | This is a helper to combine service principal credentials with the subscription id. 9 | Notice that the client is using default Azure credentials. 10 | To make default credentials work, ensure that environment variables 'Azure_Client_ID', 11 | 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials. 12 | """ 13 | 14 | def __init__(self, subscription_id): 15 | self.credentials = DefaultAzureCredential() 16 | self.subscription_id = subscription_id 17 | 18 | 19 | azure_context = AzureContext( 20 | subscription_id = os.getenv("AZURE_SUBSCRIPTION_ID") 21 | ) 22 | 23 | #ACI Specific configurations 24 | ACI_CONFIG = { 25 | "subscriptionId": os.getenv("AZURE_SUBSCRIPTION_ID"), 26 | "resourceGroup": os.getenv("AZURE_RESOURCE_GROUP") 27 | } 28 | 29 | #CosmosMongoDb without the ssl 30 | DATABASE_URI = os.getenv("COSMOS_CONNECTION_STRING") 31 | 32 | queueConf = { 33 | 'queue_name': os.getenv("SERVICE_BUS_CREATE_QUEUE"), 34 | 'delete_queue_name': os.getenv("SERVICE_BUS_DELETE_QUEUE"), 35 | 'connstr': os.getenv('SERVICE_BUS_CONNECTION_STR') 36 | } 37 | -------------------------------------------------------------------------------- /web-server/example-config.py: -------------------------------------------------------------------------------- 1 | from azure.identity import DefaultAzureCredential 2 | 3 | class AzureContext(object): 4 | """Azure Security Context. 5 | 6 | remarks: 7 | This is a helper to combine service principal credentials with the subscription id. 8 | Notice that the client is using default Azure credentials. 9 | To make default credentials work, ensure that environment variables 'Azure_Client_ID', 10 | 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials. 11 | """ 12 | 13 | def __init__(self, subscription_id): 14 | self.credentials = DefaultAzureCredential() 15 | self.subscription_id = subscription_id 16 | 17 | #Service Principle Creds for ACI 18 | azure_context = AzureContext( 19 | subscription_id = '' 20 | ) 21 | 22 | #ACI Specific configurations 23 | ACI_CONFIG = { 24 | "subscriptionId": "", 25 | "resourceGroup": "", 26 | "location": "" 27 | } 28 | 29 | #Cosmosdb mongodb api connection string 30 | DATABASE_URI = "" 31 | 32 | #Service Bus Queue Config 33 | queueConf = { 34 | 'queue_name': '', 35 | 'connstr': '' 36 | } 37 | -------------------------------------------------------------------------------- /web-server/requirements.txt: -------------------------------------------------------------------------------- 1 | azure-common==1.1.27 2 | azure-servicebus>=7.3.4 3 | azure-mgmt-monitor==2.0.0 4 | flask 5 | jsonify 6 | bson 7 | pymongo 8 | requests -------------------------------------------------------------------------------- /web-server/util.ps1: -------------------------------------------------------------------------------- 1 | # drm 2 | 3 | $imageName = "pskreter/web-server:latest" 4 | $containerName = "hero-web-server" 5 | 6 | 7 | if ($args.Count -gt 0 ){ 8 | 9 | if($args[0] -eq "dev"){ 10 | docker stop $containerName 11 | docker run --name $containerName -it --rm -p 8000:8000 -v ${PWD}:/app $imageName /bin/bash 12 | } 13 | elseif($args[0] -eq "build-run") { 14 | docker build -t $imageName . 15 | docker stop $containerName 16 | docker run --rm -p 8000:8000 --name $containerName $imageName 17 | } 18 | elseif($args[0] -eq "build-push"){ 19 | docker build -t $imageName . 20 | docker push $imageName 21 | } 22 | } 23 | else { 24 | docker stop $containerName 25 | docker run --rm -p 8000:8000 --name $containerName $imageName 26 | } 27 | 28 | --------------------------------------------------------------------------------