{"action":"created","comment":{"url":"https://api.github.com/repos/nymag/amphora/pulls/comments/86410914","pull_request_review_id":7072111,"id":86410914,"diff_hunk":"@@ -0,0 +1,387 @@\n+'use strict';\n+\n+const elastic = require('elasticsearch'),\n+  bluebird = require('bluebird'),\n+  _ = require('lodash'),\n+  util = require('util'),\n+  log = require('./log').withStandardPrefix(__filename),\n+  endpoint = process.env.ELASTIC_HOST || '',\n+  serverConfig = {\n+    host: endpoint,\n+    maxSockets: 500,\n+    apiVersion: '1.7',\n+    // log: ['error', 'trace'],\n+    defer: require('../utils/defer')\n+  };\n+\n+var client,\n+  indexVersion = '_v1';\n+\n+/**\n+ * Test whether or not the client is connected\n+ * to Elastic\n+ *\n+ * @param  {object} currentClient\n+ * @returns {Promise}\n+ */\n+function healthCheck(currentClient) {\n+  return currentClient.ping({\n+    requestTimeout: 1000\n+  }).then(function () {\n+    log('info', 'Elasticsearch cluster is up!');\n+    return bluebird.resolve();\n+  }).catch(function (error) {\n+    log('info', 'Elasticsearch cluster is down!');\n+    return bluebird.reject(error);\n+  });\n+}\n+\n+/**\n+ * Create an Elasticsearch index\n+ *\n+ * @param {string} index\n+ * @param {object} mappings\n+ * @returns {Promise}\n+ */\n+function initIndex(index, mappings) {\n+  return client.indices.create({\n+    index: index,\n+    body: mappings\n+  }).then(function () {\n+    log('info', 'Successfully created ' + index);\n+  })\n+    .catch(function (error) {\n+      log('error', error);\n+      return bluebird.reject(error);\n+    });\n+}\n+\n+/**\n+ * Check if an Elasticsearch index exists\n+ *\n+ * @param {string} index\n+ * @returns {Promise}\n+ */\n+function existsIndex(index) {\n+  return client.indices.exists({\n+    index: index\n+  });\n+}\n+\n+/**\n+ * Indices should have a different name than the alias\n+ * Append the `indexVersion` to an index name.\n+ *\n+ * @param {string} alias\n+ * @returns {string}\n+ */\n+function createIndexName(alias) {\n+  return alias + indexVersion;\n+}\n+\n+/**\n+ * Create an Elasticsearch alias\n+ *\n+ * @param {string} name, e.g. 'editable-articles' for the index 'editable-articles_v1'\n+ * @param {string} index\n+ * @returns {Promise}\n+ */\n+function initAlias(name, index) {\n+  return client.indices.putAlias({\n+    name: name,\n+    index: index\n+  });\n+}\n+\n+/**\n+ * Check if an Elasticsearch alias exists\n+ *\n+ * @param {string} name\n+ * @returns {Promise}\n+ */\n+function existsAlias(name) {\n+  return client.indices.existsAlias({\n+    name: name\n+  });\n+}\n+\n+/**\n+ * Create an Elasticsearch mapping\n+ *\n+* @param {string} index\n+* @param {string} type\n+* @param {object} mapping\n+* @returns {Promise}\n+ */\n+function initMapping(index, type, mapping) {\n+  return client.indices.putMapping({\n+    index: index,\n+    type: type,\n+    body: mapping\n+  }).then(function () {\n+    log('info', 'Successfully created a mapping for ' + index);\n+    return bluebird.resolve(index);\n+  })\n+    .catch(function (error) {\n+      log('error', error);\n+      return bluebird.reject(error);\n+    });\n+}\n+\n+/**\n+ * Check if an Elasticsearch mapping exists\n+ * Note: An empty mapping can still exist\n+ *\n+ * @param {string} index\n+  * @param {type} type\n+ * @returns {Promise}\n+ */\n+function existsMapping(index, type) {\n+  return client.indices.getMapping({\n+    index: index,\n+    type: type\n+  });\n+}\n+\n+/**\n+ * Create an Elasticsearch mapping if one doesn't exist\n+ *\n+ * @param {string} index\n+ * @param {string} type\n+ * @param {object} mapping\n+ * @returns {Promise}\n+ */\n+function createMappingIfNone(index, type, mapping) {\n+  return module.exports.existsMapping(index, type)\n+    .then(function (result) {\n+      let getMapping = _.get(result, index + '.mappings.' + type);\n+\n+      if (!_.size(getMapping)) {\n+        log('info', 'Mapping is missing!');\n+\n+        return module.exports.initMapping(index, type, mapping)\n+          .then(function (result) {\n+            log('info', 'Creating mapping', index, type, ':', result);\n+          }).catch(function (error) {\n+            log('error', error.stack);\n+          });\n+      } else {\n+        log('info', 'Mapping found for', index);\n+      }\n+    });\n+}\n+\n+/**\n+ * Create an Elasticsearch index if one doesn't exist\n+ *\n+ * @param {string} index\n+ * @returns {Promise}\n+ */\n+function createIndexIfNone(index) {\n+  return existsIndex(index)\n+    .then(function (exists) {\n+      if (!exists) {\n+        return module.exports.initIndex(index)\n+          .then(function (result) {\n+            log('info', 'Creating Elasticsearch index', index, ':', result);\n+          })\n+          .catch(function (error) {\n+            log('error', error);\n+          });\n+      } else {\n+        log('info', 'Elasticsearch index exists at', index);\n+      }\n+    });\n+}\n+\n+/**\n+ * Create an Elasticsearch alias if one doesn't exist\n+ *\n+ * @param {string} index\n+ * @returns {Promise}\n+ */\n+function createAliasIfNone(index) {\n+  return module.exports.existsAlias(index)\n+    .then(function (exists) {\n+      if (!exists) {\n+        // Indices should have a different name than the alias\n+        // Append `aliaSuffix` to newly created indices","path":"lib/services/search.js","position":208,"original_position":208,"commit_id":"dd4665347dc2a02efdd7760e0a4adadda01e74c9","original_commit_id":"dd4665347dc2a02efdd7760e0a4adadda01e74c9","user":{"login":"dmabuada","id":5923128,"avatar_url":"https://avatars.githubusercontent.com/u/5923128?v=3","gravatar_id":"","url":"https://api.github.com/users/dmabuada","html_url":"https://github.com/dmabuada","followers_url":"https://api.github.com/users/dmabuada/followers","following_url":"https://api.github.com/users/dmabuada/following{/other_user}","gists_url":"https://api.github.com/users/dmabuada/gists{/gist_id}","starred_url":"https://api.github.com/users/dmabuada/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmabuada/subscriptions","organizations_url":"https://api.github.com/users/dmabuada/orgs","repos_url":"https://api.github.com/users/dmabuada/repos","events_url":"https://api.github.com/users/dmabuada/events{/privacy}","received_events_url":"https://api.github.com/users/dmabuada/received_events","type":"User","site_admin":false},"body":"hmmm? aliaSuffix?","created_at":"2016-11-03T18:21:41Z","updated_at":"2016-11-03T18:21:53Z","html_url":"https://github.com/nymag/amphora/pull/327#discussion_r86410914","pull_request_url":"https://api.github.com/repos/nymag/amphora/pulls/327","_links":{"self":{"href":"https://api.github.com/repos/nymag/amphora/pulls/comments/86410914"},"html":{"href":"https://github.com/nymag/amphora/pull/327#discussion_r86410914"},"pull_request":{"href":"https://api.github.com/repos/nymag/amphora/pulls/327"}}},"pull_request":{"url":"https://api.github.com/repos/nymag/amphora/pulls/327","id":91843157,"html_url":"https://github.com/nymag/amphora/pull/327","diff_url":"https://github.com/nymag/amphora/pull/327.diff","patch_url":"https://github.com/nymag/amphora/pull/327.patch","issue_url":"https://api.github.com/repos/nymag/amphora/issues/327","number":327,"state":"open","locked":false,"title":"Elastic Integration","user":{"login":"jonwinton","id":4906712,"avatar_url":"https://avatars.githubusercontent.com/u/4906712?v=3","gravatar_id":"","url":"https://api.github.com/users/jonwinton","html_url":"https://github.com/jonwinton","followers_url":"https://api.github.com/users/jonwinton/followers","following_url":"https://api.github.com/users/jonwinton/following{/other_user}","gists_url":"https://api.github.com/users/jonwinton/gists{/gist_id}","starred_url":"https://api.github.com/users/jonwinton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonwinton/subscriptions","organizations_url":"https://api.github.com/users/jonwinton/orgs","repos_url":"https://api.github.com/users/jonwinton/repos","events_url":"https://api.github.com/users/jonwinton/events{/privacy}","received_events_url":"https://api.github.com/users/jonwinton/received_events","type":"User","site_admin":false},"body":" Creates a search service in Amphora which can be used to index content. Implementation can be found here: https://github.com/nymag/sites/compare/search-service?expand=1","created_at":"2016-11-01T19:00:53Z","updated_at":"2016-11-03T18:29:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f2edb56fd68ffa308a73930c72308460be898869","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/nymag/amphora/pulls/327/commits","review_comments_url":"https://api.github.com/repos/nymag/amphora/pulls/327/comments","review_comment_url":"https://api.github.com/repos/nymag/amphora/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nymag/amphora/issues/327/comments","statuses_url":"https://api.github.com/repos/nymag/amphora/statuses/dd4665347dc2a02efdd7760e0a4adadda01e74c9","head":{"label":"nymag:search-service","ref":"search-service","sha":"dd4665347dc2a02efdd7760e0a4adadda01e74c9","user":{"login":"nymag","id":1136688,"avatar_url":"https://avatars.githubusercontent.com/u/1136688?v=3","gravatar_id":"","url":"https://api.github.com/users/nymag","html_url":"https://github.com/nymag","followers_url":"https://api.github.com/users/nymag/followers","following_url":"https://api.github.com/users/nymag/following{/other_user}","gists_url":"https://api.github.com/users/nymag/gists{/gist_id}","starred_url":"https://api.github.com/users/nymag/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nymag/subscriptions","organizations_url":"https://api.github.com/users/nymag/orgs","repos_url":"https://api.github.com/users/nymag/repos","events_url":"https://api.github.com/users/nymag/events{/privacy}","received_events_url":"https://api.github.com/users/nymag/received_events","type":"Organization","site_admin":false},"repo":{"id":32480128,"name":"amphora","full_name":"nymag/amphora","owner":{"login":"nymag","id":1136688,"avatar_url":"https://avatars.githubusercontent.com/u/1136688?v=3","gravatar_id":"","url":"https://api.github.com/users/nymag","html_url":"https://github.com/nymag","followers_url":"https://api.github.com/users/nymag/followers","following_url":"https://api.github.com/users/nymag/following{/other_user}","gists_url":"https://api.github.com/users/nymag/gists{/gist_id}","starred_url":"https://api.github.com/users/nymag/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nymag/subscriptions","organizations_url":"https://api.github.com/users/nymag/orgs","repos_url":"https://api.github.com/users/nymag/repos","events_url":"https://api.github.com/users/nymag/events{/privacy}","received_events_url":"https://api.github.com/users/nymag/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nymag/amphora","description":"Middleware for Express that composes components into renderable pages","fork":false,"url":"https://api.github.com/repos/nymag/amphora","forks_url":"https://api.github.com/repos/nymag/amphora/forks","keys_url":"https://api.github.com/repos/nymag/amphora/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nymag/amphora/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nymag/amphora/teams","hooks_url":"https://api.github.com/repos/nymag/amphora/hooks","issue_events_url":"https://api.github.com/repos/nymag/amphora/issues/events{/number}","events_url":"https://api.github.com/repos/nymag/amphora/events","assignees_url":"https://api.github.com/repos/nymag/amphora/assignees{/user}","branches_url":"https://api.github.com/repos/nymag/amphora/branches{/branch}","tags_url":"https://api.github.com/repos/nymag/amphora/tags","blobs_url":"https://api.github.com/repos/nymag/amphora/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nymag/amphora/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nymag/amphora/git/refs{/sha}","trees_url":"https://api.github.com/repos/nymag/amphora/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nymag/amphora/statuses/{sha}","languages_url":"https://api.github.com/repos/nymag/amphora/languages","stargazers_url":"https://api.github.com/repos/nymag/amphora/stargazers","contributors_url":"https://api.github.com/repos/nymag/amphora/contributors","subscribers_url":"https://api.github.com/repos/nymag/amphora/subscribers","subscription_url":"https://api.github.com/repos/nymag/amphora/subscription","commits_url":"https://api.github.com/repos/nymag/amphora/commits{/sha}","git_commits_url":"https://api.github.com/repos/nymag/amphora/git/commits{/sha}","comments_url":"https://api.github.com/repos/nymag/amphora/comments{/number}","issue_comment_url":"https://api.github.com/repos/nymag/amphora/issues/comments{/number}","contents_url":"https://api.github.com/repos/nymag/amphora/contents/{+path}","compare_url":"https://api.github.com/repos/nymag/amphora/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nymag/amphora/merges","archive_url":"https://api.github.com/repos/nymag/amphora/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nymag/amphora/downloads","issues_url":"https://api.github.com/repos/nymag/amphora/issues{/number}","pulls_url":"https://api.github.com/repos/nymag/amphora/pulls{/number}","milestones_url":"https://api.github.com/repos/nymag/amphora/milestones{/number}","notifications_url":"https://api.github.com/repos/nymag/amphora/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nymag/amphora/labels{/name}","releases_url":"https://api.github.com/repos/nymag/amphora/releases{/id}","deployments_url":"https://api.github.com/repos/nymag/amphora/deployments","created_at":"2015-03-18T19:38:22Z","updated_at":"2016-11-02T16:01:17Z","pushed_at":"2016-11-03T14:53:58Z","git_url":"git://github.com/nymag/amphora.git","ssh_url":"git@github.com:nymag/amphora.git","clone_url":"https://github.com/nymag/amphora.git","svn_url":"https://github.com/nymag/amphora","homepage":"","size":1092,"stargazers_count":4,"watchers_count":4,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":10,"forks":3,"open_issues":10,"watchers":4,"default_branch":"master"}},"base":{"label":"nymag:master","ref":"master","sha":"37bceeb76b063576853e69cbe7c39421fb0510e9","user":{"login":"nymag","id":1136688,"avatar_url":"https://avatars.githubusercontent.com/u/1136688?v=3","gravatar_id":"","url":"https://api.github.com/users/nymag","html_url":"https://github.com/nymag","followers_url":"https://api.github.com/users/nymag/followers","following_url":"https://api.github.com/users/nymag/following{/other_user}","gists_url":"https://api.github.com/users/nymag/gists{/gist_id}","starred_url":"https://api.github.com/users/nymag/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nymag/subscriptions","organizations_url":"https://api.github.com/users/nymag/orgs","repos_url":"https://api.github.com/users/nymag/repos","events_url":"https://api.github.com/users/nymag/events{/privacy}","received_events_url":"https://api.github.com/users/nymag/received_events","type":"Organization","site_admin":false},"repo":{"id":32480128,"name":"amphora","full_name":"nymag/amphora","owner":{"login":"nymag","id":1136688,"avatar_url":"https://avatars.githubusercontent.com/u/1136688?v=3","gravatar_id":"","url":"https://api.github.com/users/nymag","html_url":"https://github.com/nymag","followers_url":"https://api.github.com/users/nymag/followers","following_url":"https://api.github.com/users/nymag/following{/other_user}","gists_url":"https://api.github.com/users/nymag/gists{/gist_id}","starred_url":"https://api.github.com/users/nymag/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nymag/subscriptions","organizations_url":"https://api.github.com/users/nymag/orgs","repos_url":"https://api.github.com/users/nymag/repos","events_url":"https://api.github.com/users/nymag/events{/privacy}","received_events_url":"https://api.github.com/users/nymag/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nymag/amphora","description":"Middleware for Express that composes components into renderable pages","fork":false,"url":"https://api.github.com/repos/nymag/amphora","forks_url":"https://api.github.com/repos/nymag/amphora/forks","keys_url":"https://api.github.com/repos/nymag/amphora/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nymag/amphora/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nymag/amphora/teams","hooks_url":"https://api.github.com/repos/nymag/amphora/hooks","issue_events_url":"https://api.github.com/repos/nymag/amphora/issues/events{/number}","events_url":"https://api.github.com/repos/nymag/amphora/events","assignees_url":"https://api.github.com/repos/nymag/amphora/assignees{/user}","branches_url":"https://api.github.com/repos/nymag/amphora/branches{/branch}","tags_url":"https://api.github.com/repos/nymag/amphora/tags","blobs_url":"https://api.github.com/repos/nymag/amphora/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nymag/amphora/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nymag/amphora/git/refs{/sha}","trees_url":"https://api.github.com/repos/nymag/amphora/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nymag/amphora/statuses/{sha}","languages_url":"https://api.github.com/repos/nymag/amphora/languages","stargazers_url":"https://api.github.com/repos/nymag/amphora/stargazers","contributors_url":"https://api.github.com/repos/nymag/amphora/contributors","subscribers_url":"https://api.github.com/repos/nymag/amphora/subscribers","subscription_url":"https://api.github.com/repos/nymag/amphora/subscription","commits_url":"https://api.github.com/repos/nymag/amphora/commits{/sha}","git_commits_url":"https://api.github.com/repos/nymag/amphora/git/commits{/sha}","comments_url":"https://api.github.com/repos/nymag/amphora/comments{/number}","issue_comment_url":"https://api.github.com/repos/nymag/amphora/issues/comments{/number}","contents_url":"https://api.github.com/repos/nymag/amphora/contents/{+path}","compare_url":"https://api.github.com/repos/nymag/amphora/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nymag/amphora/merges","archive_url":"https://api.github.com/repos/nymag/amphora/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nymag/amphora/downloads","issues_url":"https://api.github.com/repos/nymag/amphora/issues{/number}","pulls_url":"https://api.github.com/repos/nymag/amphora/pulls{/number}","milestones_url":"https://api.github.com/repos/nymag/amphora/milestones{/number}","notifications_url":"https://api.github.com/repos/nymag/amphora/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nymag/amphora/labels{/name}","releases_url":"https://api.github.com/repos/nymag/amphora/releases{/id}","deployments_url":"https://api.github.com/repos/nymag/amphora/deployments","created_at":"2015-03-18T19:38:22Z","updated_at":"2016-11-02T16:01:17Z","pushed_at":"2016-11-03T14:53:58Z","git_url":"git://github.com/nymag/amphora.git","ssh_url":"git@github.com:nymag/amphora.git","clone_url":"https://github.com/nymag/amphora.git","svn_url":"https://github.com/nymag/amphora","homepage":"","size":1092,"stargazers_count":4,"watchers_count":4,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":10,"forks":3,"open_issues":10,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nymag/amphora/pulls/327"},"html":{"href":"https://github.com/nymag/amphora/pull/327"},"issue":{"href":"https://api.github.com/repos/nymag/amphora/issues/327"},"comments":{"href":"https://api.github.com/repos/nymag/amphora/issues/327/comments"},"review_comments":{"href":"https://api.github.com/repos/nymag/amphora/pulls/327/comments"},"review_comment":{"href":"https://api.github.com/repos/nymag/amphora/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nymag/amphora/pulls/327/commits"},"statuses":{"href":"https://api.github.com/repos/nymag/amphora/statuses/dd4665347dc2a02efdd7760e0a4adadda01e74c9"}}}}
{"actor":{"display_login":"dmabuada"}}