search.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // eslint-disable-next-line no-unused-vars
  2. const logger = require('@alias/logger')('growi:service:search');
  3. class SearchService {
  4. constructor(crowi) {
  5. this.crowi = crowi;
  6. this.configManager = crowi.configManager;
  7. this.isErrorOccuredOnHealthcheck = null;
  8. this.isErrorOccuredOnSearching = null;
  9. try {
  10. this.delegator = this.generateDelegator();
  11. }
  12. catch (err) {
  13. logger.error(err);
  14. }
  15. if (this.isConfigured) {
  16. this.delegator.init();
  17. this.registerUpdateEvent();
  18. }
  19. }
  20. get isConfigured() {
  21. return this.delegator != null;
  22. }
  23. get isReachable() {
  24. return this.isConfigured && !this.isErrorOccuredOnHealthcheck && !this.isErrorOccuredOnSearching;
  25. }
  26. get isSearchboxEnabled() {
  27. return this.configManager.getConfig('crowi', 'app:searchboxSslUrl') != null;
  28. }
  29. get isElasticsearchEnabled() {
  30. return this.configManager.getConfig('crowi', 'app:elasticsearchUri') != null;
  31. }
  32. generateDelegator() {
  33. logger.info('Initializing search delegator');
  34. if (this.isSearchboxEnabled) {
  35. logger.info('Searchbox is enabled');
  36. const SearchboxDelegator = require('./search-delegator/searchbox.js');
  37. return new SearchboxDelegator(this.configManager, this.crowi.socketIoService);
  38. }
  39. if (this.isElasticsearchEnabled) {
  40. logger.info('Elasticsearch (not Searchbox) is enabled');
  41. const ElasticsearchDelegator = require('./search-delegator/elasticsearch.js');
  42. return new ElasticsearchDelegator(this.configManager, this.crowi.socketIoService);
  43. }
  44. }
  45. registerUpdateEvent() {
  46. const pageEvent = this.crowi.event('page');
  47. pageEvent.on('create', this.delegator.syncPageUpdated.bind(this.delegator));
  48. pageEvent.on('update', this.delegator.syncPageUpdated.bind(this.delegator));
  49. pageEvent.on('deleteCompletely', this.delegator.syncPagesDeletedCompletely.bind(this.delegator));
  50. pageEvent.on('delete', this.delegator.syncPageDeleted.bind(this.delegator));
  51. pageEvent.on('updateMany', this.delegator.syncPagesUpdated.bind(this.delegator));
  52. pageEvent.on('syncDescendants', this.delegator.syncDescendantsPagesUpdated.bind(this.delegator));
  53. const bookmarkEvent = this.crowi.event('bookmark');
  54. bookmarkEvent.on('create', this.delegator.syncBookmarkChanged.bind(this.delegator));
  55. bookmarkEvent.on('delete', this.delegator.syncBookmarkChanged.bind(this.delegator));
  56. const tagEvent = this.crowi.event('tag');
  57. tagEvent.on('update', this.delegator.syncTagChanged.bind(this.delegator));
  58. }
  59. resetErrorStatus() {
  60. this.isErrorOccuredOnHealthcheck = false;
  61. this.isErrorOccuredOnSearching = false;
  62. }
  63. async reconnectClient() {
  64. logger.info('Try to reconnect...');
  65. this.delegator.initClient();
  66. try {
  67. await this.getInfoForHealth();
  68. logger.info('Reconnecting succeeded.');
  69. this.resetErrorStatus();
  70. }
  71. catch (err) {
  72. throw err;
  73. }
  74. }
  75. async getInfo() {
  76. try {
  77. return await this.delegator.getInfo();
  78. }
  79. catch (err) {
  80. logger.error(err);
  81. throw err;
  82. }
  83. }
  84. async getInfoForHealth() {
  85. try {
  86. const result = await this.delegator.getInfoForHealth();
  87. this.isErrorOccuredOnHealthcheck = false;
  88. return result;
  89. }
  90. catch (err) {
  91. logger.error(err);
  92. // switch error flag, `isErrorOccuredOnHealthcheck` to be `false`
  93. this.isErrorOccuredOnHealthcheck = true;
  94. throw err;
  95. }
  96. }
  97. async getInfoForAdmin() {
  98. return this.delegator.getInfoForAdmin();
  99. }
  100. async normalizeIndices() {
  101. return this.delegator.normalizeIndices();
  102. }
  103. async rebuildIndex() {
  104. return this.delegator.rebuildIndex();
  105. }
  106. async searchKeyword(keyword, user, userGroups, searchOpts) {
  107. try {
  108. return await this.delegator.searchKeyword(keyword, user, userGroups, searchOpts);
  109. }
  110. catch (err) {
  111. logger.error(err);
  112. // switch error flag, `isReachable` to be `false`
  113. this.isErrorOccuredOnSearching = true;
  114. throw err;
  115. }
  116. }
  117. }
  118. module.exports = SearchService;