configSchema.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import { JSONSchema4 } from 'json-schema'
  2. import winston from 'winston'
  3. import { MAX_CONCURRENT_RESPONSE_TIME_CHECKS } from '../services/networking/NetworkingService'
  4. export const bytesizeUnits = ['B', 'K', 'M', 'G', 'T']
  5. export const bytesizeRegex = new RegExp(`^[0-9]+(${bytesizeUnits.join('|')})$`)
  6. export const configSchema: JSONSchema4 = {
  7. title: 'Distributor node configuration',
  8. description: 'Configuration schema for distirubtor CLI and node',
  9. type: 'object',
  10. required: ['id', 'endpoints', 'directories', 'buckets', 'keys', 'port', 'workerId', 'limits', 'intervals'],
  11. additionalProperties: false,
  12. properties: {
  13. id: {
  14. type: 'string',
  15. description: 'Node identifier used when sending elasticsearch logs and exposed on /status endpoint',
  16. minLength: 1,
  17. },
  18. endpoints: {
  19. type: 'object',
  20. description: 'Specifies external endpoints that the distributor node will connect to',
  21. additionalProperties: false,
  22. required: ['queryNode', 'joystreamNodeWs'],
  23. properties: {
  24. queryNode: {
  25. description: 'Query node graphql server uri (for example: http://localhost:8081/graphql)',
  26. type: 'string',
  27. },
  28. joystreamNodeWs: {
  29. description: 'Joystream node websocket api uri (for example: ws://localhost:9944)',
  30. type: 'string',
  31. },
  32. elasticSearch: {
  33. description: 'Elasticsearch uri used for submitting the distributor node logs (if enabled via `log.elastic`)',
  34. type: 'string',
  35. },
  36. },
  37. },
  38. directories: {
  39. type: 'object',
  40. required: ['assets', 'cacheState'],
  41. additionalProperties: false,
  42. description: "Specifies paths where node's data will be stored",
  43. properties: {
  44. assets: {
  45. description: 'Path to a directory where all the cached assets will be stored',
  46. type: 'string',
  47. },
  48. cacheState: {
  49. description:
  50. 'Path to a directory where information about the current cache state will be stored (LRU-SP cache data, stored assets mime types etc.)',
  51. type: 'string',
  52. },
  53. logs: {
  54. description:
  55. 'Path to a directory where logs will be stored if logging to a file was enabled (via `log.file`).',
  56. type: 'string',
  57. },
  58. },
  59. },
  60. log: {
  61. type: 'object',
  62. additionalProperties: false,
  63. description: 'Specifies minimum log levels by supported log outputs',
  64. properties: {
  65. file: {
  66. description: 'Minimum level of logs written to a file specified in `directories.logs`',
  67. type: 'string',
  68. enum: [...Object.keys(winston.config.npm.levels), 'off'],
  69. },
  70. console: {
  71. description: 'Minimum level of logs outputted to a console',
  72. type: 'string',
  73. enum: [...Object.keys(winston.config.npm.levels), 'off'],
  74. },
  75. elastic: {
  76. description: 'Minimum level of logs sent to elasticsearch endpoint specified in `endpoints.elasticSearch`',
  77. type: 'string',
  78. enum: [...Object.keys(winston.config.npm.levels), 'off'],
  79. },
  80. },
  81. },
  82. limits: {
  83. type: 'object',
  84. required: [
  85. 'storage',
  86. 'maxConcurrentStorageNodeDownloads',
  87. 'maxConcurrentOutboundConnections',
  88. 'outboundRequestsTimeout',
  89. ],
  90. description: 'Specifies node limits w.r.t. storage, outbound connections etc.',
  91. additionalProperties: false,
  92. properties: {
  93. storage: {
  94. description: 'Maximum total size of all (cached) assets stored in `directories.assets`',
  95. type: 'string',
  96. pattern: bytesizeRegex.source,
  97. },
  98. maxConcurrentStorageNodeDownloads: {
  99. description: 'Maximum number of concurrent downloads from the storage node(s)',
  100. type: 'integer',
  101. minimum: 1,
  102. },
  103. maxConcurrentOutboundConnections: {
  104. description: 'Maximum number of total simultaneous outbound connections to storage node(s)',
  105. type: 'integer',
  106. minimum: 1,
  107. },
  108. outboundRequestsTimeout: {
  109. description: 'Timeout for all outbound storage node http requests in miliseconds',
  110. type: 'integer',
  111. minimum: 1,
  112. },
  113. },
  114. },
  115. intervals: {
  116. type: 'object',
  117. required: ['saveCacheState', 'checkStorageNodeResponseTimes', 'cacheCleanup'],
  118. additionalProperties: false,
  119. description: 'Specifies how often periodic tasks (for example cache cleanup) are executed by the node.',
  120. properties: {
  121. saveCacheState: {
  122. description:
  123. 'How often, in seconds, will the cache state be saved in `directories.state`. ' +
  124. 'Independently of the specified interval, the node will always try to save cache state before exiting.',
  125. type: 'integer',
  126. minimum: 1,
  127. },
  128. checkStorageNodeResponseTimes: {
  129. description:
  130. 'How often, in seconds, will the distributor node attempt to send requests to all current storage node endpoints ' +
  131. 'in order to check how quickly they respond. ' +
  132. `The node will never make more than ${MAX_CONCURRENT_RESPONSE_TIME_CHECKS} such requests concurrently.`,
  133. type: 'integer',
  134. minimum: 1,
  135. },
  136. cacheCleanup: {
  137. description:
  138. 'How often, in seconds, will the distributor node fetch data about all its distribution obligations from the query node ' +
  139. 'and remove all the no-longer assigned data objects from local storage and cache state',
  140. type: 'integer',
  141. minimum: 1,
  142. },
  143. },
  144. },
  145. port: { description: 'Distributor node http api port', type: 'integer', minimum: 0 },
  146. keys: {
  147. description: 'Specifies the keys available within distributor node CLI.',
  148. type: 'array',
  149. items: {
  150. oneOf: [
  151. {
  152. type: 'object',
  153. title: 'Substrate uri',
  154. description: "Keypair's substrate uri (for example: //Alice)",
  155. required: ['suri'],
  156. additionalProperties: false,
  157. properties: {
  158. type: { type: 'string', enum: ['ed25519', 'sr25519', 'ecdsa'], default: 'sr25519' },
  159. suri: { type: 'string' },
  160. },
  161. },
  162. {
  163. type: 'object',
  164. title: 'Mnemonic phrase',
  165. description: 'Menomonic phrase',
  166. required: ['mnemonic'],
  167. additionalProperties: false,
  168. properties: {
  169. type: { type: 'string', enum: ['ed25519', 'sr25519', 'ecdsa'], default: 'sr25519' },
  170. mnemonic: { type: 'string' },
  171. },
  172. },
  173. {
  174. type: 'object',
  175. title: 'JSON backup file',
  176. description: 'Path to JSON backup file from polkadot signer / polakdot/apps (relative to config file path)',
  177. required: ['keyfile'],
  178. additionalProperties: false,
  179. properties: {
  180. keyfile: { type: 'string' },
  181. },
  182. },
  183. ],
  184. },
  185. minItems: 1,
  186. },
  187. buckets: {
  188. description: 'Specifies the buckets distributed by the node',
  189. oneOf: [
  190. {
  191. title: 'Bucket ids',
  192. description: 'List of distribution bucket ids',
  193. type: 'array',
  194. items: { type: 'integer', minimum: 0 },
  195. minItems: 1,
  196. },
  197. {
  198. title: 'All buckets',
  199. description: 'Distribute all buckets assigned to worker specified in `workerId`',
  200. type: 'string',
  201. enum: ['all'],
  202. },
  203. ],
  204. },
  205. workerId: {
  206. description: 'ID of the node operator (distribution working group worker)',
  207. type: 'integer',
  208. minimum: 0,
  209. },
  210. },
  211. }
  212. export default configSchema