From d82aa00e2b483942c60ee20661d68e98ad5174b2 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Tue, 8 Jan 2019 12:50:55 +0100 Subject: [PATCH 01/12] No ETCD PoC --- .dockerignore | 1 + Dockerfile | 9 + docker-compose.yaml | 20 +- .../docker-compose.yaml | 5 +- npm-shrinkwrap.json | 2285 ++++++++--------- package.json | 1 - src/common/cassandra.js | 12 +- src/common/config.js | 20 +- src/common/service-discovery.js | 66 +- src/index.js | 8 +- .../register-with-service-discovery.js | 10 +- src/services/search/get-query-suggestions.js | 4 +- .../suggested-videos/get-related-videos.js | 8 +- 13 files changed, 1198 insertions(+), 1251 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..046b469 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM node:8 +WORKDIR /usr/src/app + +COPY . . + +RUN npm install --unsafe-perm +RUN npm run build + +CMD node dist/index.js diff --git a/docker-compose.yaml b/docker-compose.yaml index a9f9315..5220714 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,9 +2,21 @@ version: '3' # Other services are specified in .\lib\killrvideo-docker-common\docker-compose.yaml services: + node: + build: /Users/aleksandrvolochnev/killrvideo/node + depends_on: + - dse + environment: + KILLRVIDEO_ETCD: "etcd:2379" + KILLRVIDEO_DSE_USERNAME: $KILLRVIDEO_DSE_USERNAME + KILLRVIDEO_DSE_PASSWORD: $KILLRVIDEO_DSE_PASSWORD + KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION + KILLRVIDEO_LOGGING_LEVEL: $KILLRVIDEO_LOGGING_LEVEL + # Start the KillrVideo web UI on port 3000 web: image: killrvideo/killrvideo-web:1.2.6 + #build: /Users/aleksandrvolochnev/killrvideo/web ports: - "3000:3000" depends_on: @@ -22,12 +34,12 @@ services: generator: image: killrvideo/killrvideo-generator:1.2.4 depends_on: - - dse - - etcd + - dse + - etcd environment: KILLRVIDEO_ETCD: "etcd:2379" - KILLRVIDEO_DSE_USERNAME: $KILLRVIDEO_DSE_USERNAME - KILLRVIDEO_DSE_PASSWORD: $KILLRVIDEO_DSE_PASSWORD + KILLRVIDEO_DSE_USERNAME: cassandra + KILLRVIDEO_DSE_PASSWORD: cassandra NODE_ENV: $NODE_ENV KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION KILLRVIDEO_LOGGING_LEVEL: $KILLRVIDEO_LOGGING_LEVEL diff --git a/lib/killrvideo-docker-common/docker-compose.yaml b/lib/killrvideo-docker-common/docker-compose.yaml index 8268688..c470993 100644 --- a/lib/killrvideo-docker-common/docker-compose.yaml +++ b/lib/killrvideo-docker-common/docker-compose.yaml @@ -20,7 +20,8 @@ services: registrator: image: gliderlabs/registrator:latest # Tell registrator where the etcd HTTP API is and to use the docker VM's IP - command: [ -ip, "$KILLRVIDEO_DOCKER_IP", "etcd://etcd:2379/killrvideo/services" ] + #command: [ -ip, "$KILLRVIDEO_DOCKER_IP", "etcd://etcd:2379/killrvideo/services" ] + command: [ "etcd://etcd:2379/killrvideo/services" ] volumes: # So registrator can use the docker API to inspect containers - "/var/run/docker.sock:/tmp/docker.sock" @@ -48,7 +49,7 @@ services: # Container to load KillrVideo schema and search config into DSE # Provides options to configure secure users as well dse-config: - image: killrvideo/killrvideo-dse-config:1.2.1 + image: hadesarchitect/killrvideo-dse-config:disable-loopback environment: KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP KILLRVIDEO_DSE_EXTERNAL_IP: $KILLRVIDEO_DSE_EXTERNAL_IP diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index aa8d3b8..d617284 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -9,10 +9,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "ansi-regex": { @@ -32,8 +32,8 @@ "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", "dev": true, "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11" + "arrify": "^1.0.0", + "micromatch": "^2.1.5" } }, "arguejs": { @@ -47,7 +47,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.0.1" + "arr-flatten": "^1.0.1" } }, "arr-flatten": { @@ -91,8 +91,8 @@ "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", "requires": { - "colour": "0.7.1", - "optjs": "3.2.2" + "colour": "~0.7.1", + "optjs": "~3.2.2" } }, "asn1": { @@ -110,7 +110,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", "requires": { - "lodash": "4.17.4" + "lodash": "^4.14.0" } }, "async-each": { @@ -140,21 +140,21 @@ "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", "dev": true, "requires": { - "babel-core": "6.26.0", - "babel-polyfill": "6.26.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "chokidar": "1.7.0", - "commander": "2.11.0", - "convert-source-map": "1.5.0", - "fs-readdir-recursive": "1.0.0", - "glob": "7.1.2", - "lodash": "4.17.4", - "output-file-sync": "1.1.2", - "path-is-absolute": "1.0.1", - "slash": "1.0.0", - "source-map": "0.5.6", - "v8flags": "2.1.1" + "babel-core": "^6.26.0", + "babel-polyfill": "^6.26.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "chokidar": "^1.6.1", + "commander": "^2.11.0", + "convert-source-map": "^1.5.0", + "fs-readdir-recursive": "^1.0.0", + "glob": "^7.1.2", + "lodash": "^4.17.4", + "output-file-sync": "^1.1.2", + "path-is-absolute": "^1.0.1", + "slash": "^1.0.0", + "source-map": "^0.5.6", + "v8flags": "^2.1.1" }, "dependencies": { "babel-runtime": { @@ -163,8 +163,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "chokidar": { @@ -174,15 +174,15 @@ "dev": true, "optional": true, "requires": { - "anymatch": "1.3.0", - "async-each": "1.0.0", - "fsevents": "1.1.2", - "glob-parent": "2.0.0", - "inherits": "2.0.1", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" } }, "commander": { @@ -217,9 +217,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "babel-core": { @@ -228,25 +228,25 @@ "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.0", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.5.0", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.6" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" }, "dependencies": { "babel-code-frame": { @@ -255,9 +255,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "babel-helpers": { @@ -266,8 +266,8 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-messages": { @@ -276,7 +276,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-runtime": { @@ -285,8 +285,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "babel-template": { @@ -295,11 +295,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.4" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, "babel-traverse": { @@ -308,15 +308,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" } }, "babel-types": { @@ -325,10 +325,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, "babylon": { @@ -349,7 +349,7 @@ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -380,7 +380,7 @@ "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", "dev": true, "requires": { - "loose-envify": "1.2.0" + "loose-envify": "^1.0.0" } }, "js-tokens": { @@ -401,7 +401,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "ms": { @@ -442,14 +442,14 @@ "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", "dev": true, "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.4", - "source-map": "0.5.6", - "trim-right": "1.0.1" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.6", + "trim-right": "^1.0.1" }, "dependencies": { "babel-messages": { @@ -458,7 +458,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-runtime": { @@ -467,8 +467,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "babel-types": { @@ -477,10 +477,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, "detect-indent": { @@ -489,7 +489,7 @@ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "jsesc": { @@ -510,7 +510,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "1.0.1" + "is-finite": "^1.0.0" } }, "to-fast-properties": { @@ -527,9 +527,9 @@ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", "dev": true, "requires": { - "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -538,8 +538,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -556,10 +556,10 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -568,8 +568,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -586,10 +586,10 @@ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "dev": true, "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -598,8 +598,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -616,9 +616,9 @@ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -627,8 +627,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -645,11 +645,11 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -658,8 +658,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -676,8 +676,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -686,8 +686,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -704,8 +704,8 @@ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -714,8 +714,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -732,8 +732,8 @@ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -742,8 +742,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -760,9 +760,9 @@ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -771,8 +771,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -789,11 +789,11 @@ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", "dev": true, "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-code-frame": { @@ -802,9 +802,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "babel-helper-function-name": { @@ -813,11 +813,11 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-get-function-arity": { @@ -826,8 +826,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-messages": { @@ -836,7 +836,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-runtime": { @@ -845,8 +845,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "babel-template": { @@ -855,11 +855,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.4" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, "babel-traverse": { @@ -868,15 +868,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" } }, "babel-types": { @@ -885,10 +885,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, "babylon": { @@ -918,7 +918,7 @@ "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", "dev": true, "requires": { - "loose-envify": "1.2.0" + "loose-envify": "^1.0.0" } }, "js-tokens": { @@ -953,12 +953,12 @@ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -967,8 +967,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -985,7 +985,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -994,8 +994,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1012,7 +1012,7 @@ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1021,8 +1021,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1057,9 +1057,9 @@ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1068,8 +1068,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1086,7 +1086,7 @@ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1095,8 +1095,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1113,7 +1113,7 @@ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1122,8 +1122,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1140,11 +1140,11 @@ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -1153,8 +1153,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1171,15 +1171,15 @@ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "dev": true, "requires": { - "babel-helper-define-map": "6.26.0", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1188,8 +1188,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1206,8 +1206,8 @@ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1216,8 +1216,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1234,7 +1234,7 @@ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1243,8 +1243,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1261,8 +1261,8 @@ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1271,8 +1271,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1289,7 +1289,7 @@ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1298,8 +1298,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1316,9 +1316,9 @@ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "dev": true, "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1327,8 +1327,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1345,7 +1345,7 @@ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1354,8 +1354,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1372,9 +1372,9 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1383,8 +1383,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1401,10 +1401,10 @@ "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" }, "dependencies": { "babel-runtime": { @@ -1413,8 +1413,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1431,9 +1431,9 @@ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "dev": true, "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1442,8 +1442,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1460,9 +1460,9 @@ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1471,8 +1471,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1489,8 +1489,8 @@ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "dev": true, "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.26.0" + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1499,8 +1499,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1517,12 +1517,12 @@ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "dev": true, "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1531,8 +1531,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1549,8 +1549,8 @@ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1559,8 +1559,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1577,7 +1577,7 @@ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1586,8 +1586,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1604,9 +1604,9 @@ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "dev": true, "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1615,8 +1615,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1633,7 +1633,7 @@ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1642,8 +1642,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1660,7 +1660,7 @@ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1669,8 +1669,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1687,9 +1687,9 @@ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "dev": true, "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "regexpu-core": "2.0.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" }, "dependencies": { "babel-runtime": { @@ -1698,8 +1698,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1716,9 +1716,9 @@ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", "dev": true, "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", - "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1727,8 +1727,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1745,7 +1745,7 @@ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "dev": true, "requires": { - "regenerator-transform": "0.10.1" + "regenerator-transform": "^0.10.0" } }, "babel-plugin-transform-strict-mode": { @@ -1754,8 +1754,8 @@ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1764,8 +1764,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1782,9 +1782,9 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "core-js": "2.5.1", - "regenerator-runtime": "0.10.5" + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" }, "dependencies": { "babel-runtime": { @@ -1793,8 +1793,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { "regenerator-runtime": { @@ -1825,36 +1825,36 @@ "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.7.0", - "invariant": "2.2.2", - "semver": "5.3.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^2.1.2", + "invariant": "^2.2.2", + "semver": "^5.3.0" } }, "babel-register": { @@ -1863,13 +1863,13 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "6.26.0", - "babel-runtime": "6.26.0", - "core-js": "2.5.1", - "home-or-tmp": "2.0.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "source-map-support": "0.4.18" + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" }, "dependencies": { "babel-runtime": { @@ -1878,8 +1878,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1894,8 +1894,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.1" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "regenerator-runtime": { @@ -1910,7 +1910,7 @@ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "^0.5.6" } } } @@ -1921,8 +1921,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { "regenerator-runtime": { @@ -1939,11 +1939,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.4" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -1952,8 +1952,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -1970,15 +1970,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -1987,8 +1987,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -2005,10 +2005,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" }, "dependencies": { "babel-runtime": { @@ -2017,8 +2017,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -2047,7 +2047,7 @@ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "binary-extensions": { @@ -2056,11 +2056,6 @@ "integrity": "sha1-5uIFfyzfsXrUBjSchrce+AaaJfU=", "dev": true }, - "bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=" - }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", @@ -2072,7 +2067,7 @@ "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", "dev": true, "requires": { - "balanced-match": "0.4.2", + "balanced-match": "^0.4.1", "concat-map": "0.0.1" } }, @@ -2082,9 +2077,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "browserslist": { @@ -2093,8 +2088,8 @@ "integrity": "sha512-s34mrlczJsfbJu//mz/m9zlOy/S6tiP6El1u8iC1gTfEnzKXvxo8RAoCxS/MmojB7rd7bnfYzvKQNHykWaUWWw==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000758", - "electron-to-chromium": "1.3.27" + "caniuse-lite": "^1.0.30000757", + "electron-to-chromium": "^1.3.27" } }, "buffer-shims": { @@ -2114,7 +2109,7 @@ "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", "requires": { - "long": "3.2.0" + "long": "~3" }, "dependencies": { "long": { @@ -2140,7 +2135,7 @@ "resolved": "https://registry.npmjs.org/cassandra-driver/-/cassandra-driver-3.3.0.tgz", "integrity": "sha1-ek0no2Tjm9El5LRWTTDDYUXXY14=", "requires": { - "long": "2.4.0" + "long": "^2.2.0" } }, "chalk": { @@ -2149,11 +2144,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "chokidar": { @@ -2162,15 +2157,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "1.3.0", - "async-each": "1.0.0", - "fsevents": "1.1.2", - "glob-parent": "2.0.0", - "inherits": "2.0.1", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.0", - "readdirp": "2.1.0" + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" } }, "cliui": { @@ -2178,9 +2173,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, "co": { @@ -2199,7 +2194,7 @@ "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "^1.1.1" } }, "color-name": { @@ -2223,7 +2218,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "concat-map": { @@ -2269,17 +2264,17 @@ "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "chokidar": "1.7.0", - "duplexer": "0.1.1", - "glob": "7.1.2", - "glob2base": "0.0.12", - "minimatch": "3.0.3", - "mkdirp": "0.5.1", - "resolve": "1.5.0", - "safe-buffer": "5.1.1", - "shell-quote": "1.6.1", - "subarg": "1.0.0" + "babel-runtime": "^6.9.2", + "chokidar": "^1.6.0", + "duplexer": "^0.1.1", + "glob": "^7.0.5", + "glob2base": "^0.0.12", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "resolve": "^1.1.7", + "safe-buffer": "^5.0.1", + "shell-quote": "^1.6.1", + "subarg": "^1.0.0" } }, "cross-spawn": { @@ -2288,9 +2283,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "cycle": { @@ -2303,16 +2298,7 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "assert-plus": "1.0.0" - } - }, - "deasync": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.9.tgz", - "integrity": "sha1-9Y3Un6YxEMdL6oQFqQqCi+JtOiQ=", - "requires": { - "bindings": "1.2.1", - "nan": "2.4.0" + "assert-plus": "^1.0.0" } }, "debug": { @@ -2335,8 +2321,8 @@ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "dev": true, "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.11" + "foreach": "^2.0.5", + "object-keys": "^1.0.8" } }, "delayed-stream": { @@ -2366,7 +2352,7 @@ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "electron-to-chromium": { @@ -2381,7 +2367,7 @@ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "es-abstract": { @@ -2390,11 +2376,11 @@ "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", "dev": true, "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" } }, "es-to-primitive": { @@ -2403,9 +2389,9 @@ "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", "dev": true, "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" } }, "escape-string-regexp": { @@ -2432,13 +2418,13 @@ "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { - "duplexer": "0.1.1", - "from": "0.1.7", - "map-stream": "0.1.0", + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" } }, "expand-brackets": { @@ -2447,7 +2433,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "expand-range": { @@ -2456,7 +2442,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.3" + "fill-range": "^2.1.0" } }, "extglob": { @@ -2465,7 +2451,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "extsprintf": { @@ -2500,11 +2486,11 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.5", - "repeat-element": "1.1.2", - "repeat-string": "1.5.4" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "find-index": { @@ -2525,7 +2511,7 @@ "integrity": "sha1-AUm0GjkIjHUV9R6+HBOG1F+TUHI=", "dev": true, "requires": { - "for-in": "0.1.5" + "for-in": "^0.1.5" } }, "foreach": { @@ -2563,8 +2549,8 @@ "dev": true, "optional": true, "requires": { - "nan": "2.4.0", - "node-pre-gyp": "0.6.36" + "nan": "^2.3.0", + "node-pre-gyp": "^0.6.36" }, "dependencies": { "abbrev": { @@ -2579,14 +2565,15 @@ "dev": true, "optional": true, "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.1.1", @@ -2600,8 +2587,8 @@ "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "asn1": { @@ -2645,23 +2632,25 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "block-stream": { "version": "0.0.9", "bundled": true, "dev": true, + "optional": true, "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "boom": { "version": "2.10.1", "bundled": true, "dev": true, + "optional": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "brace-expansion": { @@ -2669,14 +2658,15 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "0.4.2", + "balanced-match": "^0.4.1", "concat-map": "0.0.1" } }, "buffer-shims": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "caseless": { "version": "0.12.0", @@ -2693,14 +2683,16 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "combined-stream": { "version": "1.0.5", "bundled": true, "dev": true, + "optional": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "concat-map": { @@ -2711,12 +2703,14 @@ "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "cryptiles": { "version": "2.0.5", @@ -2724,7 +2718,7 @@ "dev": true, "optional": true, "requires": { - "boom": "2.10.1" + "boom": "2.x.x" } }, "dashdash": { @@ -2733,7 +2727,7 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -2762,7 +2756,8 @@ "delayed-stream": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "delegates": { "version": "1.0.0", @@ -2776,7 +2771,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "extend": { @@ -2788,7 +2783,8 @@ "extsprintf": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "forever-agent": { "version": "0.6.1", @@ -2816,11 +2812,12 @@ "version": "1.0.11", "bundled": true, "dev": true, + "optional": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "fstream-ignore": { @@ -2829,9 +2826,9 @@ "dev": true, "optional": true, "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" } }, "gauge": { @@ -2840,14 +2837,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "getpass": { @@ -2856,7 +2853,7 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -2872,18 +2869,19 @@ "bundled": true, "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "graceful-fs": { "version": "4.1.11", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "har-schema": { "version": "1.0.5", @@ -2897,8 +2895,8 @@ "dev": true, "optional": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "^4.9.1", + "har-schema": "^1.0.5" } }, "has-unicode": { @@ -2913,16 +2911,17 @@ "dev": true, "optional": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "hoek": { "version": "2.16.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "http-signature": { "version": "1.1.1", @@ -2930,9 +2929,9 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { @@ -2940,8 +2939,8 @@ "bundled": true, "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -2959,6 +2958,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "1.0.1" } @@ -2972,7 +2972,8 @@ "isarray": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "isstream": { "version": "0.1.2", @@ -2986,7 +2987,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "jsbn": { @@ -3007,7 +3008,7 @@ "dev": true, "optional": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stringify-safe": { @@ -3045,12 +3046,14 @@ "mime-db": { "version": "1.27.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "mime-types": { "version": "2.1.15", "bundled": true, "dev": true, + "optional": true, "requires": { "mime-db": "1.27.0" } @@ -3066,12 +3069,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "mkdirp": { "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3088,15 +3093,15 @@ "dev": true, "optional": true, "requires": { - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "request": "^2.81.0", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^2.2.1", + "tar-pack": "^3.4.0" } }, "nopt": { @@ -3105,8 +3110,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npmlog": { @@ -3115,16 +3120,17 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "oauth-sign": { "version": "0.8.2", @@ -3143,7 +3149,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -3164,8 +3170,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -3182,7 +3188,8 @@ "process-nextick-args": { "version": "1.0.7", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "punycode": { "version": "1.4.1", @@ -3202,10 +3209,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -3220,14 +3227,15 @@ "version": "2.2.9", "bundled": true, "dev": true, + "optional": true, "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" } }, "request": { @@ -3236,28 +3244,28 @@ "dev": true, "optional": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" } }, "rimraf": { @@ -3265,13 +3273,14 @@ "bundled": true, "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { "version": "5.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "semver": { "version": "5.3.0", @@ -3297,7 +3306,7 @@ "dev": true, "optional": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "sshpk": { @@ -3306,15 +3315,15 @@ "dev": true, "optional": true, "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jodid25519": "^1.0.0", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" }, "dependencies": { "assert-plus": { @@ -3329,18 +3338,20 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "stringstream": { @@ -3353,8 +3364,9 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -3367,10 +3379,11 @@ "version": "2.2.1", "bundled": true, "dev": true, + "optional": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-pack": { @@ -3379,14 +3392,14 @@ "dev": true, "optional": true, "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" + "debug": "^2.2.0", + "fstream": "^1.0.10", + "fstream-ignore": "^1.0.5", + "once": "^1.3.3", + "readable-stream": "^2.1.4", + "rimraf": "^2.5.1", + "tar": "^2.2.1", + "uid-number": "^0.0.6" } }, "tough-cookie": { @@ -3395,7 +3408,7 @@ "dev": true, "optional": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { @@ -3404,7 +3417,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -3422,7 +3435,8 @@ "util-deprecate": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "uuid": { "version": "3.0.1", @@ -3445,7 +3459,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { @@ -3466,7 +3480,7 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -3475,12 +3489,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.5", - "inherits": "2.0.1", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "dependencies": { "balanced-match": { @@ -3495,7 +3509,7 @@ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -3505,7 +3519,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } } } @@ -3516,8 +3530,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" } }, "glob-parent": { @@ -3526,7 +3540,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "glob2base": { @@ -3535,7 +3549,7 @@ "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", "dev": true, "requires": { - "find-index": "0.1.1" + "find-index": "^0.1.1" } }, "globals": { @@ -3555,11 +3569,11 @@ "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.7.1.tgz", "integrity": "sha512-lMgjZUzJx09VL5iCfs7rFagE5htikdv/9VzX/ji3zuwlzAhijqcU47bi5N5lbVw/UB2fxneeYg8sBTfQfd0c4A==", "requires": { - "arguejs": "0.2.3", - "lodash": "4.17.4", - "nan": "2.4.0", - "node-pre-gyp": "0.6.39", - "protobufjs": "5.0.2" + "arguejs": "^0.2.3", + "lodash": "^4.15.0", + "nan": "^2.0.0", + "node-pre-gyp": "^0.6.39", + "protobufjs": "^5.0.0" }, "dependencies": { "abbrev": { @@ -3570,8 +3584,8 @@ "version": "4.11.8", "bundled": true, "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, "ansi-regex": { @@ -3586,8 +3600,8 @@ "version": "1.1.4", "bundled": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.3" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "asn1": { @@ -3619,28 +3633,28 @@ "bundled": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "block-stream": { "version": "0.0.9", "bundled": true, "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "boom": { "version": "2.10.1", "bundled": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "brace-expansion": { "version": "1.1.8", "bundled": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -3660,7 +3674,7 @@ "version": "1.0.5", "bundled": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "concat-map": { @@ -3679,14 +3693,14 @@ "version": "2.0.5", "bundled": true, "requires": { - "boom": "2.10.1" + "boom": "2.x.x" } }, "dashdash": { "version": "1.14.1", "bundled": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -3723,7 +3737,7 @@ "bundled": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "extend": { @@ -3742,9 +3756,9 @@ "version": "2.1.4", "bundled": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" } }, "fs.realpath": { @@ -3755,40 +3769,40 @@ "version": "1.0.11", "bundled": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "fstream-ignore": { "version": "1.0.5", "bundled": true, "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" } }, "gauge": { "version": "2.7.4", "bundled": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "getpass": { "version": "0.1.7", "bundled": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -3801,12 +3815,12 @@ "version": "7.1.1", "bundled": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "graceful-fs": { @@ -3821,8 +3835,8 @@ "version": "4.2.1", "bundled": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "^4.9.1", + "har-schema": "^1.0.5" } }, "has-unicode": { @@ -3833,10 +3847,10 @@ "version": "3.1.3", "bundled": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "hoek": { @@ -3847,17 +3861,17 @@ "version": "1.1.1", "bundled": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { "version": "1.0.6", "bundled": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -3872,7 +3886,7 @@ "version": "1.0.0", "bundled": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-typedarray": { @@ -3900,7 +3914,7 @@ "version": "1.0.1", "bundled": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stringify-safe": { @@ -3935,14 +3949,14 @@ "version": "2.1.17", "bundled": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "~1.30.0" } }, "minimatch": { "version": "3.0.4", "bundled": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -3964,25 +3978,25 @@ "version": "0.6.39", "bundled": true, "requires": { - "detect-libc": "1.0.2", + "detect-libc": "^1.0.2", "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.2", - "rc": "1.2.2", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.0.2", + "rc": "^1.1.7", "request": "2.81.0", - "rimraf": "2.6.2", - "semver": "5.4.1", - "tar": "2.2.1", - "tar-pack": "3.4.1" + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^2.2.1", + "tar-pack": "^3.4.0" }, "dependencies": { "nopt": { "version": "4.0.1", "bundled": true, "requires": { - "abbrev": "1.0.9", - "osenv": "0.1.4" + "abbrev": "1", + "osenv": "^0.1.4" } } } @@ -3991,10 +4005,10 @@ "version": "4.1.2", "bundled": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -4013,7 +4027,7 @@ "version": "1.4.0", "bundled": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -4028,8 +4042,8 @@ "version": "0.1.4", "bundled": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -4056,10 +4070,10 @@ "version": "1.2.2", "bundled": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -4072,48 +4086,48 @@ "version": "2.3.3", "bundled": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" } }, "request": { "version": "2.81.0", "bundled": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" } }, "rimraf": { "version": "2.6.2", "bundled": true, "requires": { - "glob": "7.1.1" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -4136,21 +4150,21 @@ "version": "1.0.9", "bundled": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "sshpk": { "version": "1.13.1", "bundled": true, "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" }, "dependencies": { "assert-plus": { @@ -4163,16 +4177,16 @@ "version": "1.0.2", "bundled": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.0.3", "bundled": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "stringstream": { @@ -4183,7 +4197,7 @@ "version": "3.0.1", "bundled": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -4194,37 +4208,37 @@ "version": "2.2.1", "bundled": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-pack": { "version": "3.4.1", "bundled": true, "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.3.3", - "rimraf": "2.6.2", - "tar": "2.2.1", - "uid-number": "0.0.6" + "debug": "^2.2.0", + "fstream": "^1.0.10", + "fstream-ignore": "^1.0.5", + "once": "^1.3.3", + "readable-stream": "^2.1.4", + "rimraf": "^2.5.1", + "tar": "^2.2.1", + "uid-number": "^0.0.6" } }, "tough-cookie": { "version": "2.3.3", "bundled": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { "version": "0.6.0", "bundled": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -4248,9 +4262,9 @@ "version": "1.10.0", "bundled": true, "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" }, "dependencies": { "assert-plus": { @@ -4263,7 +4277,7 @@ "version": "1.1.2", "bundled": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { @@ -4278,7 +4292,7 @@ "integrity": "sha1-NvKg0ayVZ2b7s2hfQBOKWCj/90k=", "dev": true, "requires": { - "node-pre-gyp": "0.6.38" + "node-pre-gyp": "^0.6.38" }, "dependencies": { "abbrev": { @@ -4291,8 +4305,8 @@ "bundled": true, "dev": true, "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, "ansi-regex": { @@ -4310,8 +4324,8 @@ "bundled": true, "dev": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.3" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "asn1": { @@ -4350,7 +4364,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "block-stream": { @@ -4358,7 +4372,7 @@ "bundled": true, "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "boom": { @@ -4366,7 +4380,7 @@ "bundled": true, "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "brace-expansion": { @@ -4374,7 +4388,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -4398,7 +4412,7 @@ "bundled": true, "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "concat-map": { @@ -4421,7 +4435,7 @@ "bundled": true, "dev": true, "requires": { - "boom": "2.10.1" + "boom": "2.x.x" } }, "dashdash": { @@ -4429,7 +4443,7 @@ "bundled": true, "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -4468,7 +4482,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "extend": { @@ -4491,9 +4505,9 @@ "bundled": true, "dev": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" } }, "fs.realpath": { @@ -4506,10 +4520,10 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "fstream-ignore": { @@ -4517,9 +4531,9 @@ "bundled": true, "dev": true, "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" } }, "gauge": { @@ -4527,14 +4541,14 @@ "bundled": true, "dev": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "getpass": { @@ -4542,7 +4556,7 @@ "bundled": true, "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -4557,12 +4571,12 @@ "bundled": true, "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "graceful-fs": { @@ -4580,8 +4594,8 @@ "bundled": true, "dev": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "^4.9.1", + "har-schema": "^1.0.5" } }, "has-unicode": { @@ -4594,10 +4608,10 @@ "bundled": true, "dev": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "hoek": { @@ -4610,9 +4624,9 @@ "bundled": true, "dev": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { @@ -4620,8 +4634,8 @@ "bundled": true, "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -4639,7 +4653,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-typedarray": { @@ -4673,7 +4687,7 @@ "bundled": true, "dev": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stringify-safe": { @@ -4714,7 +4728,7 @@ "bundled": true, "dev": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "~1.30.0" } }, "minimatch": { @@ -4722,7 +4736,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -4749,15 +4763,15 @@ "dev": true, "requires": { "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.2", - "rc": "1.2.1", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.0.2", + "rc": "^1.1.7", "request": "2.81.0", - "rimraf": "2.6.2", - "semver": "5.4.1", - "tar": "2.2.1", - "tar-pack": "3.4.0" + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^2.2.1", + "tar-pack": "^3.4.0" } }, "nopt": { @@ -4765,8 +4779,8 @@ "bundled": true, "dev": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.4" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npmlog": { @@ -4774,10 +4788,10 @@ "bundled": true, "dev": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -4800,7 +4814,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -4818,8 +4832,8 @@ "bundled": true, "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -4852,10 +4866,10 @@ "bundled": true, "dev": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -4870,13 +4884,13 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" } }, "request": { @@ -4884,28 +4898,28 @@ "bundled": true, "dev": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" } }, "rimraf": { @@ -4913,7 +4927,7 @@ "bundled": true, "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -4941,7 +4955,7 @@ "bundled": true, "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "sshpk": { @@ -4949,14 +4963,14 @@ "bundled": true, "dev": true, "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" }, "dependencies": { "assert-plus": { @@ -4971,9 +4985,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -4981,7 +4995,7 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "stringstream": { @@ -4994,7 +5008,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -5007,9 +5021,9 @@ "bundled": true, "dev": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-pack": { @@ -5017,14 +5031,14 @@ "bundled": true, "dev": true, "requires": { - "debug": "2.6.9", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.3.3", - "rimraf": "2.6.2", - "tar": "2.2.1", - "uid-number": "0.0.6" + "debug": "^2.2.0", + "fstream": "^1.0.10", + "fstream-ignore": "^1.0.5", + "once": "^1.3.3", + "readable-stream": "^2.1.4", + "rimraf": "^2.5.1", + "tar": "^2.2.1", + "uid-number": "^0.0.6" } }, "tough-cookie": { @@ -5032,7 +5046,7 @@ "bundled": true, "dev": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { @@ -5040,7 +5054,7 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -5069,9 +5083,9 @@ "bundled": true, "dev": true, "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" }, "dependencies": { "assert-plus": { @@ -5086,7 +5100,7 @@ "bundled": true, "dev": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { @@ -5106,8 +5120,8 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "5.3.0", - "har-schema": "2.0.0" + "ajv": "^5.1.0", + "har-schema": "^2.0.0" } }, "has": { @@ -5116,7 +5130,7 @@ "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "dev": true, "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.0.2" } }, "has-ansi": { @@ -5125,7 +5139,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "2.0.0" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -5145,9 +5159,9 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { @@ -5155,8 +5169,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz", "integrity": "sha1-2zIEzVqd4ubNiQuFxuL2a89PYgo=", "requires": { - "once": "1.3.3", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -5170,7 +5184,7 @@ "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", "dev": true, "requires": { - "loose-envify": "1.2.0" + "loose-envify": "^1.0.0" } }, "invert-kv": { @@ -5190,7 +5204,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.5.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -5205,7 +5219,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-callable": { @@ -5232,7 +5246,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -5253,7 +5267,7 @@ "integrity": "sha1-ZDhgPq6+J5OUj/SkJi7I2z1iWXs=", "dev": true, "requires": { - "number-is-nan": "1.0.0" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -5261,7 +5275,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.0" + "number-is-nan": "^1.0.0" } }, "is-glob": { @@ -5270,7 +5284,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-number": { @@ -5279,7 +5293,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "3.0.4" + "kind-of": "^3.0.2" } }, "is-posix-bracket": { @@ -5300,7 +5314,7 @@ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, "requires": { - "has": "1.0.1" + "has": "^1.0.1" } }, "is-symbol": { @@ -5401,7 +5415,7 @@ "integrity": "sha1-e47PGKThf4Jp1ztQHJ8jLJaIenQ=", "dev": true, "requires": { - "is-buffer": "1.1.4" + "is-buffer": "^1.0.2" } }, "lcid": { @@ -5409,7 +5423,7 @@ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "load-json-file": { @@ -5418,10 +5432,10 @@ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { - "graceful-fs": "4.1.5", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, "lodash": { @@ -5445,7 +5459,7 @@ "integrity": "sha1-aaZarT3lQs9O4PT+dOjjPHCcyw8=", "dev": true, "requires": { - "js-tokens": "1.0.3" + "js-tokens": "^1.0.1" }, "dependencies": { "js-tokens": { @@ -5462,8 +5476,8 @@ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "map-stream": { @@ -5478,7 +5492,7 @@ "integrity": "sha1-Jz/3d6tg/sWZsRY1UlUoLMosUMI=", "dev": true, "requires": { - "readable-stream": "1.0.34" + "readable-stream": "~1.0.2" }, "dependencies": { "isarray": { @@ -5493,10 +5507,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.1", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } } } @@ -5507,19 +5521,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.0", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.0.4", - "normalize-path": "2.0.1", - "object.omit": "2.0.0", - "parse-glob": "3.0.4", - "regex-cache": "0.4.3" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, "minimatch": { @@ -5528,7 +5542,7 @@ "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", "dev": true, "requires": { - "brace-expansion": "1.1.6" + "brace-expansion": "^1.0.0" } }, "minimist": { @@ -5562,27 +5576,16 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz", "integrity": "sha1-+zxZ1F/k7/4hXwuJD4rfbrMtIjI=" }, - "node-etcd": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-etcd/-/node-etcd-5.1.0.tgz", - "integrity": "sha1-0CqlfBJ0OHTfFjuLD+/xHMd/B7A=", - "requires": { - "deasync": "0.1.9", - "request": "2.83.0", - "underscore": "1.8.2", - "url-parse": "1.0.5" - } - }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.3.0", - "validate-npm-package-license": "3.0.1" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { @@ -5597,15 +5600,15 @@ "integrity": "sha512-qrmqqaJa+REbzUTIL/mHfTdgwz+gL1xUezY/ueyLa7GISZ4T3h0CH8D2r6AaZdCYN2unu7PzspP0ofpXla1ftg==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "chalk": "2.3.0", - "cross-spawn": "5.1.0", - "memory-streams": "0.1.2", - "minimatch": "3.0.4", - "ps-tree": "1.1.0", - "read-pkg": "2.0.0", - "shell-quote": "1.6.1", - "string.prototype.padend": "3.0.0" + "ansi-styles": "^3.2.0", + "chalk": "^2.1.0", + "cross-spawn": "^5.1.0", + "memory-streams": "^0.1.2", + "minimatch": "^3.0.4", + "ps-tree": "^1.1.0", + "read-pkg": "^2.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" }, "dependencies": { "ansi-styles": { @@ -5614,7 +5617,7 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.0" + "color-convert": "^1.9.0" } }, "balanced-match": { @@ -5629,7 +5632,7 @@ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -5639,9 +5642,9 @@ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "ansi-styles": "^3.1.0", + "escape-string-regexp": "^1.0.5", + "supports-color": "^4.0.0" } }, "minimatch": { @@ -5650,7 +5653,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "supports-color": { @@ -5659,7 +5662,7 @@ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } } } @@ -5692,8 +5695,8 @@ "integrity": "sha1-hoWXMz1U5gZilAu0WGBd1q4S/pQ=", "dev": true, "requires": { - "for-own": "0.1.4", - "is-extendable": "0.1.1" + "for-own": "^0.1.3", + "is-extendable": "^0.1.1" } }, "once": { @@ -5701,7 +5704,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "optjs": { @@ -5720,7 +5723,7 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { - "lcid": "1.0.0" + "lcid": "^1.0.0" } }, "os-tmpdir": { @@ -5735,9 +5738,9 @@ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { - "graceful-fs": "4.1.5", - "mkdirp": "0.5.1", - "object-assign": "4.1.0" + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" } }, "parse-glob": { @@ -5746,10 +5749,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.2", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-json": { @@ -5758,7 +5761,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-is-absolute": { @@ -5778,7 +5781,7 @@ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { - "pify": "2.3.0" + "pify": "^2.0.0" } }, "pause-stream": { @@ -5787,7 +5790,7 @@ "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { - "through": "2.3.8" + "through": "~2.3" } }, "performance-now": { @@ -5824,10 +5827,10 @@ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.2.tgz", "integrity": "sha1-WXSNfc8D0tsiwT2p/rAk4Wq4DJE=", "requires": { - "ascli": "1.0.1", - "bytebuffer": "5.0.1", - "glob": "7.1.2", - "yargs": "3.32.0" + "ascli": "~1", + "bytebuffer": "~5", + "glob": "^7.0.5", + "yargs": "^3.10.0" }, "dependencies": { "balanced-match": { @@ -5840,7 +5843,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -5849,12 +5852,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.5", - "inherits": "2.0.1", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "minimatch": { @@ -5862,7 +5865,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } } } @@ -5873,7 +5876,7 @@ "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", "dev": true, "requires": { - "event-stream": "3.3.4" + "event-stream": "~3.3.0" } }, "pseudomap": { @@ -5892,19 +5895,14 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, - "querystringify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz", - "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=" - }, "randomatic": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.5.tgz", "integrity": "sha1-Xp718tVzxnvSuBJK6QtRVuRXhAs=", "dev": true, "requires": { - "is-number": "2.1.0", - "kind-of": "3.0.4" + "is-number": "^2.0.2", + "kind-of": "^3.0.2" } }, "read-pkg": { @@ -5913,9 +5911,9 @@ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "readable-stream": { @@ -5924,13 +5922,13 @@ "integrity": "sha1-cLl5HG/LhIDbRL0VWg9rtY8XJGg=", "dev": true, "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.1", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -5939,10 +5937,10 @@ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "dev": true, "requires": { - "graceful-fs": "4.1.5", - "minimatch": "3.0.3", - "readable-stream": "2.1.4", - "set-immediate-shim": "1.0.1" + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" } }, "redeyed": { @@ -5951,7 +5949,7 @@ "integrity": "sha1-6WwZO0DAgWsArshCaY5hGF5VSYo=", "optional": true, "requires": { - "esprima": "3.0.0" + "esprima": "~3.0.0" } }, "regenerate": { @@ -5971,9 +5969,9 @@ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "private": "0.1.8" + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" }, "dependencies": { "babel-runtime": { @@ -5982,8 +5980,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.11.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "regenerator-runtime": { @@ -6000,8 +5998,8 @@ "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", "dev": true, "requires": { - "is-equal-shallow": "0.1.3", - "is-primitive": "2.0.0" + "is-equal-shallow": "^0.1.3", + "is-primitive": "^2.0.0" } }, "regexpu-core": { @@ -6010,9 +6008,9 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "1.3.3", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "regjsgen": { @@ -6027,7 +6025,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } }, "repeat-element": { @@ -6047,28 +6045,28 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" }, "dependencies": { "boom": { @@ -6076,7 +6074,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "requires": { - "hoek": "4.2.0" + "hoek": "4.x.x" } }, "caseless": { @@ -6089,7 +6087,7 @@ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "requires": { - "boom": "5.2.0" + "boom": "5.x.x" }, "dependencies": { "boom": { @@ -6097,7 +6095,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "requires": { - "hoek": "4.2.0" + "hoek": "4.x.x" } } } @@ -6112,9 +6110,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" } }, "hawk": { @@ -6122,10 +6120,10 @@ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.1.0" + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" } }, "hoek": { @@ -6143,7 +6141,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", "requires": { - "mime-db": "1.30.0" + "mime-db": "~1.30.0" } }, "sntp": { @@ -6151,7 +6149,7 @@ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "requires": { - "hoek": "4.2.0" + "hoek": "4.x.x" } }, "tough-cookie": { @@ -6159,7 +6157,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { @@ -6167,7 +6165,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "uuid": { @@ -6182,10 +6180,10 @@ "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", "requires": { - "bluebird": "3.5.1", + "bluebird": "^3.5.0", "request-promise-core": "1.1.1", - "stealthy-require": "1.1.1", - "tough-cookie": "2.3.3" + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" }, "dependencies": { "bluebird": { @@ -6198,7 +6196,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } } } @@ -6208,21 +6206,16 @@ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", "requires": { - "lodash": "4.17.4" + "lodash": "^4.13.1" } }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, "resolve": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "dev": true, "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, "rimraf": { @@ -6231,7 +6224,7 @@ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -6257,7 +6250,7 @@ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -6272,10 +6265,10 @@ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true, "requires": { - "array-filter": "0.0.1", - "array-map": "0.0.0", - "array-reduce": "0.0.0", - "jsonify": "0.0.0" + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" } }, "slash": { @@ -6296,7 +6289,7 @@ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-license-ids": "^1.0.2" } }, "spdx-expression-parse": { @@ -6317,7 +6310,7 @@ "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { - "through": "2.3.8" + "through": "2" } }, "sshpk": { @@ -6325,14 +6318,14 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" } }, "stack-trace": { @@ -6351,7 +6344,7 @@ "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { - "duplexer": "0.1.1" + "duplexer": "~0.1.1" } }, "string-width": { @@ -6359,9 +6352,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string.prototype.padend": { @@ -6370,9 +6363,9 @@ "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", "dev": true, "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.9.0", - "function-bind": "1.1.1" + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" } }, "string_decoder": { @@ -6391,7 +6384,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "2.0.0" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -6406,7 +6399,7 @@ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.1.0" }, "dependencies": { "minimist": { @@ -6446,20 +6439,6 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "optional": true }, - "underscore": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.2.tgz", - "integrity": "sha1-ZN8utZCJnelQeC83NRkLpC6/MR0=" - }, - "url-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz", - "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=", - "requires": { - "querystringify": "0.0.4", - "requires-port": "1.0.0" - } - }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", @@ -6478,7 +6457,7 @@ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { - "user-home": "1.1.1" + "user-home": "^1.1.1" } }, "validate-npm-package-license": { @@ -6487,8 +6466,8 @@ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" } }, "validator": { @@ -6502,8 +6481,8 @@ "integrity": "sha1-GR2p/p3EzWjQ0USY1OKpEP9OZRY=", "optional": true, "requires": { - "redeyed": "1.0.1", - "through": "2.3.8" + "redeyed": "~1.0.1", + "through": "~2.3.4" } }, "verror": { @@ -6511,9 +6490,9 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "which": { @@ -6522,7 +6501,7 @@ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "window-size": { @@ -6535,12 +6514,12 @@ "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.0.tgz", "integrity": "sha1-gIBQuT1SZh7Z+2wms/DIJnCLCu4=", "requires": { - "async": "1.0.0", - "colors": "1.0.3", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "stack-trace": "0.0.10" + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" }, "dependencies": { "async": { @@ -6555,8 +6534,8 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" } }, "wrappy": { @@ -6580,13 +6559,13 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "requires": { - "camelcase": "2.1.1", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "os-locale": "1.4.0", - "string-width": "1.0.2", - "window-size": "0.1.4", - "y18n": "3.2.1" + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" } }, "yargs-parser": { @@ -6594,7 +6573,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" }, "dependencies": { "camelcase": { diff --git a/package.json b/package.json index e99455f..2dbf8e6 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "dotenv": "^4.0.0", "grpc": "^1.7.1", "moment": "^2.19.1", - "node-etcd": "^5.1.0", "regenerator-runtime": "^0.11.0", "request": "^2.83.0", "request-promise": "^4.2.2", diff --git a/src/common/cassandra.js b/src/common/cassandra.js index 628c503..3c345bf 100644 --- a/src/common/cassandra.js +++ b/src/common/cassandra.js @@ -1,6 +1,6 @@ import Promise from 'bluebird'; import { Client, types as CassandraTypes } from 'cassandra-driver'; -import { lookupServiceAsync } from './service-discovery'; +import { lookupService } from './service-discovery'; import { withRetries } from './with-retries'; import { logger } from './logging'; @@ -9,12 +9,10 @@ import { logger } from './logging'; * specified. Returns a Promise of the created client. */ function createClientAsync(keyspace, queryOptions) { - return lookupServiceAsync('cassandra') - .then(contactPoints => { - let client = new Client({ contactPoints, keyspace, queryOptions }); - Promise.promisifyAll(client); // This creates "Async" versions of methods that return promises - return client; - }); + let client = new Client({ 'contactPoints': [lookupService('cassandra')], keyspace, queryOptions }); + Promise.promisifyAll(client); // This creates "Async" versions of methods that return promises + + return new Promise (function(resolve, reject){resolve(client)}); } // A singleton client instance to be reused throughout the application diff --git a/src/common/config.js b/src/common/config.js index 7ecd488..1c12ebe 100644 --- a/src/common/config.js +++ b/src/common/config.js @@ -75,22 +75,6 @@ const conf = convict({ env: 'NODE_APP_INSTANCE' }, - etcd: { - ip: { - doc: 'The IP address for etcd to do service discovery', - format: 'docker-fallback-ip', - default: '${dockerIp}', - env: 'KILLRVIDEO_ETCD_IP' - }, - - port: { - doc: 'The port for etcd to do service discovery', - format: 'port', - default: 2379, - env: 'KILLRVIDEO_ETCD_PORT' - } - }, - listen: { ip: { doc: 'The IP address for Grpc services to listen on', @@ -110,8 +94,8 @@ const conf = convict({ broadcast: { ip: { doc: 'The IP address to broadcast for Grpc services (i.e. register with service discovery)', - format: 'docker-fallback-ip', - default: '${hostIp}', + format: String, + default: 'backend', env: 'KILLRVIDEO_BROADCAST_IP' }, diff --git a/src/common/service-discovery.js b/src/common/service-discovery.js index 18947ca..53bafcb 100644 --- a/src/common/service-discovery.js +++ b/src/common/service-discovery.js @@ -1,68 +1,32 @@ -import Promise from 'bluebird'; -import Etcd from 'node-etcd'; import { logger } from './logging'; import config from './config'; -// Reuse a singleton instance of the etcd client for all operations -let etcdClient = null; - -/** - * Get the etcd client. - */ -function getEtcdClient() { - if (etcdClient !== null) { - return etcdClient; - } - - let etcdConfig = config.get('etcd'); - logger.log('debug', `Using etcd at ${etcdConfig.ip}:${etcdConfig.port} for service discovery`); - - let client = new Etcd(`http://${etcdConfig.ip}:${etcdConfig.port}`); - Promise.promisifyAll(client); - etcdClient = client; - return etcdClient; -} +let registry = { + 'dse-search': 'dse:8983', + 'web': 'web:3000', + 'cassandra': 'dse:9042' +}; /** - * Looks up a service by name. Returns a Promise that resolves to an array of host:port string values. + * Looks up a service by name. Returns host:port string value. */ -export function lookupServiceAsync(serviceName) { - return Promise.try(getEtcdClient) - .then(client => { - return client.getAsync(`/killrvideo/services/${serviceName}`); - }) - .then(response => { - return response.node.nodes.map(node => node.value); - }) - .tap(values => { - logger.log('debug', `Found service ${serviceName} at ${JSON.stringify(values)}`); - }); +export function lookupService(serviceName) { + logger.log('debug', `Found service ${serviceName} at ${registry[serviceName]}`); + return registry[serviceName]; }; /** * Registers a service at the host and port specified. */ -export function registerServiceAsync(serviceName, uniqueId, hostAndPort) { - let key = `/killrvideo/services/${serviceName}/${uniqueId}`; - return Promise.try(getEtcdClient) - .then(client => { - return client.setAsync(key, hostAndPort); - }) - .tap(() => { - logger.log('debug', `Registered service ${serviceName}, instance ${uniqueId} at ${hostAndPort}`); - }); +export function registerService(serviceName, hostAndPort) { + registry[serviceName] = hostAndPort; + logger.log('debug', `Registered service ${serviceName} at ${hostAndPort}`); }; /** * Removes a service from the registry. */ -export function removeServiceAsync(serviceName, uniqueId) { - let key = `/killrvideo/services/${serviceName}/${uniqueId}`; - return Promise.try(getEtcdClient) - .then(client => { - return client.delAsync(key); - }) - .tap(() => { - logger.log('debug', `Removed service ${serviceName}, instance ${uniqueId}`); - }); +export function removeService(serviceName) { + delete registry[serviceName]; + logger.log('debug', `Removed service ${serviceName}`); }; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 19d1cb2..c106fc0 100644 --- a/src/index.js +++ b/src/index.js @@ -7,7 +7,7 @@ import Promise from 'bluebird'; import config from './common/config'; import { initCassandraAsync } from './common/cassandra'; import { logger, setLoggingLevel } from './common/logging'; -import { lookupServiceAsync } from './common/service-discovery'; +import { lookupService } from './common/service-discovery'; import { subscribeAsync } from './common/message-bus'; import { GrpcServer } from './grpc/server'; import { services } from './services'; @@ -45,9 +45,9 @@ function startAsync() { // Wait for all subscriptions to finish .all() // Find the web UI's host and port - .then(() => lookupServiceAsync('web')) + .then(() => lookupService('web')) // Start the Grpc server to process requests - .then(webIpAndPorts => { + .then(webIpAndPort => { // Create a Grpc server and register all listeners logger.log('info', 'Starting all Grpc services'); @@ -56,7 +56,7 @@ function startAsync() { // Start the server and return it server.start(); - logger.log('info', `Open http://${webIpAndPorts[0]} in a web browser to see the UI`); + logger.log('info', `Open http://${webIpAndPort} in a web browser to see the UI`); logger.log('info', 'KillrVideo has started. Press Ctrl+C to exit.'); return server; }) diff --git a/src/server-listeners/register-with-service-discovery.js b/src/server-listeners/register-with-service-discovery.js index 5ab827a..d2b2352 100644 --- a/src/server-listeners/register-with-service-discovery.js +++ b/src/server-listeners/register-with-service-discovery.js @@ -1,5 +1,5 @@ import Promise from 'bluebird'; -import { registerServiceAsync, removeServiceAsync } from '../common/service-discovery' +import { registerService, removeService } from '../common/service-discovery' import { withRetries } from '../common/with-retries'; import config from '../common/config'; import {serviceNameFromDefinition} from '../services'; @@ -29,11 +29,11 @@ export function register(grpcServer) { startStopPromise.cancel(); } - // Register each service with etcd + // Register each service let startServices = services.map(s => { let name = serviceNameFromDefinition(s); - let registerFn = () => registerServiceAsync(name, uniqueId, ipAndPort); - return withRetries(registerFn, Infinity, 5, `Could not register ${name} in service registry`, false); + // let registerFn = () => registerService(name, ipAndPort); + return withRetries(() => new Promise(function(resolve, reject) {resolve(registerService(name, ipAndPort))}), Infinity, 5, `Could not register ${name} in service registry`, false); }); startStopPromise = Promise.all(startServices).tap(() => { startStopPromise = null; }) }); @@ -56,7 +56,7 @@ export function remove(grpcServer) { // Remove each service from etcd let stopServices = services.map(s => { let name = serviceNameFromDefinition(s); - let removeFn = () => removeServiceAsync(name, uniqueId); + let removeFn = () => removeService(name); return withRetries(removeFn, Infinity, 5, `Could not remove ${name} from service registry`, false); }); startStopPromise = Promise.all(stopServices).tap(() => { startStopPromise = null; }); diff --git a/src/services/search/get-query-suggestions.js b/src/services/search/get-query-suggestions.js index 37bc92b..b11bcd5 100644 --- a/src/services/search/get-query-suggestions.js +++ b/src/services/search/get-query-suggestions.js @@ -1,7 +1,7 @@ import Promise from 'bluebird'; import rp from 'request-promise'; import config from '../../common/config'; -import { lookupServiceAsync } from '../../common/service-discovery'; +import { lookupService } from '../../common/service-discovery'; import { getCassandraClient } from '../../common/cassandra'; import { NotImplementedError } from '../common/grpc-errors'; import { GetQuerySuggestionsResponse } from './protos'; @@ -44,7 +44,7 @@ let getSearchClientPromise = null; function getSearchClientAsync() { if (getSearchClientPromise === null) { - getSearchClientPromise = lookupServiceAsync('dse-search') + getSearchClientPromise = lookupService('dse-search') .then(hostAndPorts => { // Just use the first host:port returned return rp.defaults({ diff --git a/src/services/suggested-videos/get-related-videos.js b/src/services/suggested-videos/get-related-videos.js index 368e84a..90bd85d 100644 --- a/src/services/suggested-videos/get-related-videos.js +++ b/src/services/suggested-videos/get-related-videos.js @@ -1,6 +1,6 @@ import Promise from 'bluebird'; import rp from 'request-promise'; -import { lookupServiceAsync } from '../../common/service-discovery'; +import { lookupService } from '../../common/service-discovery'; import { getCassandraClient } from '../../common/cassandra'; import config from '../../common/config'; import { toCassandraUuid, toProtobufUuid, toProtobufTimestamp } from '../common/protobuf-conversions'; @@ -144,11 +144,11 @@ let getSearchClientPromise = null; function getSearchClientAsync() { if (getSearchClientPromise === null) { - getSearchClientPromise = lookupServiceAsync('dse-search') + let searchLocation = lookupService('dse-search') + getSearchClientPromise = new Promise (function(resolve, reject){resolve(searchLocation)}) .then(hostAndPorts => { - // Just use the first host:port returned return rp.defaults({ - baseUrl: `http://${hostAndPorts[0]}/solr` + baseUrl: `http://${hostAndPorts}/solr` }); }) .catch(err => { From f7f4dbd36dc03268ebf863960bfce21481fab7b3 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Fri, 25 Jan 2019 21:36:28 +0100 Subject: [PATCH 02/12] Reworked docker-compose.yml --- README.md | 13 ++++---- docker-compose.yaml | 75 ++++++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index fcf5599..e470b0c 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,15 @@ A reference application for Node.js developers looking to learn more about using [Apache Cassandra][cassandra] and [DataStax Enterprise][dse] in their applications and services. Learn more at [killrvideo.github.io][killrvideo]. -## Running Locally +## Running Locally using Docker -Use these guides to get started running KillrVideo locally on your development machine: +Development should be pretty straight-forward if you are familiar with docker and docker-compose -* [Getting Started with KillrVideo][getting-started]: Follow this to setup common dependencies -like Docker. -* [Getting Started with Node.js][getting-started-node]: Follow this to get this Node.js code -running. +``` +> docker-compose pull +> docker-compose build +> docker-compose up -d +``` ## Contributing, Requests for More Examples diff --git a/docker-compose.yaml b/docker-compose.yaml index 5220714..3c1c574 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,59 +1,64 @@ version: '3' - -# Other services are specified in .\lib\killrvideo-docker-common\docker-compose.yaml services: - node: - build: /Users/aleksandrvolochnev/killrvideo/node + # NodeJS Backend + backend: + build: . + volumes: + - .:/usr/src/app depends_on: - dse environment: - KILLRVIDEO_ETCD: "etcd:2379" - KILLRVIDEO_DSE_USERNAME: $KILLRVIDEO_DSE_USERNAME - KILLRVIDEO_DSE_PASSWORD: $KILLRVIDEO_DSE_PASSWORD - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_LOGGING_LEVEL: $KILLRVIDEO_LOGGING_LEVEL + KILLRVIDEO_LOGGING_LEVEL: debug - # Start the KillrVideo web UI on port 3000 + # Datastax Enterprise + dse: + image: datastax/dse-server:6.0.0 + command: [ -s -g ] + ports: + - "9042:9042" + - "8983:8983" + - "8182:8182" + environment: + DS_LICENSE: accept + # Allow DSE to lock memory with mlock + cap_add: + - IPC_LOCK + ulimits: + memlock: -1 + + # Frontend web: - image: killrvideo/killrvideo-web:1.2.6 - #build: /Users/aleksandrvolochnev/killrvideo/web + image: killrvideo/killrvideo-web:3.0.0-rc1 ports: - "3000:3000" depends_on: - dse - - etcd environment: - SERVICE_3000_NAME: web - KILLRVIDEO_ETCD: "etcd:2379" - KILLRVIDEO_DSE_USERNAME: $KILLRVIDEO_DSE_USERNAME - KILLRVIDEO_DSE_PASSWORD: $KILLRVIDEO_DSE_PASSWORD - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_LOGGING_LEVEL: $KILLRVIDEO_LOGGING_LEVEL + KILLRVIDEO_LOGGING_LEVEL: debug - # The sample data generator + # DSE Configurator to setup DSE + dse-config: + image: killrvideo/killrvideo-dse-config:2.2.1 + environment: + KILLRVIDEO_SERVICE_DISCOVERY_DISABLED: 'true' + depends_on: + - dse + + # Sample Data Generator generator: - image: killrvideo/killrvideo-generator:1.2.4 + image: killrvideo/killrvideo-generator:3.0.0-rc4 depends_on: - dse - - etcd + - backend environment: - KILLRVIDEO_ETCD: "etcd:2379" - KILLRVIDEO_DSE_USERNAME: cassandra - KILLRVIDEO_DSE_PASSWORD: cassandra - NODE_ENV: $NODE_ENV - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_LOGGING_LEVEL: $KILLRVIDEO_LOGGING_LEVEL + KILLRVIDEO_LOGGING_LEVEL: debug - # One instance of DataStax Studio + # DataStax Studio studio: image: killrvideo/killrvideo-studio:2.0.0 ports: - # The Web UI exposed to our host - - "9091:9091" + - "9091:9091" depends_on: - - dse + - dse environment: - SERVICE_9091_NAME: studio DS_LICENSE: accept - - From da0a9d4e485e4dfc91f835b4be46e4d6c986fc01 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Fri, 25 Jan 2019 23:03:31 +0100 Subject: [PATCH 03/12] Removed docker-common lib --- lib/killrvideo-docker-common/.gitignore | 4 - lib/killrvideo-docker-common/LICENSE | 202 --- lib/killrvideo-docker-common/README.md | 1 - .../config-secure/dse.yaml | 1183 ----------------- .../config-secure/remote.yaml | 37 - .../create-environment.ps1 | 76 -- .../create-environment.sh | 38 - .../docker-compose-ops-center.yaml | 69 - .../docker-compose-secure.yaml | 61 - .../docker-compose-studio.yaml | 70 - .../docker-compose-volumes.yaml | 64 - .../docker-compose.yaml | 59 - .../extras/_with_server_and_external_down.sh | 6 - .../extras/_with_server_and_external_up.sh | 6 - .../extras/_with_server_down.sh | 6 - .../extras/_with_server_up.sh | 6 - .../extras/docker-compose-dse-external.yaml | 18 - .../extras/docker-compose-server.yaml | 19 - .../get-environment.ps1 | 63 - .../get-environment.sh | 46 - 20 files changed, 2034 deletions(-) delete mode 100644 lib/killrvideo-docker-common/.gitignore delete mode 100644 lib/killrvideo-docker-common/LICENSE delete mode 100644 lib/killrvideo-docker-common/README.md delete mode 100644 lib/killrvideo-docker-common/config-secure/dse.yaml delete mode 100644 lib/killrvideo-docker-common/config-secure/remote.yaml delete mode 100644 lib/killrvideo-docker-common/create-environment.ps1 delete mode 100755 lib/killrvideo-docker-common/create-environment.sh delete mode 100644 lib/killrvideo-docker-common/docker-compose-ops-center.yaml delete mode 100644 lib/killrvideo-docker-common/docker-compose-secure.yaml delete mode 100644 lib/killrvideo-docker-common/docker-compose-studio.yaml delete mode 100644 lib/killrvideo-docker-common/docker-compose-volumes.yaml delete mode 100644 lib/killrvideo-docker-common/docker-compose.yaml delete mode 100755 lib/killrvideo-docker-common/extras/_with_server_and_external_down.sh delete mode 100755 lib/killrvideo-docker-common/extras/_with_server_and_external_up.sh delete mode 100755 lib/killrvideo-docker-common/extras/_with_server_down.sh delete mode 100755 lib/killrvideo-docker-common/extras/_with_server_up.sh delete mode 100644 lib/killrvideo-docker-common/extras/docker-compose-dse-external.yaml delete mode 100644 lib/killrvideo-docker-common/extras/docker-compose-server.yaml delete mode 100644 lib/killrvideo-docker-common/get-environment.ps1 delete mode 100755 lib/killrvideo-docker-common/get-environment.sh diff --git a/lib/killrvideo-docker-common/.gitignore b/lib/killrvideo-docker-common/.gitignore deleted file mode 100644 index 445ea2d..0000000 --- a/lib/killrvideo-docker-common/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.env -.idea -*/.idea/* - diff --git a/lib/killrvideo-docker-common/LICENSE b/lib/killrvideo-docker-common/LICENSE deleted file mode 100644 index 021eb6b..0000000 --- a/lib/killrvideo-docker-common/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016 Luke Tillman - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/lib/killrvideo-docker-common/README.md b/lib/killrvideo-docker-common/README.md deleted file mode 100644 index 7b4d165..0000000 --- a/lib/killrvideo-docker-common/README.md +++ /dev/null @@ -1 +0,0 @@ -# KillrVideo Common Docker Environment Setup diff --git a/lib/killrvideo-docker-common/config-secure/dse.yaml b/lib/killrvideo-docker-common/config-secure/dse.yaml deleted file mode 100644 index 362216d..0000000 --- a/lib/killrvideo-docker-common/config-secure/dse.yaml +++ /dev/null @@ -1,1183 +0,0 @@ -# Memory limit for DSE In-Memory tables as a fraction of system memory (the default is 0.2, or 20%) -max_memory_to_lock_fraction: 0.20 - -# # Can also be specified as a maximum in MB; the fraction value is ignored if this is set to a non-zero value. -# max_memory_to_lock_mb: 10240 - -########################## -# Authentication options -# -# These options are used if the authenticator option in cassandra.yaml is set to -# com.datastax.bdp.cassandra.auth.DseAuthenticator -# -# The enabled option controls whether the DseAuthenticator will authenticate users. If -# set to true users will be authenticated, if set to false they will not. -# -# DseAuthenticator allows multiple authentication schemes to be used at the same time. -# The schemes to be used are controlled by the default_scheme and allowed_schemes options. -# A driver can select the scheme to use during authentication. -# -# The default_scheme option selects which authentication scheme will be used if the driver -# does not request a specific scheme. This can be one of the following values: -# internal - plain text authentication using the Cassandra password authenticator -# ldap - plain text authentication using the passthrough ldap authenticator -# kerberos - gssapi authentication using the kerberos authenticator -# The other_schemes option is a list of schemes that can also be selected for use by a -# driver and can be a list of the above schemes. -# -# The scheme_permissions option controls whether roles need to have permission granted to -# them in order to use specific authentication schemes. These permissions can be granted -# only when the DseAuthorizer is used. -# -# The allow_digest_with_kerberos option controls whether digest-md5 authentication is also -# allowed when kerberos is one of the authentication schemes. If set to false, it will not -# be allowed. You must set allow_digest_with_kerberos to true in analytics clusters to use Hadoop -# inter-node authentication with Hadoop and Spark jobs. -# -# The plain_text_without_ssl controls how the DseAuthenticator reacts to plain text -# authentication requests over unencrypted client connections. It can be one of: -# block - block the request with an authentication error -# warn - log a warning about the request but allow it to continue -# allow - allow the request without any warning -# -# The transitional_mode option allows the DseAuthenticator to operate in a transitional -# mode during setup of authentication in a cluster. This can be one of the following values: -# disabled - transitional mode is disabled -# permissive - Only super users are authenticated and logged in, all other -# authentication attempts will be logged in as the anonymous user -# normal - If credentials are passed they are authenticated. If the -# authentication is successful then the user is logged in, otherwise -# the user is logged in as anonymous. If no credentials are passed, -# then the user is logged in as anonymous -# strict - If credentials are passed they are authenticated. If the -# authentication is successful, the user is logged in. If the -# authentication fails, an authentication error is returned. If no -# credentials are passed, the user is logged in as anonymous -authentication_options: - enabled: true -# default_scheme: internal -# allow_digest_with_kerberos: true -# plain_text_without_ssl: warn -# transitional_mode: default -# other_schemes: -# scheme_permissions: false - -########################## -# Role Management Options -# -# These options are used when the role_manager option in cassandra.yaml is set to -# com.datastax.bdp.cassandra.auth.DseRoleManager -# -# mode can be one of: -# internal - the granting and revoking of roles is managed internally -# using the GRANT ROLE and REVOKE ROLE statements -# ldap - the granting and revoking of roles is managed by an external -# LDAP server configured using the ldap_options. -role_management_options: - mode: internal - -########################## -# Authorization options -# -# The enabled option controls whether the DseAuthorizer will perform authorization. If -# set to true authorization is performed, if set to false it is not. -# -# The transitional_mode option allows the DseAuthorizer to operate in a transitional -# mode during setup of authorization in a cluster. This can be one of the following values: -# disabled - transitional mode is disabled -# normal - permissions can be granted to resources but are not enforced -# strict - permissions can be granted to resources and are enforced on -# authenticated users. They are not enforced against anonymous -# users -# allow_row_level_security - In order for row level security to be used, this must be set to allow it -# for the entire system. true or false -authorization_options: - enabled: true -# transitional_mode: disabled -# allow_row_level_security: false - -########################## -# Kerberos options -# -# The qop is the Quality of Protection (QOP) values that clients and servers -# can use for each connection. Below is a list of valid values and their meanings. -# auth - (default) authentication only -# auth-int - authentication plus integity protection of all transmitted data -# auth-conf - authentication plus integrity protection and encryption of all -# transmitted data -# -# Warning - Encryption using auth-conf is separate and completely independent -# of whether encryption is done using SSL. If auth-conf is selected here -# and SSL is enabled, the transmitted data is encrypted twice. -kerberos_options: - keytab: resources/dse/conf/dse.keytab - service_principal: dse/_HOST@REALM - http_principal: HTTP/_HOST@REALM - qop: auth - -########################## -# LDAP options -# -# These are options are used when the com.datastax.bdp.cassandra.auth.LdapAuthenticator -# is configured as the authenticator in cassandra.yaml - -# ldap_options: -# server_host: -# -# # Port to use to connect to the LDAP server. This is normally 389 for unencrypted -# # connections and 636 for ssl encrypted connections. If use_tls is set to true, use the -# # unencrypted port -# server_port: 389 -# -# # The distinguished name (DN) of the user that is used to search for other users on the -# # LDAP server. This user should have only the necessary permissions to do the search -# # If not present then an anonymous bind is used for the search -# search_dn: -# -# # Password of the search user -# search_password: -# -# # Set to true to use an SSL encrypted connection. In this case the server_port needs -# # to be set to the LDAP port for the server -# use_ssl: false -# -# # Set to true to initiate a TLS encrypted connection on the default ldap port -# use_tls: false -# -# truststore_path: -# truststore_password: -# truststore_type: jks -# user_search_base: -# user_search_filter: (uid={0}) -# -# # Set to the attribute on the user entry containing group membership information. -# user_memberof_attribute: memberof -# -# # The group_search_type defines how group membership will be determined for a user. It -# # can be one of: -# # directory_search - will do a subtree search of group_search_base using -# # group_search_filter to filter the results -# # memberof_search - will get groups from the memberof attribute of the user. This -# # requires the directory server to have memberof support -# group_search_type: directory_search -# group_search_base: -# group_search_filter: (uniquemember={0}) -# -# # The attribute in the group entry that holds the group name. -# group_name_attribute: cn -# -# # Validity period for the credentials cache in milli-seconds (remote bind is an expensive -# # operation). Defaults to 0, set to 0 to disable. -# credentials_validity_in_ms: 0 -# -# # Validity period for the search cache in seconds. Defaults to 0, set to 0 to disable. -# search_validity_in_seconds: 0 -# -# connection_pool: -# max_active: 8 -# max_idle: 8 - -# To ensure that records with TTLs are purged from DSE Search indexes when they expire, DSE -# periodically checks all indexes for expired documents and deletes them. These settings -# control the scheduling and execution of those checks. -ttl_index_rebuild_options: - - # By default, schedule a check every 300 seconds: - fixed_rate_period: 300 - - # The first check is delayed to speed up startup time: - initial_delay: 20 - - # All documents determined to be expired are deleted from the index during each check, but - # to avoid memory pressure, their unique keys are retrieved and deletes issued in batches. - # This determines the maximum number of documents per batch: - max_docs_per_batch: 4096 - - # Maximum number of search indexes that can execute TTL cleanup concurrently: - thread_pool_size: 1 - -# DSE Search resource upload size limit in MB. A value of '0' disables resource uploading. -solr_resource_upload_limit_mb: 10 - -# Transport options for inter-node communication between DSE Search nodes. -shard_transport_options: - # The cumulative shard request timeout, in milliseconds (default is 60000). - netty_client_request_timeout: 60000 - -# ---- DSE Search index encryption options - -solr_encryption_options: -# # Whether to allocate shared index decryption cache off JVM heap. -# # Default is off heap allocation (true). -# decryption_cache_offheap_allocation: true - -# # The maximum size of shared DSE Search decryption cache, in MB. -# # Default is 256 MB. -# decryption_cache_size_in_mb: 256 - -# ---- DSE Search indexing settings - -# # Max number of concurrent asynchronous indexing threads per Solr core. If set -# # to 1, the system reverts to the synchronous behavior, where data is -# # synchronously written into Cassandra and indexed by Solr. -# # -# # Default: On most Linux distributions, the number of physical CPU cores (even if those cores -# # have multiple threads). On other platforms, this defaults to the number of logical -# # CPU cores visible to the JVM. If the system property "cassandra.available_processors" -# # is set, the default here will be that value divided by the number of threads per CPU core. -# max_solr_concurrency_per_core: 2 -# -# # Allows back pressure system to adapt max auto soft commit time (defined per core in solrconfig.xml) to the actual load. -# # Setting is respected only for NRT (near real time) cores. When core has RT (real time) enabled, adaptive commits -# # are disabled regardless of this property value. -# # -# # Default: enabled (true) -# enable_back_pressure_adaptive_nrt_commit: true -# -# # The back pressure threshold is the target total number of queued asynchronous indexing requests per core; -# # the back pressure mechanism will throttle incoming requests to keep the queue size as close to the threshold as possible. -# # -# # Default: 1000 * max_solr_concurrency_per_core -# back_pressure_threshold_per_core: 2000 -# -# # The max time to wait for flushing of async index updates, happening either -# # at Solr commit time or Cassandra flush time. -# # Flushing should always complete successfully, in order to fully sync Solr indexes -# # with Cassandra data, so should always be set at a reasonable high value. -# # -# # Default: 5 minutes -# flush_max_time_per_core: 5 -# -# # The max time to wait for each Solr core to load upon startup or create/reload operations. -# # This is an advanced option, which should be changed only if any exceptions happen during core loading. -# # -# # Default: 5 minutes -# load_max_time_per_core: 5 -# -# # Applies the configured Cassandra disk failure policy to index write failures. -# # Default is disabled (false). -# enable_index_disk_failure_policy: false - -# # The directory to store index data; each DSE Search index will be stored under -# # a solrconfig_data_dir/keyspace.table directory. -# # Default is a solr.data directory inside Cassandra data directory, or as specified -# # by the dse.solr.data.dir system property -# solr_data_dir: /MyDir - -# # The Lucene field cache has been deprecated, instead set docValues="true" on the field -# # in the schema.xml file. After doing so RELOAD the core and reindex. -# # Default: false -# solr_field_cache_enabled: false - -# ---- Solr CQL query options - -# # Max number of threads to use for retrieving rows during CQL Solr queries. -# # This value is cross-request and cross-core. -# # Default is "number of available processors" * 10. -# cql_solr_query_executor_threads: 2 -# -# # Max time in milliseconds to wait for either each row (pre-5.0) or all rows (5.0 onwards) -# # to be read from Cassandra during CQL Solr queries. -# # Default is 10000 (10 seconds). -# cql_solr_query_row_timeout: 10000 - -########################## -# Global performance service options - -# # Maximum number of background threads used by the performance service. -# # Defaults to concurrent_writes specified in cassandra.yaml. -# performance_max_threads: 32 -# -# # The number of queued tasks in the backlog when the number of performance_max_threads are busy (minimum 0). -# performance_queue_capacity: 32000 -# -# # If the performance service requests more tasks than (performance_max_threads + performance_queue_capacity), -# # a dropped task warning will be issued. This indicates that collected statistics may not be up to date because the -# # server couldn't keep up under the current load. -# -# # You may either disable or reconfigure some services, or increase the queue size. - -########################## -# Core performance service options - -graph_events: - ttl_seconds: 600 - -# cql_slow_log_options: -# enabled: true -# -# # When t > 1, log queries taking longer than t milliseconds. -# # 0 <= t <= 1, log queries above t percentile -# threshold: 200.0 -# -# # Initial number of queries before percentile filter becomes active -# minimum_samples: 100 -# -# ttl_seconds: 259200 -# -# # keeps slow queries in-memory only and doesn't write data to C* -# # WARNING - if this is set to 'false' then set threshold >= 2000, otherwise there will be a high load on C* -# skip_writing_to_db: true -# -# # the number of slow queries to keep in-memory -# num_slowest_queries: 5 - -cql_system_info_options: - enabled: false - refresh_rate_ms: 10000 - -resource_level_latency_tracking_options: - enabled: false - refresh_rate_ms: 10000 - -db_summary_stats_options: - enabled: false - refresh_rate_ms: 10000 - -cluster_summary_stats_options: - enabled: false - refresh_rate_ms: 10000 - -spark_cluster_info_options: - enabled: false - refresh_rate_ms: 10000 - -# ---- Spark application stats options -spark_application_info_options: - enabled: false - refresh_rate_ms: 10000 - - driver: - # enables or disables writing of the metrics collected at Spark Driver to Cassandra - sink: false - - # enables or disables Spark Cassandra Connector metrics at Spark Driver - connectorSource: false - - # enables or disables JVM heap and GC metrics at Spark Driver - jvmSource: false - - # enables or disables application state metrics - stateSource: false - - executor: - # enables or disables writing of the metrics collected at executors to Cassandra - sink: false - - # enables or disables Spark Cassandra Connector metrics at executors - connectorSource: false - - # enables or disables JVM heap and GC metrics at executors - jvmSource: false - -# Column Family Histogram data tables options -histogram_data_options: - enabled: false - refresh_rate_ms: 10000 - retention_count: 3 - -# User/Resource latency tracking settings -user_level_latency_tracking_options: - enabled: false - refresh_rate_ms: 10000 - top_stats_limit: 100 - quantiles: false - -# ---- DSE Search Performance Objects - -solr_indexing_error_log_options: - enabled: false - ttl_seconds: 604800 - async_writers: 1 - -solr_slow_sub_query_log_options: - enabled: false - ttl_seconds: 604800 - async_writers: 1 - threshold_ms: 3000 - -solr_update_handler_metrics_options: - enabled: false - ttl_seconds: 604800 - refresh_rate_ms: 60000 - -solr_request_handler_metrics_options: - enabled: false - ttl_seconds: 604800 - refresh_rate_ms: 60000 - -solr_index_stats_options: - enabled: false - ttl_seconds: 604800 - refresh_rate_ms: 60000 - -solr_cache_stats_options: - enabled: false - ttl_seconds: 604800 - refresh_rate_ms: 60000 - -solr_latency_snapshot_options: - enabled: false - ttl_seconds: 604800 - refresh_rate_ms: 60000 - -# Node health is a score-based representation of how fit a node is to handle queries. The score is a -# function of how long a node has been up and the rate of dropped mutations in the recent past. -node_health_options: - refresh_rate_ms: 60000 - # The amount of continuous uptime required for the node to reach the maximum uptime score. If you - # are concerned with consistency during repair after a period of downtime, you may want to - # temporarily increase this to the expected time it will take to complete repair. - # - # (Default: 86400 seconds, or 1 day) - uptime_ramp_up_period_seconds: 86400 - # The window in the past over which the rate of dropped mutations affects the node health score. - # (Default: 30 minutes) - dropped_mutation_window_minutes: 30 - -# If enabled (true), replica selection for distributed DSE Search queries takes node health into account -# when multiple candidates exist for a particular token range. Set this to false to ignore -# node health when choosing replicas. -# -# Health-based routing allows us to make a trade-off between index consistency and query throughput. If -# the primary concern is query performance, it may make sense to set this to "false". -# -# Default is enabled (true). -enable_health_based_routing: true - -# If enabled (true), DSE Search reindexing of bootstrapped data will happen asynchronously, and the node will join the ring straight -# after bootstrap. -# -# Default is disabled (false): the node will wait for reindexing of bootstrapped data to finish before joining the ring. -async_bootstrap_reindex: false - -# Lease metrics. Enable these to help monitor the performance of the lease subsystem. -# ttl_seconds controls how long the log of lease holder changes persists. -lease_metrics_options: - enabled: false - ttl_seconds: 604800 - -# The directory where system keys are kept -# -# Keys used for sstable encryption must be distributed to all nodes -# DSE must be able to read and write to the directory. -# -# This directory should have 700 permissions and belong to the dse user -system_key_directory: /etc/dse/conf - -# If this is set to true, DSE will expect the following config values to be encrypted: -# resources/cassandra/conf/cassandra.yaml: -# server_encryption_options.keystore_password -# server_encryption_options.truststore_password -# client_encryption_options.keystore_password -# client_encryption_options.truststore_password -# resources/dse/conf/dse.yaml: -# ldap_options.search_password -# ldap_options.truststore_password -# -# It's an error if the passwords aren't encrypted. -# Config values can be encrypted with "dsetool encryptconfigvalue" -config_encryption_active: false - -# The name of the system key used to encrypt / decrypt passwords stored -# in configuration files. -# -# If config_encryption_active is true, it's an error if a valid key with -# this name isn't in the system key directory keyfiles, and KMIP managed -# keys can be created with "dsetool createsystemkey" -config_encryption_key_name: system_key - -########################## -# Spark-related settings - -# The fraction of available system resources to be used by Spark Worker. -# This the only initial value, once it is reconfigured, the new value is stored -# and retrieved on next run. -initial_spark_worker_resources: 0.7 - -# The length of a shared secret used to authenticate Spark components and encrypt the connections between them. -# Note that this is not the strength of the cipher used for encrypting connections. -spark_shared_secret_bit_length: 256 - -# Enables Spark security based on shared secret infrastructure. This means enabling mutual authentication of -# the Spark components as well as optionally encryption of communication channels except Web UI. -spark_security_enabled: false - -# Enables encryption on Spark connections except Web UI. It uses Digest-MD5 SASL based encryption mechanism. -# This options does make sense only if spark_security_enabled is true. -spark_security_encryption_enabled: false - -# # How often Spark plugin should check for Spark Master / Worker readiness to start. The value is -# # a time (in ms) between subsequent retries. -# spark_daemon_readiness_assertion_interval: 1000 - -# Beginning in DSE 5.1: Communication between Spark applications and the resource manager are now routed through -# the CQL native protocol. Enabling client encryption in the cassandra.yaml will also enable encryption for -# the communication with the DSE Spark Master. The communication between Spark Driver and Spark Executors can be -# secured by enabling Spark authentication and encryption for that application. -# On the other hand, mutual authentication and encryption of communication between DSE Spark Master and Workers are -# managed by spark_security_enabled and spark_security_encryption_enabled defined above. - -# Spark UI options apply to Spark Master and Spark Worker UIs - thus Spark daemon UIs in general. They do NOT apply to -# user applications even if they run in cluster mode. -spark_ui_options: - # Allowed values are: - # inherit - SSL settings are inherited from Cassandra client encryption options - # custom - SSL settings from encryption_options below - encryption: inherit - - encryption_options: - enabled: false - keystore: resources/dse/conf/.ui-keystore - keystore_password: cassandra - # require_client_auth: false - # Set trustore and truststore_password if require_client_auth is true - # truststore: resources/dse/conf/.ui-truststore - # truststore_password: cassandra - # More advanced defaults below: - # protocol: TLS - # algorithm: SunX509 - # store_type: JKS - # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA] - -# Configure the way how the driver and executor processes are created and managed. -spark_process_runner: - # Allowed options are: default, run_as - runner_type: default - - # RunAs runner uses sudo to start Spark drivers and executors. A set of predefined fake users, called slots, is used - # for this purpose. All drivers and executors owned by some DSE user are run as some slot user x. At the same time - # drivers and executors of any other DSE user use different slots. - # Setting up slots: - # 1. create n users (n - number of slots), call them, say slot1, slot2, ..., slotn, with no login; each such user - # should have primary group the same as its name, so for example slot1:slot1, slot2:slot2, ... - # 2. add DSE service user (the one as who DSE server is run) to the slot user groups - DSE service user has to be - # in all slot user groups - # 3. modify sudoers files so that: - # a) DSE service user can execute any command as any slot user without providing a password - # b) umask is overridden to 007 for those commands so that files created by sub-processes will not be accessible - # by anyone by default, - # For example, if we have two slot users slot1, slot2, and DSE service user dse, this should be added to sudoers: - # Runas_Alias SLOTS = slot1, slot2 - # Defaults>SLOTS umask=007 - # Defaults>SLOTS umask_override - # dse ALL=(SLOTS) NOPASSWD: ALL - run_as_runner_options: - user_slots: - - slot1 - - slot2 - -########################## -# DSE File System options -# dsefs_options: -# -# # Determines whether DSEFS should be enabled on this node. -# # If not present, DSEFS is enabled only on the nodes that run Spark workload. -# enabled: -# -# # Keyspace for storing the DSE FS metadata -# keyspace_name: dsefs -# -# # The local directory for storing node-local metadata e.g. the node identifier -# # The amount of data stored there is tiny, so no special throughput, latency nor capacity are required. -# # The work directory must not be shared by DSE FS nodes. -# work_dir: /var/lib/dsefs -# -# # Port for DSE FS clients, the service on this port will be bound to RPC address. -# public_port: 5598 -# -# # Port for internode communication, must be not visible from outside of the cluster. -# # It will be bound to listen address. -# private_port: 5599 -# -# # Set of directories for storing the file data. 'dir' attribute is mandatory. -# # It is recommended to put them on different physical devices than devices used for Cassandra. -# # Using multiple directories on JBOD improves performance and capacity. -# data_directories: -# - dir: /var/lib/dsefs/data -# -# # How much data should be placed in this directory relative to other directories in the cluster -# storage_weight: 1.0 -# -# # Reserved space (in bytes) that is not going to be used for storing blocks -# min_free_space: 5368709120 -# -# # More advanced settings below: -# -# # How long DseFs Server is going to wait for services to bootstrap -# service_startup_timeout_ms: 30000 -# -# # How long DseFs Server is going to wait for services to close -# service_close_timeout_ms: 600000 -# -# # How long DseFs Server is going to wait close all pending connections during shutdown -# server_close_timeout_ms: 2147483647 # Integer.MAX_VALUE -# -# # The maximum accepted size of a compression frame (compression frame size is specified by a user during file -# # upload) -# compression_frame_max_size: 1048576 -# -# # Maximum number of elements in single DseFs Server query cache. DseFs reuses this value for every cache that -# # stores database query results. -# query_cache_size: 2048 -# -# # How long DseFs Server query cache element exists in cache. DseFs reuses this value for every cache that -# # stores database query results. -# query_cache_expire_after_ms: 2000 -# -# gossip_options: -# # The delay between gossip rounds -# round_delay_ms: 2000 -# -# # How long to wait after registering the Location and reading back all other Locations from Cassandra -# startup_delay_ms: 5000 -# -# # How long to wait after announcing shutdown before shutting down the node -# shutdown_delay_ms: 10000 -# -# rest_options: -# # How long RestClient is going to wait for a response corresponding to a given request -# request_timeout_ms: 330000 -# -# # How long RestClient is going to wait for establishing a new connection -# connection_open_timeout_ms: 55000 -# -# # How long RestClient is going to wait until all pending transfers are complete before closing -# client_close_timeout_ms: 60000 -# -# # How long to wait for the server rest call to complete -# server_request_timeout_ms: 300000 -# -# # How long to wait until idle connection is closed, 0 if disabled -# idle_connection_timeout_ms: 0 - -# transaction_options: -# # How long to allow a transaction to run before considering it for timing out and rollback -# transaction_timeout_ms: 60000 -# -# # How long to wait before retrying a transaction aborted due to a conflict -# conflict_retry_delay_ms: 10 -# -# # How many times the transaction is retried in case of a conflict before giving up -# conflict_retry_count: 40 -# -# # How long to wait before retrying a failed transaction payload execution -# execution_retry_delay_ms: 1000 -# -# # How many times to retry executing the payload before signaling the error to the application -# execution_retry_count: 3 -# -# block_allocator_options: -# # The overflow_margin_mb and overflow_factor options control how much additional data can be placed -# # on the local (coordinator) before the local node overflows to the other nodes. -# # A local node is preferred for a new block allocation, if -# # used_size_on_the_local_node < average_used_size_per_node * overflow_factor + overflow_margin. -# # The trade-off is between data locality of writes and balancing the cluster. -# # To disable the preference for allocating blocks on the coordinator node, set these values to 0 MB and 1.0. -# overflow_margin_mb: 1024 -# overflow_factor: 1.05 - -########################## -# Audit logging options -audit_logging_options: - enabled: false - - # The logger used for logging audit information - # Available loggers are: - # CassandraAuditWriter - logs audit info to a cassandra table. This logger can be run either synchronously, or - # asynchronously. Audit logs are stored in the dse_audit.audit_log table. - # When run synchronously, a query will not execute until it has been written - # to the audit log table successfully. If there is a failure between when an audit event is - # written, and it's query is executed, the audit logs may contain queries that were never - # executed. - # SLF4JAuditWriter - logs audit info to an slf4j logger. The logger name is `SLF4JAuditWriter`, - # and can be configured in the logback.xml file. - logger: SLF4JAuditWriter - -# # Comma separated list of audit event categories to be included or excluded from the audit log. -# # Defaults to including all categories and keyspaces. -# # Categories are: QUERY, DML, DDL, DCL, AUTH, ADMIN, ERROR -# # Specify either included or excluded categories. Specifying both is an error -# included_categories: -# excluded_categories: - -# # Comma separated list of keyspaces to be included or excluded from the audit log. -# # Specify either included or excluded keyspaces. Specifying both is an error -# included_keyspaces: -# excluded_keyspaces: - - # The amount of time, in hours, audit events are retained by supporting loggers - # Currently, only the CassandraAuditWriter supports retention time - # values of 0 or less retain events forever - retention_time: 0 - - cassandra_audit_writer_options: - # Sets the mode the writer runs in. - # - # When run synchronously, a query is not executed until the audit event is successfully written. - # - # When run asynchronously, audit events are queued for writing to the audit table, but are - # not necessarily logged before the query executes. A pool of writer threads consumes the - # audit events from the queue, and writes them to the audit table in batch queries. While - # this substantially improves performance under load, if there is a failure between when - # a query is executed, and it's audit event is written to the table, the audit table may - # be missing entries for queries that were executed. - # valid options are 'sync' and 'async' - mode: sync - - # The maximum number of events the writer will dequeue before writing them out to the table. - # If you're seeing warnings in your logs about batches being too large, decrease this value. - # Increasing batch_size_warn_threshold_in_kb in cassandra.yaml is also an option, but make sure you understand - # the implications before doing so. - # - # Only used in async mode. Must be >0 - batch_size: 50 - - # The maximum amount of time in milliseconds an event will be dequeued by a writer before being written out. This - # prevents events from waiting too long before being written to the table when there's not a lot of queries happening. - # - # Only used in async mode. Must be >0 - flush_time: 500 - - # The number of worker threads asynchronously logging events to the CassandraAuditWriter. - # - # Only used in async mode. Must be >0 - num_writers: 10 - - # The size of the queue feeding the asynchronous audit log writer threads. When there are more events being - # produced than the writers can write out, the queue will fill up, and newer queries will block until there - # is space on the queue. - # If a value of 0 is used, the queue size will be unbounded, which can lead to resource exhaustion under - # heavy query load. - queue_size: 10000 - - # the consistency level used to write audit events - write_consistency: QUORUM - -# # Where dropped events are logged -# dropped_event_log: /var/log/cassandra/dropped_audit_events.log - -# # Partition days into hours by default -# day_partition_millis: 3600000 - -########################## -# System information encryption settings -# -# If enabled, system tables that may contain sensitive information (system.batchlog, -# system.paxos), hints files and Cassandra commit logs are encrypted with the -# encryption settings below. -# -# If DSE Search index encryption is enabled, DSE Search index files are also encrypted with the settings below. -# If backing C* table encryption is enabled, DSE Search commit log is encrypted with settings below. -# -# When enabling system table encryption on a node with existing data, run -# `nodetool upgradesstables -a` on the listed tables to encrypt existing data -# -# When tracing is enabled, sensitive info will be written into the tables in the -# system_traces keyspace. Those tables should be configured to encrypt their data -# on disk by using an encrypting compressor. -# -# DataStax recommends using remote encryption keys from a KMIP server when using Transparent Data Encryption (TDE) features. -# Local key support is provided when a KMIP server is not available. -system_info_encryption: - enabled: false - cipher_algorithm: AES - secret_key_strength: 128 - chunk_length_kb: 64 - -# # Selects an alternate key provider for local encryption. Useful for using a kmip host as a key provider. -# key_provider: KmipKeyProviderFactory - -# # If KmipKeyProviderFactory is used for system_info_encryption, this specifies the kmip host to be used. -# kmip_host: kmip_host_name - -########################## -# Kmip hosts options -# -# Connection settings for key servers supporting the kmip protocol -# this allows DSE's encryption features to use keys that are not stored -# on the same machine running DSE. -# -# Hosts are configured as : {connection_settings}, which maps a user definable -# name to a set of hosts, truststores, etc used with a particular key server. This name is then -# used when referring to kmip hosts. DSE supports multiple kmip hosts. - -# kmip_hosts: -# # The unique name of this kmip host/cluster which is specified in the table schema. -# host.yourdomain.com: -# -# # Comma-separated list of kmip hosts host[:port] -# # The current implementation of KMIP connection management only supports failover, so all requests will -# # go through a single KMIP server. There is no load balancing. This is because there aren't any KMIP servers -# # available (that we've found) that support read replication, or other strategies for availability. -# # -# # Hosts are tried in the order they appear here. So add them in the same sequence they'll fail over in -# hosts: kmip1.yourdomain.com, kmip2.yourdomain.com -# -# # keystore/truststore info -# keystore_path: /path/to/keystore.jks -# keystore_type: jks -# keystore_password: password -# -# truststore_path: /path/to/truststore.jks, -# truststore_type: jks -# truststore_password: password -# -# # Keys read from the KMIP hosts are cached locally for the period of time specified below. -# # The longer keys are cached, the fewer requests are made to the key server, but the longer -# # it takes for changes (ie: revocation) to propagate to the DSE node -# key_cache_millis: 300000 -# -# # Socket timeout in milliseconds. -# timeout: 1000 - -# # When 'driver' DSE Search will use Solr cursor paging when pagination is enabled by the CQL driver. -# # -# # When 'off' DSE Search will ignore the driver's pagination settings and use normal Solr paging unless: -# # - The current workload is an analytics workload (ex. SearchAnalytics). -# # - The query parameter 'paging' is set to 'driver'. -# # -# # Default is 'off' -# # -# cql_solr_query_paging: off - -# Local settings for tiered storage -# -# Tiered supports multiple disk configurations, which are configured as : , and specified in DDL -# The tiers themselves are unnamed, and are just collections of paths, which need to be defined in the order they're to be used. -# Typically, you'd put your fastest storage in the top tier, and go down from there. -# -# Storage configurations don't need to be homogenous across the cluster, and internally, each node will only make use of the -# the number of tiers it actually has configured, or the number of tiers configured to be used in the DDL, whichever is less. -# -# Although the behavior of the tiered strategy for a given table is configured in the DDL, these settings can -# be overridden locally, per node, by specifying 'local_options' : {:, ...} in a config. This can be useful for testing -# options before deploying cluster wide, or for storage configurations which don't map cleanly to the DDL configuration. -# -# tiered_storage_options: -# strategy1: -# tiers: -# - paths: -# - /mnt1 -# - /mnt2 -# - paths: [ /mnt3, /mnt4 ] -# - paths: [ /mnt5, /mnt6 ] -# -# local_options: -# k1: v1 -# k2: v2 -# -# 'another strategy': -# tiers: [ paths: [ /mnt1 ] ] - -########################## -# DSE Advanced Replication configuration settings -# -# DSE Advanced replication supports one-way distributed data replication from remote -# clusters to central data hubs. -# When conf_driver_password_encryption_enabled: true, the configured passwords (including C* password, SSL keystore/truststore -# password, etc.) stored in the advrep config are expected to be encrypted -# with the dse configuration encryption using the systemkey. The same systemkey -# that was used to create the passwords, must be copied to every node in -# the cluster. -# advanced_replication_options: -# enabled: false -# conf_driver_password_encryption_enabled: false - -# # The directory under which Advanced Replication files (e.g. replication log files) will be stored. -# advanced_replication_directory: /var/lib/cassandra/advrep - -# # The base path that will be prepended to paths in the Advanced Replication -# # configuration locations, including locations to SSL keystore, SSL truststore etc. -# security_base_path: /base/path/to/advrep/security/files/ - -########################## -# These internode_messaging_options configure network services for internal communication -# for all nodes. These settings must be identical on all nodes in the cluster. -internode_messaging_options: - # TCP listen port (mandatory) - port: 8609 - -# # Max message frame length (default 256MB) -# frame_length_in_mb: 256 - -# # Number of server acceptor threads (default is number of available processors) -# server_acceptor_threads: 8 - -# # Number of server worker threads (default is number of available processors * 8) -# server_worker_threads: 16 - -# # Max number of client connections -# client_max_connections: 100 - -# # Number of client worker threads (default is number of available processors * 8) -# client_worker_threads: 16 - -# # Timeout for comm handshake process (default is 10 seconds) -# handshake_timeout_seconds: 10 - -# # Client request timeout, in seconds (default is 60). -# client_request_timeout_seconds: 60 - -########################## -# Graph configuration -# Contains all system-level configuration options and those shared between graph -# instances. -graph: - # The number of stale rows per second to clean from each graph's adjacency cache. - # Value: integer. - adjacency_cache_clean_rate: 1024 - - # The maximum entry size in each graph's adjacency cache. When set to zero, the - # default is calculated based on the cache size and the number of CPUs. Entries - # that would exceed this size are quietly dropped by the cache without producing - # an explicit error or log message. Value: integer. - adjacency_cache_max_entry_size_in_mb: 0 - - # The amount of ram to allocate to each graph's adjacency (edge and property) - # cache. Value: integer. - adjacency_cache_size_in_mb: 128 - - # Maximum time to wait for an analytic (Spark) traversal to evaluate. Value: a - # duration in minutes. - analytic_evaluation_timeout_in_minutes: 10080 - - # Enables or disables Gremlin Server. Value: boolean. - gremlin_server_enabled: true - - # The number of stale entries per second to clean from the adjacency cache. Value: - # integer. - index_cache_clean_rate: 1024 - - # The maximum entry size in the index adjacency cache. When set to zero, the - # default is calculated based on the cache size and the number of CPUs. Entries - # that would exceed this size are quietly dropped by the cache without producing - # an explicit error or log message. Value: integer. - index_cache_max_entry_size_in_mb: 0 - - # The amount of ram to allocate to the index cache. Value: integer. - index_cache_size_in_mb: 128 - - # The maximum number of CQL queries that can be queued as a result of Gremlin - # requests. Incoming queries are rejected if the queue size exceeds this setting. - # Value: integer. - max_query_queue: 10000 - - # The maximum number of threads to use for graph queries on Cassandra. When this - # option is not set, its effective default is 10 times either the gremlinPool - # setting (if gremlinPool is present in this file and nonzero), or the number of - # available CPU cores (if gremlinPool is not present in this file or set to zero). - # The gremlinPool setting lives under the gremlin_server subsection of the graph - # section in dse.yaml. Value: integer. - # max_query_threads (no explicit default) - - # Maximum time to wait for a real-time traversal to evaluate. Value: a duration in - # seconds. - realtime_evaluation_timeout_in_seconds: 30 - - # Maximum time to wait for cassandra to agree on schema versions before timing - # out. Value: a duration in milliseconds. - schema_agreement_timeout_in_ms: 10000 - - # Controls automatic schema creation. Setting this to "Development" permits - # loading graph data without explicitly specifying a graph schema through the - # graph schema API beforehand. Setting this to "Production" requires explicitly - # specifying a graph schema through the graph schema API before loading any - # dependent graph data (vertices, edges, properties). Value: one of Development, - # Production, Default. - schema_mode: Production - - # Maximum time to wait for a graph-system request to evaluate. Creating a new - # graph is an example of a graph-system request. Value: a duration in seconds. - system_evaluation_timeout_in_seconds: 180 - - # The number of samples to keep when aggregating log events. Only a small subset - # of graph'slog statements use this system. Modifying this setting is rarely - # necessary or helpful. Value: integer. - window_size: 100000 - - # The maximum number of parameters that can be passed on a graph query request for both TinkerPop drivers - # and those using the Cassandra native protocol. Generally speaking, it is considered an anti-pattern to - # pass "massive" numbers of parameters on requests, as it increases the script evaluation time. Consider - # other methods for parameterizing scripts (like passing a single Map or List if many arguments are needed) - # prior to increasing this value. Future releases will have this value set at 16. - max_query_params: 256 - - # Configuration options for standard vertex ID assignment and partitioning - # strategies. - ids: - # Graph's standard vertex ID allocator operates on blocks of contiguous IDs. Each - # block is allocated using a Cassandra lightweight transaction, which requires - # coordination latency. To hide the cost of allocating a standard ID block, the - # allocator begins asynchronously buffering a replacement block whenever a current - # block is nearly empty. This parameter defines "nearly empty". It expresses, as - # a floating point number between 0 and 1, how much of a standard ID block can be - # used before graph starts asynchronously allocating its replacement. This - # setting has no effect on custom IDs. Value: double. - block_renew: 0.8 - - # For graphs using standard vertex IDs, if a transaction creates multiple - # vertices, the allocator attempts to assign vertex IDs that colocate vertices on - # the same Cassandra replicas. If an especially large vertex cohort is created, - # the allocator chunks the vertex creation and assigns a random target location to - # avoid load hotspotting. This setting controls the vertex chunk size. The - # setting has no effect on custom IDs. Value: long. - community_reuse: 28 - - # Must be set to either DC_LOCAL or GLOBAL. If set to DC_LOCAL, then - # datacenter_id must be correctly configured on every node in the cluster. If set - # to GLOBAL, then datacenter_id is irrelevant and its value is ignored. This - # option must have the same value on every node in any given cluster. Its value - # can only be changed when the entire cluster is stopped. This setting has no - # effect on custom IDs. Value: one of GLOBAL, DC_LOCAL. - consistency_mode: GLOBAL - - # This option is ignored when consistency_mode is not set to DC_LOCAL. When - # consistency_mode is set to DC_LOCAL, this must be set to an arbitrary value - # between 1 and 127, inclusive. Any given value for this option must appear in at - # most one datacenter whenever consistency_mode is DC_LOCAL. Violating this - # constraint will corrupt the database. This setting has no effect on custom IDs. - # Value: integer. - # datacenter_id (no explicit default) - - # An integer between 1 and 2^24 (both inclusive) that affects maximum ID capacity - # and the maximum storage space used by ID allocations. Lower values reduce both - # storage space consumed and lightweight transaction overhead imposed at startup. - # Lower values also reduce the total number of IDs that can be allocated over the - # life of a graph, because this parameter is proportional to the allocatable ID - # space. However, the proportion coefficient is Long.MAX_VALUE (2^63-1), so ID - # headroom should be sufficient, practically speaking, even if this is set to 1. - # This setting has no effect on custom IDs. Value: integer. - id_hash_modulus: 20 - - # Graph's standard vertex ID allocator claims uniformly-sized blocks of contiguous - # IDs using lightweight transactionson Cassandra. This setting controls the size - # of each block. This setting has no effect on custom IDs. Value: integer. - member_block_size: 512 - - # Contains all registered state listeners identified by their name. - listener: -# # On the following line, "listener_name" is a placeholder string. This can be -# # changed to an arbitrary string composed of lowercase letters, numbers, and -# # underscores, where the string begins with a lowercase letter. -# listener_name: -# # The names of state types that are ignored. All state types but those given are -# # listened to. Value: YAML-formatted list of strings. -# black_types: # This list is empty by default -# -# # The interval in which the state values are logged. Value: a duration in seconds. -# interval_in_seconds: 3600 -# -# # The type of the state listener. Must be one of the following values: slf4j. -# # Value: string. -# type: slf4j -# -# # The names of state types that should be listened. Only those state types are -# # listened to and all others ignored. Value: YAML-formatted list of strings. -# white_types: # This list is empty by default -# - # Configuration options graph's internal query forwarding and lightweight - # messaging system. - msg: - # Graph messages must be acknowledged within this interval, or else the message - # will be assumed dropped/failed. Graph will retry the message or fail the - # responsible request if the retry limit has been exceeded. Value: a duration in - # milliseconds. - graph_msg_timeout_in_ms: 5000 - - # Contains all registered event observers identified by their name. - observer: -# # On the following line, "observer_name" is a placeholder string. This can be -# # changed to an arbitrary string composed of lowercase letters, numbers, and -# # underscores, where the string begins with a lowercase letter. -# observer_name: -# # The names of event types that are ignored. All event types but those given are -# # observed. Value: YAML-formatted list of strings. -# black_types: # This list is empty by default -# -# # The names of the graphs for which events are observed. Value: YAML-formatted -# # list of strings. -# observed_graphs: # This list is empty by default -# -# # Threshold at which slow events get reported. Value: a duration in milliseconds. -# slow_threshold_in_ms: 300000 -# -# # The type of the event observer. Must be one of the following values: slf4j, -# # slow_request. Value: string. -# type: slf4j -# -# # The names of event types that should be observed. Only those event types are -# # observed and all others ignored. Value: YAML-formatted list of strings. -# white_types: # This list is empty by default -# - # Shared data. - shared_data: - # The interval between refreshes. Value: a duration in milliseconds. - refresh_interval_in_ms: 60000 - - gremlin_server: - port: 8182 - - threadPoolWorker: 2 - - # The number of "Gremlin" threads available to execute actual scripts in a ScriptEngine. This pool represents - # the workers available to handle blocking operations in Gremlin Server. When set to zero, this value will - # be defaulted to the value of the JVM property "cassandra.available_processors" (if set) - # or to Runtime.getRuntime().availableProcessors(). - gremlinPool: 0 - maxContentLength: 65536000 - - # The maximum length of the content or each chunk. If the content length exceeds this value, the transfer - # encoding of the decoded request will be converted to chunked and the content will be split into multiple - # HttpContent objects. If the transfer encoding of the HTTP request is chunked already, each chunk will be split - # into smaller chunks if the length of the chunk exceeds this value. - maxChunkSize: 4096000 - - # The maximum length of the initial line (e.g. "GET / HTTP/1.0") processed in a request, which essentially - # controls the maximum length of the submitted URI. - maxInitialLineLength: 4096 - - # The maximum length of all headers. - maxHeaderSize: 8192 - - # Maximum number of request components that can be aggregated for a message. - maxAccumulationBufferComponents: 1024 - - # Defines the size in which the result of a request is "batched" back to the client. In other words, if set to 1, - # then a result that had ten items in it would get each result sent back individually. If set to 2 the same ten - # results would come back in five batches of two each. Note that this value can be overridden per request. - resultIterationBatchSize: 64 - - # Try to use epoll event loops (works only on Linux os) instead of netty NIO. - useEpollEventLoop: false - - # A List of Map settings, where each Map represents a MessageSerializer implementation to use along with its - # configuration. - serializers: - - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistry], classResolverSupplier: com.datastax.bdp.graph.impl.tinkerpop.io.DseClassResolverProvider }} - - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistry], classResolverSupplier: com.datastax.bdp.graph.impl.tinkerpop.io.DseClassResolverProvider }} - - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }} - - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistry] }} - - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2d0, com.datastax.bdp.graph.impl.tinkerpop.io.DseGraphIoRegistryV2d0] }} - - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistry] }} - -# # The gremlin-groovy script engine will always be added even if the configuration option is not present. -# # Additional imports may be added in the configuration for that script engine. -# scriptEngines: -# gremlin-groovy: -# config: -# # To disable the gremlin groovy sandbox entirely -# sandbox_enabled: false -# sandbox_rules: -# -# # To completely whitelist a package add the package name here -# whitelist_packages: -# - package.name -# -# # To whitelist an individual type add the name of the type here -# whitelist_types: -# - fully.qualified.class.name -# -# # To whitelist a super class add the name of the type here -# whitelist_supers: -# - fully.qualified.class.name diff --git a/lib/killrvideo-docker-common/config-secure/remote.yaml b/lib/killrvideo-docker-common/config-secure/remote.yaml deleted file mode 100644 index 052ea60..0000000 --- a/lib/killrvideo-docker-common/config-secure/remote.yaml +++ /dev/null @@ -1,37 +0,0 @@ -hosts: [localhost] -port: 8182 -serializer: { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, - config: { serializeResultToString: true, ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistry] }} -connectionPool: { - enableSsl: false, - # The maximum length in bytes that a message can be sent to the server. This number can be no greater than the - # setting of the same name in the server configuration. - maxContentLength: 65536000, - # The maximum number of in-flight requests that can occur on a connection. - maxInProcessPerConnection: 4, - # The maximum number of times that a connection can be borrowed from the pool simultaneously. - maxSimultaneousUsagePerConnection: 16, - # The maximum size of a connection pool for a host. - maxSize: 8, - # The amount of time in milliseconds to wait for a new connection before timing out. - maxWaitForConnection: 3000, - # The amount of time in milliseconds to wait for a session to close before timing out (does not apply to - # sessionless connections). - maxWaitForSessionClose: 3000, - # The minimum number of in-flight requests that can occur on a connection. - minInProcessPerConnection: 1, - # The maximum number of times that a connection can be borrowed from the pool simultaneously. - minSimultaneousUsagePerConnection: 8, - # The minimum size of a connection pool for a host. - minSize: 2, - # The amount of time in milliseconds to wait before trying to reconnect to a dead host. - reconnectInterval: 1000, - # The override value for the size of the result batches to be returned from the server. - resultIterationBatchSize: 64 -} -# Sets the AuthProperties.Property.JAAS_ENTRY properties for authentication to Gremlin Server. -# jaasEntry: -# Sets the AuthProperties.Property.PROTOCOL properties for authentication to Gremlin Server. -# protocol: -username: cassandra -password: cassandra diff --git a/lib/killrvideo-docker-common/create-environment.ps1 b/lib/killrvideo-docker-common/create-environment.ps1 deleted file mode 100644 index 35ca6a7..0000000 --- a/lib/killrvideo-docker-common/create-environment.ps1 +++ /dev/null @@ -1,76 +0,0 @@ -<# - .DESCRIPTION - Gets the environment variables needed to run the Killrvideo docker-compose commands, then writes - them to a .env file in the working directory or the directory specified by the -Path switch. - - .PARAMETER Path - The path to create the environment file. Defaults to the current working directory. - - .PARAMETER FileName - The name of the environment file. Defaults to ".env". - - .PARAMETER ProjectName - The COMPOSE_PROJECT_NAME value to use. Defaults to "killrvideo". - - .PARAMETER Force - Switch to force creation of the file (i.e. overwrite it) if it already exists. -#> -[CmdletBinding()] -Param ( - [Parameter(Mandatory=$false)] - [string] - $Path = $((Resolve-Path .\).Path), - - [Parameter(Mandatory=$false)] - [string] - $FileName = '.env', - - [Parameter(Mandatory=$false)] - [string] - $ProjectName = 'killrvideo', - - [Parameter(Mandatory=$false)] - [switch] - $Force -) - -$ErrorActionPreference = 'stop' - -# Make sure we have an absolute path -if ([System.IO.Path]::IsPathRooted($Path) -eq $false) { - $cwd = (Resolve-Path .\).Path - $Path = Join-Path $cwd $Path -} - -# Path to the file and does it exist -$envFilePath = Join-Path $Path $FileName -if ((Test-Path $envFilePath) -and ($Force -eq $false)) { - Write-Host "Environment file $(Resolve-Path $envFilePath) already exists, will not overwrite" - Exit -} - -# Make sure the path exists for the .env we're generating -if ((Test-Path $Path) -eq $false) { - New-Item -Path $Path -Type Directory | Out-Null -} - -$scriptPath = Split-Path -parent $PSCommandPath - -# Use the base compose file from this project, plus one that should be in the same location -# as the .env file we're generating -Push-Location $Path -$composeFile = Resolve-Path -Relative "$scriptPath\docker-compose.yaml" -Pop-Location -$composeFile += ";.\docker-compose.yaml" - -# Base environment variables -$dockerEnv = @("COMPOSE_PROJECT_NAME=$ProjectName", "COMPOSE_FILE=$composeFile") - -# Get path to the get-environment script and run it, adding each value to the env array -$getEnvCommand = Resolve-Path "$scriptPath\get-environment.ps1" -& "$getEnvCommand" |% { $dockerEnv += $_ } - -# Write the file (have to use the .NET API here because we need UTF-8 WITHOUT the BOM) -$Utf8NoBom = New-Object System.Text.UTF8Encoding($false) -[System.IO.File]::WriteAllLines($envFilePath, $dockerEnv, $Utf8NoBom) -Write-Host "Environment file written to $(Resolve-Path $envFilePath)" \ No newline at end of file diff --git a/lib/killrvideo-docker-common/create-environment.sh b/lib/killrvideo-docker-common/create-environment.sh deleted file mode 100755 index f5e9a30..0000000 --- a/lib/killrvideo-docker-common/create-environment.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -set -e # Bail if something fails - -# This script tries to create a .env file in the current working directory for -# use with docker-compose. The file contains variables that include info on the -# user's docker setup like the IP address of the Host and VM. - -ENV_FILE_PATH="$PWD/.env" - -# TODO: Don't overwrite file if it already exists? - -# Relative path that contains this script -SCRIPT_PATH=${BASH_SOURCE%/*} - -# Create an alias for the loopback adapter so that the Mac and Docker VM can communicate using that IP -export LOOPBACK_IP='10.0.75.1' -echo 'We need to create an alias for the loopback adapter (lo0) using sudo' -echo 'so your Mac and the Docker VM can communicate. It will be created using' -echo "IP $LOOPBACK_IP. You will be prompted for your password." -if [ `uname` = "Darwin" ] ; then - sudo ifconfig lo0 alias $LOOPBACK_IP -else - sudo ifconfig lo:0 $LOOPBACK_IP/24 -fi - -# Should use compose file relative to this script, followed by a compose file relative to the -# working directory (i.e. where the .env file is going to be created) -COMPOSE_FILE="$SCRIPT_PATH/docker-compose.yaml:./docker-compose.yaml" -COMPOSE_PROJECT_NAME='killrvideo' - -# Get other variables from the get-environment.sh script -GET_ENV_OUTPUT=$(exec $SCRIPT_PATH/get-environment.sh) - -# Write to .env file in current working directory -echo "COMPOSE_PROJECT_NAME=$COMPOSE_PROJECT_NAME -COMPOSE_FILE=$COMPOSE_FILE -$GET_ENV_OUTPUT" > $ENV_FILE_PATH diff --git a/lib/killrvideo-docker-common/docker-compose-ops-center.yaml b/lib/killrvideo-docker-common/docker-compose-ops-center.yaml deleted file mode 100644 index fadf84e..0000000 --- a/lib/killrvideo-docker-common/docker-compose-ops-center.yaml +++ /dev/null @@ -1,69 +0,0 @@ -version: '3' - -# -# docker-compose-ops-center.yaml -# Use this compose file to add DataStax OpsCenter to the standard KillrVideo infrastructure configuration -# - -services: - # Etcd for our service registry - etcd: - image: quay.io/coreos/etcd:v2.3.6 - command: [ -advertise-client-urls, "http://${KILLRVIDEO_DOCKER_IP}:2379", -listen-client-urls, "http://0.0.0.0:2379" ] - ports: - # The client port - - "2379:2379" - environment: - SERVICE_2379_NAME: etcd - - # Registrator to register containers with Etcd - registrator: - image: gliderlabs/registrator:latest - # Tell registrator where the etcd HTTP API is and to use the docker VM's IP - command: [ -ip, "$KILLRVIDEO_DOCKER_IP", "etcd://etcd:2379/killrvideo/services" ] - volumes: - # So registrator can use the docker API to inspect containers - - "/var/run/docker.sock:/tmp/docker.sock" - depends_on: - - etcd - - # DataStax Enterprise - # configure this as the seed node - # start with search and graph modes enabled ("-s -g") - dse: - image: datastax/dse-server:6.0.0 - command: [ -s -g ] - ports: - - "9042:9042" - - "8983:8983" - - "8182:8182" - links: - - opscenter - environment: - DS_LICENSE: accept - # Allow DSE to lock memory with mlock - cap_add: - - IPC_LOCK - ulimits: - memlock: -1 - - # Container to load KillrVideo schema and search config into DSE - # Provides options to configure secure users as well - dse-config: - image: killrvideo/killrvideo-dse-config:1.2.1 - environment: - KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP - KILLRVIDEO_DSE_EXTERNAL_IP: $KILLRVIDEO_DSE_EXTERNAL_IP - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_GRAPH_REPLICATION: $KILLRVIDEO_GRAPH_REPLICATION - depends_on: - - dse - - # OpsCenter - opscenter: - image: datastax/dse-opscenter:6.5.0 - ports: - - "8888:8888" - environment: - SERVICE_8888_NAME: opscenter - DS_LICENSE: accept diff --git a/lib/killrvideo-docker-common/docker-compose-secure.yaml b/lib/killrvideo-docker-common/docker-compose-secure.yaml deleted file mode 100644 index 4d3060b..0000000 --- a/lib/killrvideo-docker-common/docker-compose-secure.yaml +++ /dev/null @@ -1,61 +0,0 @@ -version: '3' - -# -# docker-compose.yaml -# Default compose file for providing basic infrastructure required by KillrVideo -# - -services: - # Etcd for our service registry - etcd: - image: quay.io/coreos/etcd:v2.3.6 - command: [ -advertise-client-urls, "http://${KILLRVIDEO_DOCKER_IP}:2379", -listen-client-urls, "http://0.0.0.0:2379" ] - ports: - # The client port - - "2379:2379" - environment: - SERVICE_2379_NAME: etcd - - # Registrator to register containers with Etcd - registrator: - image: gliderlabs/registrator:latest - # Tell registrator where the etcd HTTP API is and to use the docker VM's IP - command: [ -ip, "$KILLRVIDEO_DOCKER_IP", "etcd://etcd:2379/killrvideo/services" ] - volumes: - # So registrator can use the docker API to inspect containers - - "/var/run/docker.sock:/tmp/docker.sock" - depends_on: - - etcd - - # DataStax Enterprise - # configure this as the seed node - # start with search and graph modes enabled ("-s -g") - dse: - image: datastax/dse-server:6.0.0 - command: [ -s -g ] - ports: - - "9042:9042" - - "8983:8983" - - "8182:8182" - environment: - DS_LICENSE: accept - # Allow DSE to lock memory with mlock - cap_add: - - IPC_LOCK - ulimits: - memlock: -1 - volumes: - # use custom config file with authentication/authorization enabled - - "./extras/config-secure:/config" - - # Container to load KillrVideo schema and search config into DSE - # Provides options to configure secure users as well - dse-config: - image: killrvideo/killrvideo-dse-config:1.2.1 - environment: - KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP - KILLRVIDEO_DSE_EXTERNAL_IP: $KILLRVIDEO_DSE_EXTERNAL_IP - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_GRAPH_REPLICATION: $KILLRVIDEO_GRAPH_REPLICATION - depends_on: - - dse diff --git a/lib/killrvideo-docker-common/docker-compose-studio.yaml b/lib/killrvideo-docker-common/docker-compose-studio.yaml deleted file mode 100644 index 1e1c876..0000000 --- a/lib/killrvideo-docker-common/docker-compose-studio.yaml +++ /dev/null @@ -1,70 +0,0 @@ -version: '3' - -# -# docker-compose-studio.yaml -# Use this compose file to add DSE Studio to the standard KillrVideo infrastructure configuration -# - -services: - # Etcd for our service registry - etcd: - image: quay.io/coreos/etcd:v2.3.6 - command: [ -advertise-client-urls, "http://${KILLRVIDEO_DOCKER_IP}:2379", -listen-client-urls, "http://0.0.0.0:2379" ] - ports: - # The client port - - "2379:2379" - environment: - SERVICE_2379_NAME: etcd - - # Registrator to register containers with Etcd - registrator: - image: gliderlabs/registrator:latest - # Tell registrator where the etcd HTTP API is and to use the docker VM's IP - command: [ -ip, "$KILLRVIDEO_DOCKER_IP", "etcd://etcd:2379/killrvideo/services" ] - volumes: - # So registrator can use the docker API to inspect containers - - "/var/run/docker.sock:/tmp/docker.sock" - depends_on: - - etcd - - # DataStax Enterprise - # configure this as the seed node - # start with search and graph modes enabled ("-s -g") - dse: - image: datastax/dse-server:6.0.0 - command: [ -s -g ] - ports: - - "9042:9042" - - "8983:8983" - - "8182:8182" - environment: - DS_LICENSE: accept - # Allow DSE to lock memory with mlock - cap_add: - - IPC_LOCK - ulimits: - memlock: -1 - - # Container to load KillrVideo schema and search config into DSE - # Provides options to configure secure users as well - dse-config: - image: killrvideo/killrvideo-dse-config:1.2.1 - environment: - KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP - KILLRVIDEO_DSE_EXTERNAL_IP: $KILLRVIDEO_DSE_EXTERNAL_IP - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_GRAPH_REPLICATION: $KILLRVIDEO_GRAPH_REPLICATION - depends_on: - - dse - - # One instance of DataStax Studio - studio: - image: killrvideo/killrvideo-studio:2.1.0 - ports: - # The Web UI exposed to our host - - "9091:9091" - depends_on: - - dse - environment: - SERVICE_9091_NAME: studio - DS_LICENSE: accept diff --git a/lib/killrvideo-docker-common/docker-compose-volumes.yaml b/lib/killrvideo-docker-common/docker-compose-volumes.yaml deleted file mode 100644 index da74c2e..0000000 --- a/lib/killrvideo-docker-common/docker-compose-volumes.yaml +++ /dev/null @@ -1,64 +0,0 @@ -version: '3' - -# -# docker-compose-volumes.yaml -# use this compose file to preserve DSE Cassandra data on a separate volume -# - -services: - # Etcd for our service registry - etcd: - image: quay.io/coreos/etcd:v2.3.6 - command: [ -advertise-client-urls, "http://${KILLRVIDEO_DOCKER_IP}:2379", -listen-client-urls, "http://0.0.0.0:2379" ] - ports: - # The client port - - "2379:2379" - environment: - SERVICE_2379_NAME: etcd - - # Registrator to register containers with Etcd - registrator: - image: gliderlabs/registrator:latest - # Tell registrator where the etcd HTTP API is and to use the docker VM's IP - command: [ -ip, "$KILLRVIDEO_DOCKER_IP", "etcd://etcd:2379/killrvideo/services" ] - volumes: - # So registrator can use the docker API to inspect containers - - "/var/run/docker.sock:/tmp/docker.sock" - depends_on: - - etcd - - # DataStax Enterprise with KillrVideo schema and search config - # configure this as the seed node - # start with search and graph modes enabled ("-s -g") - dse: - image: datastax/dse-server:6.0.0 - command: [ -s -g ] - ports: - - "9042:9042" - - "8983:8983" - - "8182:8182" - environment: - DS_LICENSE: accept - volumes: - # associate dse-data directory under the directory where we run docker-compose - # with the Cassandra data directory on our node - # (using relative paths to store at the root directory of the repository which includes - # these files, i.e. killrvideo-java or killrvideo-nodejs) - - "../../dse-data:/var/lib/cassandra" - # Allow DSE to lock memory with mlock - cap_add: - - IPC_LOCK - ulimits: - memlock: -1 - - # Container to load KillrVideo schema and search config into DSE - # Provides options to configure secure users as well - dse-config: - image: killrvideo/killrvideo-dse-config:1.2.1 - environment: - KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP - KILLRVIDEO_DSE_EXTERNAL_IP: $KILLRVIDEO_DSE_EXTERNAL_IP - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_GRAPH_REPLICATION: $KILLRVIDEO_GRAPH_REPLICATION - depends_on: - - dse diff --git a/lib/killrvideo-docker-common/docker-compose.yaml b/lib/killrvideo-docker-common/docker-compose.yaml deleted file mode 100644 index c470993..0000000 --- a/lib/killrvideo-docker-common/docker-compose.yaml +++ /dev/null @@ -1,59 +0,0 @@ -version: '3' - -# -# docker-compose.yaml -# Default compose file for providing basic infrastructure required by KillrVideo -# - -services: - # Etcd for our service registry - etcd: - image: quay.io/coreos/etcd:v2.3.6 - command: [ -advertise-client-urls, "http://${KILLRVIDEO_DOCKER_IP}:2379", -listen-client-urls, "http://0.0.0.0:2379" ] - ports: - # The client port - - "2379:2379" - environment: - SERVICE_2379_NAME: etcd - - # Registrator to register containers with Etcd - registrator: - image: gliderlabs/registrator:latest - # Tell registrator where the etcd HTTP API is and to use the docker VM's IP - #command: [ -ip, "$KILLRVIDEO_DOCKER_IP", "etcd://etcd:2379/killrvideo/services" ] - command: [ "etcd://etcd:2379/killrvideo/services" ] - volumes: - # So registrator can use the docker API to inspect containers - - "/var/run/docker.sock:/tmp/docker.sock" - depends_on: - - etcd - - # DataStax Enterprise - # configure this as the seed node - # start with search and graph modes enabled ("-s -g") - dse: - image: datastax/dse-server:6.0.0 - command: [ -s -g ] - ports: - - "9042:9042" - - "8983:8983" - - "8182:8182" - environment: - DS_LICENSE: accept - # Allow DSE to lock memory with mlock - cap_add: - - IPC_LOCK - ulimits: - memlock: -1 - - # Container to load KillrVideo schema and search config into DSE - # Provides options to configure secure users as well - dse-config: - image: hadesarchitect/killrvideo-dse-config:disable-loopback - environment: - KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP - KILLRVIDEO_DSE_EXTERNAL_IP: $KILLRVIDEO_DSE_EXTERNAL_IP - KILLRVIDEO_CASSANDRA_REPLICATION: $KILLRVIDEO_CASSANDRA_REPLICATION - KILLRVIDEO_GRAPH_REPLICATION: $KILLRVIDEO_GRAPH_REPLICATION - depends_on: - - dse diff --git a/lib/killrvideo-docker-common/extras/_with_server_and_external_down.sh b/lib/killrvideo-docker-common/extras/_with_server_and_external_down.sh deleted file mode 100755 index 5502f29..0000000 --- a/lib/killrvideo-docker-common/extras/_with_server_and_external_down.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -COMMON_DIR="lib/killrvideo-docker-common" -EXTRAS_DIR="$COMMON_DIR/extras" - -docker-compose -f $COMMON_DIR/docker-compose.yaml -f $EXTRAS_DIR/docker-compose-dse-external.yaml -f docker-compose.yaml -f $EXTRAS_DIR/docker-compose-server.yaml down diff --git a/lib/killrvideo-docker-common/extras/_with_server_and_external_up.sh b/lib/killrvideo-docker-common/extras/_with_server_and_external_up.sh deleted file mode 100755 index 7af2bad..0000000 --- a/lib/killrvideo-docker-common/extras/_with_server_and_external_up.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -COMMON_DIR="lib/killrvideo-docker-common" -EXTRAS_DIR="$COMMON_DIR/extras" - -docker-compose -f $COMMON_DIR/docker-compose.yaml -f $EXTRAS_DIR/docker-compose-dse-external.yaml -f docker-compose.yaml -f $EXTRAS_DIR/docker-compose-server.yaml up -d diff --git a/lib/killrvideo-docker-common/extras/_with_server_down.sh b/lib/killrvideo-docker-common/extras/_with_server_down.sh deleted file mode 100755 index 0e8f3bf..0000000 --- a/lib/killrvideo-docker-common/extras/_with_server_down.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -COMMON_DIR="lib/killrvideo-docker-common" -EXTRAS_DIR="$COMMON_DIR/extras" - -docker-compose -f $COMMON_DIR/docker-compose.yaml -f docker-compose.yaml -f $EXTRAS_DIR/docker-compose-server.yaml down diff --git a/lib/killrvideo-docker-common/extras/_with_server_up.sh b/lib/killrvideo-docker-common/extras/_with_server_up.sh deleted file mode 100755 index a4c6188..0000000 --- a/lib/killrvideo-docker-common/extras/_with_server_up.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -COMMON_DIR="lib/killrvideo-docker-common" -EXTRAS_DIR="$COMMON_DIR/extras" - -docker-compose -f $COMMON_DIR/docker-compose.yaml -f docker-compose.yaml -f $EXTRAS_DIR/docker-compose-server.yaml up -d diff --git a/lib/killrvideo-docker-common/extras/docker-compose-dse-external.yaml b/lib/killrvideo-docker-common/extras/docker-compose-dse-external.yaml deleted file mode 100644 index c039df2..0000000 --- a/lib/killrvideo-docker-common/extras/docker-compose-dse-external.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '3' - -services: - # DataStax Enterprise with KillrVideo schema and search config - dse: - image: killrvideo/killrvideo-dse-external:1.0.6 - cap_add: - - IPC_LOCK - ulimits: - memlock: -1 - environment: - SERVICE_9042_NAME: cassandra - SERVICE_8983_NAME: dse-search - SERVICE_8182_NAME: gremlin - EXTERNAL_CLUSTER_IP: $EXTERNAL_CLUSTER_IP - KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP - USERNAME: $KILLRVIDEO_DSE_USERNAME - PASSWORD: $KILLRVIDEO_DSE_PASSWORD diff --git a/lib/killrvideo-docker-common/extras/docker-compose-server.yaml b/lib/killrvideo-docker-common/extras/docker-compose-server.yaml deleted file mode 100644 index cd04472..0000000 --- a/lib/killrvideo-docker-common/extras/docker-compose-server.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: '3' - -# Other services are specified in .\lib\killrvideo-docker-common\docker-compose.yaml -# This is a helper docker service used to run the various language versions in a headless state. -# The default as you see it is set to using killrvideo-java-server, but could as easily be killrvideo-nodejs-server or some other version as long as an image is built. -services: - server: - image: killrvideo/killrvideo-java-server - ports: - - "8899:8899" - depends_on: - - dse - - etcd - - web - environment: - KILLRVIDEO_HOST_IP: $KILLRVIDEO_HOST_IP - KILLRVIDEO_DOCKER_IP: $KILLRVIDEO_DOCKER_IP - KILLRVIDEO_DSE_USERNAME: $KILLRVIDEO_DSE_USERNAME - KILLRVIDEO_DSE_PASSWORD: $KILLRVIDEO_DSE_PASSWORD diff --git a/lib/killrvideo-docker-common/get-environment.ps1 b/lib/killrvideo-docker-common/get-environment.ps1 deleted file mode 100644 index ffd4222..0000000 --- a/lib/killrvideo-docker-common/get-environment.ps1 +++ /dev/null @@ -1,63 +0,0 @@ -<# - .DESCRIPTION - Gets the environment variables needed to run the Killrvideo docker-compose commands and outputs - them to stdout. -#> -[CmdletBinding()] -Param () - -# Figure out if we're Docker for Windows or Docker Toolbox setup -Write-Host 'Determining docker installation type' - -# Docker toolbox sets an install path environment variable so check for it -$isToolbox = $false -if ($Env:DOCKER_TOOLBOX_INSTALL_PATH) { - $isToolbox = $true -} - -Write-Verbose " => Is Docker Toolbox: $isToolbox" - -# Do things differently for Toolbox vs Docker for Windows -if ($isToolbox) { - # See if the docker VM is running - & docker-machine status default | Tee-Object -Variable dockerMachineStatus | Out-Null - if ($dockerMachineStatus -ne 'Running') { - & docker-machine start default | Out-Null - } - - # Add environment to this shell - & docker-machine env | Invoke-Expression -} - -# Determine the Docker VM's IP address -Write-Host 'Getting Docker VM IP' -if ($isToolbox) { - # Just use the command that comes with docker-machine - & docker-machine ip | Tee-Object -Variable dockerIp | Out-Null -} else { - # The VM's IP should be the IP address for eth0 when running a container in host networking mode - $dockerIpCmd = "ip -4 addr show scope global dev eth0 | grep inet | awk `'{print `$2}`' | cut -d / -f 1" - & docker run --rm --net=host busybox bin/sh -c $dockerIpCmd | Tee-Object -Variable dockerIp | Out-Null -} -Write-Verbose " => Got Docker IP: $dockerIp" - -# Determine the VM host's IP address -Write-Host 'Getting corresponding local machine IP' -if ($isToolbox) { - # The host only CIDR address will contain the host's IP (along with a suffix like /24) - & docker-machine inspect --format '{{ .Driver.HostOnlyCIDR }}' default | - Tee-Object -Variable hostCidr | - Out-Null - $hostIp = $hostCidr -replace "\/\d{2}", "" -} else { - # The host's IP should be the default route for eth0 when running a container in host networking mode - $hostIpCmd = "ip -4 route list dev eth0 0/0 | cut -d `' `' -f 3" - & docker run --rm --net=host busybox bin/sh -c $hostIpCmd | Tee-Object -Variable hostIp | Out-Null -} -Write-Verbose " => Got Host IP: $hostIp" - -# Write environment variable pairs to stdout (so this can be piped to a file) -Write-Output "KILLRVIDEO_DOCKER_TOOLBOX=$($isToolbox.ToString().ToLower())" -Write-Output "KILLRVIDEO_HOST_IP=$hostIp" -Write-Output "KILLRVIDEO_DOCKER_IP=$dockerIp" - diff --git a/lib/killrvideo-docker-common/get-environment.sh b/lib/killrvideo-docker-common/get-environment.sh deleted file mode 100755 index 75d37cb..0000000 --- a/lib/killrvideo-docker-common/get-environment.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -set -e # Bail if something fails - -# This script will try and detect a user's docker setup and write some environment -# variable pairs to stdout. The stdout output from this script can then be used to, -# for example, create a .env file for use with docker-compose - -# TODO: Determine if a Docker Toolbox setup -IS_TOOLBOX=false - -if [ "$IS_TOOLBOX" = true ]; then - # Make sure default docker machine is started - STATUS=$(docker-machine status default) - if [ "$STATUS" != "Running" ]; then - docker-machine start default > /dev/null - fi - - # Load docker machine env into this shell - eval $(docker-machine env default) -fi - -# Get the docker VM's IP address -if [ "$IS_TOOLBOX" = true ]; then - # Just use the command that comes with docker-machine - DOCKER_IP=$(docker-machine ip) -else - # The create-environment.sh script should have setup a loopback alias, so use that IP - DOCKER_IP=$LOOPBACK_IP -fi - -# Get the docker VM Host's IP address -if [ "$IS_TOOLBOX" = true ]; then - # The host only CIDR address will contain the host's IP (along with a suffix like /24) - HOST_IP=$(docker-machine inspect --format '{{ .Driver.HostOnlyCIDR }}' default) - # Remove suffix - HOST_IP=${HOST_IP//\/[[:digit:]][[:digit:]]/} -else - # The create-environment.sh script should have setup a loopback alias, so use that IP - HOST_IP=$LOOPBACK_IP -fi - -# Write values to stdout -echo "KILLRVIDEO_DOCKER_TOOLBOX=$IS_TOOLBOX" -echo "KILLRVIDEO_HOST_IP=$HOST_IP" -echo "KILLRVIDEO_DOCKER_IP=$DOCKER_IP" \ No newline at end of file From 8418f694f9fc8c2d0f7766c0c7dc19902d8a7853 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 27 Jan 2019 14:31:23 +0100 Subject: [PATCH 04/12] K8S Rework --- .dockerignore | 1 - README.md | 2 +- config/services.json | 37 ++++++++++ npm-shrinkwrap.json | 24 +++++-- setup-docker.bat | 27 -------- setup-docker.sh | 18 ----- src/common/cassandra.js | 14 ++-- src/common/config.js | 69 +++---------------- src/common/extendable-error.js | 13 ++++ src/common/service-discovery.js | 41 ++++++----- src/index.js | 10 +-- src/server-listeners/index.js | 3 - .../register-with-service-discovery.js | 64 ----------------- src/services/search/get-query-suggestions.js | 5 +- .../suggested-videos/get-related-videos.js | 8 +-- 15 files changed, 116 insertions(+), 220 deletions(-) delete mode 100644 .dockerignore create mode 100644 config/services.json delete mode 100644 setup-docker.bat delete mode 100755 setup-docker.sh create mode 100644 src/common/extendable-error.js delete mode 100644 src/server-listeners/register-with-service-discovery.js diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 3c3629e..0000000 --- a/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/README.md b/README.md index e470b0c..8a8d62c 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,4 @@ open an issue here on GitHub or send a message to [@LukeTillman][twitter] on Twi [killrvideo]: https://killrvideo.github.io/ [getting-started]: https://killrvideo.github.io/getting-started/ [getting-started-node]: https://killrvideo.github.io/docs/languages/nodejs/ -[twitter]: https://twitter.com/LukeTillman \ No newline at end of file +[twitter]: https://twitter.com/LukeTillman diff --git a/config/services.json b/config/services.json new file mode 100644 index 0000000..22f2861 --- /dev/null +++ b/config/services.json @@ -0,0 +1,37 @@ +{ + "services": { + "web": [ + "web:3000" + ], + "cassandra": [ + "dse" + ], + "dse-search": [ + "dse:8983" + ], + "UploadsService": [ + "backend:50101" + ], + "RatingsService": [ + "backend:50101" + ], + "CommentsService": [ + "backend:50101" + ], + "SearchService": [ + "backend:50101" + ], + "StatisticsService": [ + "backend:50101" + ], + "VideoCatalogService": [ + "backend:50101" + ], + "UserManagementService": [ + "backend:50101" + ], + "SuggestedVideoService": [ + "backend:50101" + ] + } +} diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index d617284..1b76dea 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2624,7 +2624,8 @@ "balanced-match": { "version": "0.4.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "bcrypt-pbkdf": { "version": "1.0.1", @@ -2657,6 +2658,7 @@ "version": "1.1.7", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^0.4.1", "concat-map": "0.0.1" @@ -2698,7 +2700,8 @@ "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", @@ -2806,7 +2809,8 @@ "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "fstream": { "version": "1.0.11", @@ -2868,6 +2872,7 @@ "version": "7.1.2", "bundled": true, "dev": true, + "optional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2938,6 +2943,7 @@ "version": "1.0.6", "bundled": true, "dev": true, + "optional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2946,7 +2952,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.4", @@ -3062,6 +3069,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "1.1.7" } @@ -3148,6 +3156,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3177,7 +3186,8 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "performance-now": { "version": "0.2.0", @@ -3272,6 +3282,7 @@ "version": "2.6.1", "bundled": true, "dev": true, + "optional": true, "requires": { "glob": "^7.0.5" } @@ -3465,7 +3476,8 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/setup-docker.bat b/setup-docker.bat deleted file mode 100644 index f66f1d9..0000000 --- a/setup-docker.bat +++ /dev/null @@ -1,27 +0,0 @@ -@echo off - -REM Make sure we have a .env file -powershell -NonInteractive -ExecutionPolicy Unrestricted -File .\lib\killrvideo-docker-common\create-environment.ps1 -Force - -if %errorlevel% neq 0 exit /b %errorlevel% - -REM Figure out if we're in a Docker Toolbox environment -for /F "delims== tokens=1,2" %%i in (.env) do ( - if %%i equ KILLRVIDEO_DOCKER_TOOLBOX set is_toolbox=%%j -) - -REM If so, load docker-machine environment variables so pull will work -if %is_toolbox% equ true ( - @FOR /f "tokens=*" %%i IN ('docker-machine env') DO @%%i -) - -echo. -echo Pulling all docker dependencies - -REM Pull dependencies -docker-compose pull - -if %errorlevel% neq 0 exit /b %errorlevel% - -echo. -echo You can now start docker dependencies with 'docker-compose up -d' \ No newline at end of file diff --git a/setup-docker.sh b/setup-docker.sh deleted file mode 100755 index 977c146..0000000 --- a/setup-docker.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -set -e # Bail if something fails - -# Create the .env file -echo 'Creating docker .env file (this may take a minute)' -echo -./lib/killrvideo-docker-common/create-environment.sh - -echo -echo 'Pulling all docker dependencies' -echo - -# Pull all docker dependencies -docker-compose pull - -echo -echo "You can now start docker dependencies with 'docker-compose up -d'" diff --git a/src/common/cassandra.js b/src/common/cassandra.js index 3c345bf..33c45e2 100644 --- a/src/common/cassandra.js +++ b/src/common/cassandra.js @@ -1,6 +1,6 @@ import Promise from 'bluebird'; import { Client, types as CassandraTypes } from 'cassandra-driver'; -import { lookupService } from './service-discovery'; +import { lookupServiceAsync } from './service-discovery'; import { withRetries } from './with-retries'; import { logger } from './logging'; @@ -9,10 +9,12 @@ import { logger } from './logging'; * specified. Returns a Promise of the created client. */ function createClientAsync(keyspace, queryOptions) { - let client = new Client({ 'contactPoints': [lookupService('cassandra')], keyspace, queryOptions }); - Promise.promisifyAll(client); // This creates "Async" versions of methods that return promises - - return new Promise (function(resolve, reject){resolve(client)}); + return lookupServiceAsync('cassandra') + .then(contactPoints => { + let client = new Client({ contactPoints, keyspace, queryOptions }); + Promise.promisifyAll(client); // This creates "Async" versions of methods that return promises + return client; + }); } // A singleton client instance to be reused throughout the application @@ -51,4 +53,4 @@ export function initCassandraAsync() { clientInstance = client; logger.log('info', 'Cassandra initialized') }); -}; \ No newline at end of file +}; diff --git a/src/common/config.js b/src/common/config.js index 1c12ebe..89f6088 100644 --- a/src/common/config.js +++ b/src/common/config.js @@ -1,49 +1,4 @@ import convict from 'convict'; -import { isIP } from 'net'; -import dotenv from 'dotenv'; -import { resolve } from 'path'; - -// Load environment variables from docker's .env file if present -dotenv.config({ path: resolve(__dirname, '../../.env')}); - -// Create config for a local docker environment -const dockerConf = convict({ - hostIp: { - doc: 'The IP address of the host', - format: 'ipaddress', - default: undefined, - env: 'KILLRVIDEO_HOST_IP' - }, - - dockerIp: { - doc: 'The IP address for the docker VM', - format: 'ipaddress', - default: undefined, - env: 'KILLRVIDEO_DOCKER_IP' - } -}); - -dockerConf.validate(); - -// Custom format to allow falling back to IP addresses from the docker config -convict.addFormat({ - name: 'docker-fallback-ip', - validate(val) { - // Validate is IP v4 or v6 address - if (isIP(val) === 0) { - throw new Error('must be an IP address'); - } - }, - coerce(val, config) { - // Replace ${token} with dockerConf.get('token') value - return val.replace(/\$\{([\w\.]+)}/g, (match, dockerConfig) => { - if (dockerConf.has(dockerConfig) === false) { - return ''; - } - return dockerConf.get(dockerConfig); - }); - } -}); // Create application config const conf = convict({ @@ -75,6 +30,12 @@ const conf = convict({ env: 'NODE_APP_INSTANCE' }, + services: { + doc: 'Service definitions', + format: 'Object', + default: {} + }, + listen: { ip: { doc: 'The IP address for Grpc services to listen on', @@ -89,25 +50,11 @@ const conf = convict({ default: 50101, env: 'KILLRVIDEO_LISTEN_PORT' } - }, - - broadcast: { - ip: { - doc: 'The IP address to broadcast for Grpc services (i.e. register with service discovery)', - format: String, - default: 'backend', - env: 'KILLRVIDEO_BROADCAST_IP' - }, - - port: { - doc: 'The Port to broadcast for Grpc services (i.e. register with service discovery)', - format: 'port', - default: 50101, - env: 'KILLRVIDEO_BROADCAST_PORT' - } } }); +conf.loadFile('./config/services.json'); + // Validate the config and export it conf.validate(); diff --git a/src/common/extendable-error.js b/src/common/extendable-error.js new file mode 100644 index 0000000..c6f53a5 --- /dev/null +++ b/src/common/extendable-error.js @@ -0,0 +1,13 @@ +/** + * An ES6 class that can be used to create custom error classes + */ +export class ExtendableError extends Error { + constructor(message) { + super(); + this.message = message; + this.stack = (new Error()).stack; + this.name = this.constructor.name; + } +}; + +export default ExtendableError; \ No newline at end of file diff --git a/src/common/service-discovery.js b/src/common/service-discovery.js index 53bafcb..b756ab2 100644 --- a/src/common/service-discovery.js +++ b/src/common/service-discovery.js @@ -1,32 +1,31 @@ import { logger } from './logging'; +import Promise from 'bluebird'; +import { ExtendableError } from './extendable-error'; import config from './config'; -let registry = { - 'dse-search': 'dse:8983', - 'web': 'web:3000', - 'cassandra': 'dse:9042' -}; +let registry = config.get('services'); /** - * Looks up a service by name. Returns host:port string value. + * Error thrown when a service can't be found */ -export function lookupService(serviceName) { - logger.log('debug', `Found service ${serviceName} at ${registry[serviceName]}`); - return registry[serviceName]; +export class ServiceNotFoundError extends ExtendableError { + constructor(serviceName) { + super(`Could not find service ${serviceName}`); + } }; /** - * Registers a service at the host and port specified. + * Looks up a service with a given name. Returns a Promise with an array of strings in the format of 'ip:port' or throws ServiceNotFoundError. */ -export function registerService(serviceName, hostAndPort) { - registry[serviceName] = hostAndPort; - logger.log('debug', `Registered service ${serviceName} at ${hostAndPort}`); -}; +export function lookupServiceAsync(serviceName) { + logger.log('verbose', `Looking up service ${serviceName}`); -/** - * Removes a service from the registry. - */ -export function removeService(serviceName) { - delete registry[serviceName]; - logger.log('debug', `Removed service ${serviceName}`); -}; \ No newline at end of file + if (!(serviceName in registry)) { + logger.log('error', `Found no service ${serviceName}`); + throw new ServiceNotFoundError(serviceName); + } + + logger.log('verbose', `Found service ${serviceName} at ${registry[serviceName]}`); + + return new Promise (function(resolve, reject){resolve(registry[serviceName])}); +}; diff --git a/src/index.js b/src/index.js index c106fc0..ef3a60d 100644 --- a/src/index.js +++ b/src/index.js @@ -7,7 +7,7 @@ import Promise from 'bluebird'; import config from './common/config'; import { initCassandraAsync } from './common/cassandra'; import { logger, setLoggingLevel } from './common/logging'; -import { lookupService } from './common/service-discovery'; +import { lookupServiceAsync } from './common/service-discovery'; import { subscribeAsync } from './common/message-bus'; import { GrpcServer } from './grpc/server'; import { services } from './services'; @@ -45,9 +45,9 @@ function startAsync() { // Wait for all subscriptions to finish .all() // Find the web UI's host and port - .then(() => lookupService('web')) + .then(() => lookupServiceAsync('web')) // Start the Grpc server to process requests - .then(webIpAndPort => { + .then(webIpAndPorts => { // Create a Grpc server and register all listeners logger.log('info', 'Starting all Grpc services'); @@ -56,7 +56,7 @@ function startAsync() { // Start the server and return it server.start(); - logger.log('info', `Open http://${webIpAndPort} in a web browser to see the UI`); + logger.log('info', `Open http://${webIpAndPorts[0]} in a web browser to see the UI`); logger.log('info', 'KillrVideo has started. Press Ctrl+C to exit.'); return server; }) @@ -95,4 +95,4 @@ if (process.platform === 'win32') { output: process.stdout }) .on('SIGINT', () => process.emit('SIGINT')); -} \ No newline at end of file +} diff --git a/src/server-listeners/index.js b/src/server-listeners/index.js index c1b350b..e449569 100644 --- a/src/server-listeners/index.js +++ b/src/server-listeners/index.js @@ -1,13 +1,10 @@ import { logServices } from './log-services'; -import { register, remove } from './register-with-service-discovery'; /** * An array of all listener registration functions that want to subscribe to Grpc server events. */ export const listeners = [ logServices, - register, - remove ]; export default listeners; \ No newline at end of file diff --git a/src/server-listeners/register-with-service-discovery.js b/src/server-listeners/register-with-service-discovery.js deleted file mode 100644 index d2b2352..0000000 --- a/src/server-listeners/register-with-service-discovery.js +++ /dev/null @@ -1,64 +0,0 @@ -import Promise from 'bluebird'; -import { registerService, removeService } from '../common/service-discovery' -import { withRetries } from '../common/with-retries'; -import config from '../common/config'; -import {serviceNameFromDefinition} from '../services'; - -function getAppUniqueId() { - // Use app name and instance number to set a unique id for the app - let appName = config.get('appName'); - let appInstance = config.get('appInstance'); - return `${appName}:${appInstance}`; -} - -let startStopPromise = null; - -/** - * Register all services with etcd for service discovery on start. - */ -export function register(grpcServer) { - // Use broadcast address when registering with service discovery - let broadcast = config.get('broadcast'); - let ipAndPort = `${broadcast.ip}:${broadcast.port}`; - - grpcServer.on('start', function registerOnStart(services) { - let uniqueId = getAppUniqueId(); - - // Cancel any previous attempts if still around - if (startStopPromise !== null) { - startStopPromise.cancel(); - } - - // Register each service - let startServices = services.map(s => { - let name = serviceNameFromDefinition(s); - // let registerFn = () => registerService(name, ipAndPort); - return withRetries(() => new Promise(function(resolve, reject) {resolve(registerService(name, ipAndPort))}), Infinity, 5, `Could not register ${name} in service registry`, false); - }); - startStopPromise = Promise.all(startServices).tap(() => { startStopPromise = null; }) - }); -}; - -let stopPromise = null; - -/** - * Remove all services from etcd on stop. - */ -export function remove(grpcServer) { - grpcServer.on('stop', function removeOnStop(services) { - let uniqueId = getAppUniqueId(); - - // Cancel any previous attempts - if (startStopPromise !== null) { - startStopPromise.cancel(); - } - - // Remove each service from etcd - let stopServices = services.map(s => { - let name = serviceNameFromDefinition(s); - let removeFn = () => removeService(name); - return withRetries(removeFn, Infinity, 5, `Could not remove ${name} from service registry`, false); - }); - startStopPromise = Promise.all(stopServices).tap(() => { startStopPromise = null; }); - }); -}; diff --git a/src/services/search/get-query-suggestions.js b/src/services/search/get-query-suggestions.js index b11bcd5..71cce9f 100644 --- a/src/services/search/get-query-suggestions.js +++ b/src/services/search/get-query-suggestions.js @@ -1,7 +1,7 @@ import Promise from 'bluebird'; import rp from 'request-promise'; import config from '../../common/config'; -import { lookupService } from '../../common/service-discovery'; +import { lookupServiceAsync } from '../../common/service-discovery'; import { getCassandraClient } from '../../common/cassandra'; import { NotImplementedError } from '../common/grpc-errors'; import { GetQuerySuggestionsResponse } from './protos'; @@ -44,7 +44,7 @@ let getSearchClientPromise = null; function getSearchClientAsync() { if (getSearchClientPromise === null) { - getSearchClientPromise = lookupService('dse-search') + getSearchClientPromise = lookupServiceAsync('dse-search') .then(hostAndPorts => { // Just use the first host:port returned return rp.defaults({ @@ -90,4 +90,3 @@ async function getQuerySuggestionsWithDseSearch(call) { suggestions: searchResponse.suggest.searchSuggester[request.query].suggestions.map(s => s.term) }); } - diff --git a/src/services/suggested-videos/get-related-videos.js b/src/services/suggested-videos/get-related-videos.js index 90bd85d..368e84a 100644 --- a/src/services/suggested-videos/get-related-videos.js +++ b/src/services/suggested-videos/get-related-videos.js @@ -1,6 +1,6 @@ import Promise from 'bluebird'; import rp from 'request-promise'; -import { lookupService } from '../../common/service-discovery'; +import { lookupServiceAsync } from '../../common/service-discovery'; import { getCassandraClient } from '../../common/cassandra'; import config from '../../common/config'; import { toCassandraUuid, toProtobufUuid, toProtobufTimestamp } from '../common/protobuf-conversions'; @@ -144,11 +144,11 @@ let getSearchClientPromise = null; function getSearchClientAsync() { if (getSearchClientPromise === null) { - let searchLocation = lookupService('dse-search') - getSearchClientPromise = new Promise (function(resolve, reject){resolve(searchLocation)}) + getSearchClientPromise = lookupServiceAsync('dse-search') .then(hostAndPorts => { + // Just use the first host:port returned return rp.defaults({ - baseUrl: `http://${hostAndPorts}/solr` + baseUrl: `http://${hostAndPorts[0]}/solr` }); }) .catch(err => { From 05b626b2fb96be9abd5e718d8b746bdb68928731 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 27 Jan 2019 14:31:59 +0100 Subject: [PATCH 05/12] Fixed docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a8d62c..90ae22c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ services. Learn more at [killrvideo.github.io][killrvideo]. ## Running Locally using Docker -Development should be pretty straight-forward if you are familiar with docker and docker-compose +Running should be pretty straight-forward if you are familiar with docker and docker-compose ``` > docker-compose pull From bd8ac7322a3c55acf706c98aa457636a81c61b10 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 27 Jan 2019 14:38:55 +0100 Subject: [PATCH 06/12] Added Travis CI config --- .travis.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0b3357f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +language: node_js +node_js: +- "8" + +# Sudo required for doing docker build +sudo: required +services: +- docker + +# Build the app and a docker image +script: +- docker build -t ${TRAVIS_COMMIT} . + +# If successful, see if we need to publish also +after_success: +- test -z $TRAVIS_TAG && travis_terminate 0 +- docker tag ${TRAVIS_COMMIT} killrvideo/killrvideo-nodejs:${TRAVIS_TAG} +- docker login -u $DOCKER_USER -p $DOCKER_PASS +- docker push killrvideo/killrvideo-nodejs:${TRAVIS_TAG} + +env: + global: + # DOCKER_USER + - secure: hL9GzKnAuHP130bLzB1nK9eF6bfPD4yFdQ1IdRRp7QDZ+AJ2MUw483w5Uacw6/VNk+KlItO9ySxkAI8gaBcxjxcp+TmFkmD0o4rRQixCoZiqlNeTCMmkx5J6KffNALiFBFPjOvVNXLEYh6lbyIsPJR0/eHGlhCbfpx9Ok9PxzVV4AtNNXVcqCl4hZFWPU8OX7nL0pyQ86MD1WiC/1nfTaE/9zaZ8M/qJhv558KmsSXnFN1eGrwVJLt8XPbZ5aKEvJq3cngwVJ3/hmMQnA6ScgANZFbFrDZo9gDmQLDAbGzQ4mg1wpmvdCGB9HEo14o+ZK3utmnURZDGLHcbgKitIp7fd+FyIktxF3h+hYm7yMV/P67ixLXWxay9F0XXkKF1CPhRU+uEijcWQY/txUItvfHJtDGQbHhChUPmzv2eTQD5QoevFByZ6c3ekQew6hgCPaOsV2FspQQ+XVtdjiiOzmWzeFux2Obc46K85BSyeEp9SjuTJ0772dFBZjWn9UP+M5B8THs4BNPhkSVhceHQBvv65H8DZYEazue0aJYwJhMd1qx5tq/3dXItyDVqxCj0J0LFI4TsFbSf4R+snYOxjc2dkpO1l9aZyLNBTbRn//MTki8o/tdIjAzNYKKWHHBWCYN7OU4Ej4t7XI/SKs3Wf131ebqLlTYU0ppJD7KQUvCU= + # DOCKER_PASS + - secure: hxakhOfACkkXcGc5T9cT0+a+ICw6X2ybsOXzJsgdju4QbdP0nD2iBSZCypDzfdzlF/y83yJGcSznegMega37ABomPd8BF04IJTY1ZSvfj8LiUiLLfo/YSsz68r/X1G/AxVmS/7x9x5xaCPMnCHaH2jK5Qiogawzlqgqw/h3EAQlnJyKdjwwmFpATUAuRJidQ/95pn4KYvERg3eZ7/DzqbAO4IRjSuxHRNqDsHXDR4xlBxXAwqt0SE9qfr8rIbuA264vwStltPi4RDfTWWBooxFTGWHpu7rS/N1xEg7+48Il0zckVqmbwMJeAfl8abXhqK5RRrpv77icHeqxi5bev/SL28PnNOhj5gXn6a4/1/JPuhzmKp1omNtlJsjjZhs7YidSOVQ2nEJjDoeQ9/d+Z+g6DosnkDbiS7+ijvIPD9SlRbyUlf7Z3wD8Hf91/fUgkaUoIVkBUFvW8i0fArfcWSIQErvixIGhj41yNOwIAheUFM4Y39NsuilJZZmqZ2Zh0/9AHUiY4fA7C6CajFC06CpjUCpDhb3m0uy1vJcUiG7Y3J6iTrRzaW8eqPnGBQcVTS7/dXPj3WtEP/xOF93sYeZMKE7hk489WAUJNLV9kmasSaVTzbu80kfM5Ml9m675dN3ztUAhaAPT0IqHnycngMBKe2Y7+EDalsDBsffOpO0k= From 2d47f4d1f609e66ad9db93b61b80cd8949fa1da6 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 27 Jan 2019 14:49:19 +0100 Subject: [PATCH 07/12] Fixed travis build config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0b3357f..9ab0d0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ script: after_success: - test -z $TRAVIS_TAG && travis_terminate 0 - docker tag ${TRAVIS_COMMIT} killrvideo/killrvideo-nodejs:${TRAVIS_TAG} -- docker login -u $DOCKER_USER -p $DOCKER_PASS +- echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin - docker push killrvideo/killrvideo-nodejs:${TRAVIS_TAG} env: From 38ad10a560e2354b0374a0773375bdcd35a75482 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Fri, 8 Feb 2019 14:36:40 +0100 Subject: [PATCH 08/12] Up docker images to latest version --- docker-compose.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 3c1c574..e97533f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,7 +12,7 @@ services: # Datastax Enterprise dse: - image: datastax/dse-server:6.0.0 + image: datastax/dse-server:6.7.0 command: [ -s -g ] ports: - "9042:9042" @@ -38,7 +38,7 @@ services: # DSE Configurator to setup DSE dse-config: - image: killrvideo/killrvideo-dse-config:2.2.1 + image: killrvideo/killrvideo-dse-config:2.2.2-rc2 environment: KILLRVIDEO_SERVICE_DISCOVERY_DISABLED: 'true' depends_on: @@ -55,7 +55,7 @@ services: # DataStax Studio studio: - image: killrvideo/killrvideo-studio:2.0.0 + image: datastax/dse-studio:6.7.0 ports: - "9091:9091" depends_on: From 35dbc3cc04d7ed8bd5d2491e91aa99e3d5e96cd2 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 10 Mar 2019 15:30:41 +0100 Subject: [PATCH 09/12] Exctracted env vars to env file --- docker-compose.yaml | 19 +++++++++---------- killrvideo.env | 4 ++++ 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 killrvideo.env diff --git a/docker-compose.yaml b/docker-compose.yaml index e97533f..25c56fe 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,8 +7,9 @@ services: - .:/usr/src/app depends_on: - dse + env_file: ./killrvideo.env environment: - KILLRVIDEO_LOGGING_LEVEL: debug + NODE_ENV: development # Datastax Enterprise dse: @@ -18,6 +19,7 @@ services: - "9042:9042" - "8983:8983" - "8182:8182" + env_file: ./killrvideo.env environment: DS_LICENSE: accept # Allow DSE to lock memory with mlock @@ -29,29 +31,26 @@ services: # Frontend web: image: killrvideo/killrvideo-web:3.0.0-rc1 + env_file: ./killrvideo.env ports: - - "3000:3000" + - "3000:3000" depends_on: - - dse - environment: - KILLRVIDEO_LOGGING_LEVEL: debug + - dse # DSE Configurator to setup DSE dse-config: - image: killrvideo/killrvideo-dse-config:2.2.2-rc2 - environment: - KILLRVIDEO_SERVICE_DISCOVERY_DISABLED: 'true' + image: killrvideo/killrvideo-dse-config:3.0.0-rc1 + env_file: ./killrvideo.env depends_on: - dse # Sample Data Generator generator: image: killrvideo/killrvideo-generator:3.0.0-rc4 + env_file: ./killrvideo.env depends_on: - dse - backend - environment: - KILLRVIDEO_LOGGING_LEVEL: debug # DataStax Studio studio: diff --git a/killrvideo.env b/killrvideo.env new file mode 100644 index 0000000..317c6ef --- /dev/null +++ b/killrvideo.env @@ -0,0 +1,4 @@ +KILLRVIDEO_DSE_USERNAME=cassandra +KILLRVIDEO_DSE_PASSWORD=cassandra +KILLRVIDEO_LOGGING_LEVEL=debug +DS_LICENSE: accept From faf4234d3a5f12f4e3f3ef3742b5f6aa57b47be3 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 10 Mar 2019 15:32:01 +0100 Subject: [PATCH 10/12] Added suppressError argument to withRetries --- src/common/with-retries.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/common/with-retries.js b/src/common/with-retries.js index 17d1230..701ebc5 100644 --- a/src/common/with-retries.js +++ b/src/common/with-retries.js @@ -4,7 +4,7 @@ import { logger } from './logging'; /** * Do a promise returning function with retries. */ -export function withRetries(promiseFn, maxRetries, delaySeconds, errMsg, expBackoff) { +export function withRetries(promiseFn, maxRetries, delaySeconds, errMsg, expBackoff, suppressError = false) { let retryCount = 0; function doIt() { @@ -22,8 +22,11 @@ export function withRetries(promiseFn, maxRetries, delaySeconds, errMsg, expBack // Log, delay, and try again retryCount++; - logger.log('debug', '', err); logger.log('verbose', `${errMsg}. Retry ${retryCount} in ${delayMs}ms.`); + if (! suppressError) { + logger.log('debug', '', err); + } + return Promise.delay(delayMs).then(doIt); }); } From 630280db599c92da3a4c41c40ed830f92eb56d68 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 10 Mar 2019 15:33:35 +0100 Subject: [PATCH 11/12] Versions up --- .gitignore | 2 +- npm-shrinkwrap.json | 29 +++++++---------------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 71331d9..8e6bef3 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,4 @@ node_modules .env # Webstorm/IDEA -.idea \ No newline at end of file +.idea diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 1b76dea..710445a 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2572,8 +2572,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.1.1", @@ -2809,14 +2808,12 @@ "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "fstream": { "version": "1.0.11", "bundled": true, "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -2872,7 +2869,6 @@ "version": "7.1.2", "bundled": true, "dev": true, - "optional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2885,8 +2881,7 @@ "graceful-fs": { "version": "4.1.11", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "har-schema": { "version": "1.0.5", @@ -2925,8 +2920,7 @@ "hoek": { "version": "2.16.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "http-signature": { "version": "1.1.1", @@ -2943,7 +2937,6 @@ "version": "1.0.6", "bundled": true, "dev": true, - "optional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2952,8 +2945,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.4", @@ -3069,7 +3061,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "1.1.7" } @@ -3084,7 +3075,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3156,7 +3146,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3186,8 +3175,7 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "performance-now": { "version": "0.2.0", @@ -3282,7 +3270,6 @@ "version": "2.6.1", "bundled": true, "dev": true, - "optional": true, "requires": { "glob": "^7.0.5" } @@ -3375,7 +3362,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3476,8 +3462,7 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, From 8e858bc84e4ba4fcf66b5ed9f1aefc4b81dca983 Mon Sep 17 00:00:00 2001 From: Aleksandr Volochnev Date: Sun, 10 Mar 2019 22:45:59 +0100 Subject: [PATCH 12/12] Verify DB init --- src/common/cassandra.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/common/cassandra.js b/src/common/cassandra.js index 33c45e2..a6d4798 100644 --- a/src/common/cassandra.js +++ b/src/common/cassandra.js @@ -37,7 +37,7 @@ export function getCassandraClient() { * method in this module. Returns a Promise. */ export function initCassandraAsync() { - logger.log('info', 'Initializing cassandra'); + logger.log('info', 'Initializing cassandra...'); // Create the client with some default query options return createClientAsync('killrvideo', { @@ -46,7 +46,25 @@ export function initCassandraAsync() { }) .tap(client => { // Wait until Cassandra is ready and we can connect (could be delayed if starting up for 1st time) - return withRetries(() => client.connectAsync(), 10, 10, 'Error connecting to cassandra', false); + return withRetries(() => client.connectAsync(), 10, 10, 'Connecting to cassandra...', false, true); + }) + .tap(client => { + // Wait until Cassandra is bootstrapped and we can use it (dse-config needs time to initialise it) + return withRetries(() => + new Promise ( + function(resolve, reject){ + client.execute( + 'SELECT keyspace_name FROM system_schema.keyspaces WHERE keyspace_name=\'kv_init_done\';', [], [], + function(err, result) { + if (err || result.rowLength != 1) { + reject(new Error('DB is not initialised')); + } + resolve(); + } + ) + } + ), 10, 10, 'Waiting for dse-config to bootstrap cassandra...', false, false + ); }) .tap(client => { // Save client instance for reuse everywhere and log