index.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. *
  3. * Copyright 2015, Google Inc.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following disclaimer
  14. * in the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Google Inc. nor the names of its
  17. * contributors may be used to endorse or promote products derived from
  18. * this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. 'use strict';
  34. var path = require('path');
  35. var fs = require('fs');
  36. var SSL_ROOTS_PATH = path.resolve(__dirname, '..', '..', 'etc', 'roots.pem');
  37. var _ = require('lodash');
  38. var ProtoBuf = require('protobufjs');
  39. var client = require('./src/client.js');
  40. var server = require('./src/server.js');
  41. var common = require('./src/common.js');
  42. var Metadata = require('./src/metadata.js');
  43. var grpc = require('./src/grpc_extension');
  44. var protobuf_js_5_common = require('./src/protobuf_js_5_common');
  45. var protobuf_js_6_common = require('./src/protobuf_js_6_common');
  46. grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii'));
  47. /**
  48. * Load a ProtoBuf.js object as a gRPC object. The options object can provide
  49. * the following options:
  50. * - binaryAsBase64: deserialize bytes values as base64 strings instead of
  51. * Buffers. Defaults to false
  52. * - longsAsStrings: deserialize long values as strings instead of objects.
  53. * Defaults to true
  54. * - enumsAsStrings: deserialize enum values as strings instead of numbers.
  55. * Defaults to true
  56. * - deprecatedArgumentOrder: Use the beta method argument order for client
  57. * methods, with optional arguments after the callback. Defaults to false.
  58. * This option is only a temporary stopgap measure to smooth an API breakage.
  59. * It is deprecated, and new code should not use it.
  60. * - protobufjsVersion: Available values are 5, 6, and 'detect'. 5 and 6
  61. * respectively indicate that an object from the corresponding version of
  62. * ProtoBuf.js is provided in the value argument. If the option is 'detect',
  63. * gRPC will guess what the version is based on the structure of the value.
  64. * Defaults to 'detect'.
  65. * @param {Object} value The ProtoBuf.js reflection object to load
  66. * @param {Object=} options Options to apply to the loaded file
  67. * @return {Object<string, *>} The resulting gRPC object
  68. */
  69. exports.loadObject = function loadObject(value, options) {
  70. options = _.defaults(options, common.defaultGrpcOptions);
  71. options = _.defaults(options, {'protobufjsVersion': 'detect'});
  72. var protobufjsVersion;
  73. if (options.protobufjsVersion === 'detect') {
  74. if (protobuf_js_6_common.isProbablyProtobufJs6(value)) {
  75. protobufjsVersion = 6;
  76. } else if (protobuf_js_5_common.isProbablyProtobufJs5(value)) {
  77. protobufjsVersion = 5;
  78. } else {
  79. var error_message = 'Could not detect ProtoBuf.js version. Please ' +
  80. 'specify the version number with the "protobufjs_version" option';
  81. throw new Error(error_message);
  82. }
  83. } else {
  84. protobufjsVersion = options.protobufjsVersion;
  85. }
  86. switch (protobufjsVersion) {
  87. case 6: return protobuf_js_6_common.loadObject(value, options);
  88. case 5:
  89. var deprecation_message = 'Calling grpc.loadObject with an object ' +
  90. 'generated by ProtoBuf.js 5 is deprecated. Please upgrade to ' +
  91. 'ProtoBuf.js 6.';
  92. common.log(grpc.logVerbosity.INFO, deprecation_message);
  93. return protobuf_js_5_common.loadObject(value, options);
  94. default:
  95. throw new Error('Unrecognized protobufjsVersion', protobufjsVersion);
  96. }
  97. };
  98. var loadObject = exports.loadObject;
  99. function applyProtoRoot(filename, root) {
  100. if (_.isString(filename)) {
  101. return filename;
  102. }
  103. filename.root = path.resolve(filename.root) + '/';
  104. root.resolvePath = function(originPath, importPath, alreadyNormalized) {
  105. return ProtoBuf.util.path.resolve(filename.root,
  106. importPath,
  107. alreadyNormalized);
  108. };
  109. return filename.file;
  110. }
  111. /**
  112. * Load a gRPC object from a .proto file. The options object can provide the
  113. * following options:
  114. * - convertFieldsToCamelCase: Load this file with field names in camel case
  115. * instead of their original case
  116. * - binaryAsBase64: deserialize bytes values as base64 strings instead of
  117. * Buffers. Defaults to false
  118. * - longsAsStrings: deserialize long values as strings instead of objects.
  119. * Defaults to true
  120. * - enumsAsStrings: deserialize enum values as strings instead of numbers.
  121. * Defaults to true
  122. * - deprecatedArgumentOrder: Use the beta method argument order for client
  123. * methods, with optional arguments after the callback. Defaults to false.
  124. * This option is only a temporary stopgap measure to smooth an API breakage.
  125. * It is deprecated, and new code should not use it.
  126. * @param {string|{root: string, file: string}} filename The file to load
  127. * @param {string=} format The file format to expect. Must be either 'proto' or
  128. * 'json'. Defaults to 'proto'
  129. * @param {Object=} options Options to apply to the loaded file
  130. * @return {Object<string, *>} The resulting gRPC object
  131. */
  132. exports.load = function load(filename, format, options) {
  133. /* Note: format is currently unused, because the API for loading a proto
  134. file or a JSON file is identical in Protobuf.js 6. In the future, there is
  135. still the possibility of adding other formats that would be loaded
  136. differently */
  137. options = _.defaults(options, common.defaultGrpcOptions);
  138. options.protobufjs_version = 6;
  139. var root = new ProtoBuf.Root();
  140. var parse_options = {keepCase: !options.convertFieldsToCamelCase};
  141. return loadObject(root.loadSync(applyProtoRoot(filename, root),
  142. parse_options),
  143. options);
  144. };
  145. var log_template = _.template(
  146. '{severity} {timestamp}\t{file}:{line}]\t{message}',
  147. {interpolate: /{([\s\S]+?)}/g});
  148. /**
  149. * Sets the logger function for the gRPC module. For debugging purposes, the C
  150. * core will log synchronously directly to stdout unless this function is
  151. * called. Note: the output format here is intended to be informational, and
  152. * is not guaranteed to stay the same in the future.
  153. * Logs will be directed to logger.error.
  154. * @param {Console} logger A Console-like object.
  155. */
  156. exports.setLogger = function setLogger(logger) {
  157. common.logger = logger;
  158. grpc.setDefaultLoggerCallback(function(file, line, severity,
  159. message, timestamp) {
  160. logger.error(log_template({
  161. file: path.basename(file),
  162. line: line,
  163. severity: severity,
  164. message: message,
  165. timestamp: timestamp.toISOString()
  166. }));
  167. });
  168. };
  169. /**
  170. * Sets the logger verbosity for gRPC module logging. The options are members
  171. * of the grpc.logVerbosity map.
  172. * @param {Number} verbosity The minimum severity to log
  173. */
  174. exports.setLogVerbosity = function setLogVerbosity(verbosity) {
  175. common.logVerbosity = verbosity;
  176. grpc.setLogVerbosity(verbosity);
  177. };
  178. /**
  179. * @see module:src/server.Server
  180. */
  181. exports.Server = server.Server;
  182. /**
  183. * @see module:src/metadata
  184. */
  185. exports.Metadata = Metadata;
  186. /**
  187. * Status name to code number mapping
  188. */
  189. exports.status = grpc.status;
  190. /**
  191. * Propagate flag name to number mapping
  192. */
  193. exports.propagate = grpc.propagate;
  194. /**
  195. * Call error name to code number mapping
  196. */
  197. exports.callError = grpc.callError;
  198. /**
  199. * Write flag name to code number mapping
  200. */
  201. exports.writeFlags = grpc.writeFlags;
  202. /**
  203. * Log verbosity setting name to code number mapping
  204. */
  205. exports.logVerbosity = grpc.logVerbosity;
  206. /**
  207. * Credentials factories
  208. */
  209. exports.credentials = require('./src/credentials.js');
  210. /**
  211. * ServerCredentials factories
  212. */
  213. exports.ServerCredentials = grpc.ServerCredentials;
  214. /**
  215. * @see module:src/client.makeClientConstructor
  216. */
  217. exports.makeGenericClientConstructor = client.makeClientConstructor;
  218. /**
  219. * @see module:src/client.getClientChannel
  220. */
  221. exports.getClientChannel = client.getClientChannel;
  222. /**
  223. * @see module:src/client.waitForClientReady
  224. */
  225. exports.waitForClientReady = client.waitForClientReady;
  226. exports.closeClient = function closeClient(client_obj) {
  227. client.getClientChannel(client_obj).close();
  228. };