aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/node/ext/node_grpc.cc140
-rw-r--r--src/node/index.js12
-rw-r--r--src/node/jsdoc_conf.json2
-rw-r--r--src/node/src/client.js29
-rw-r--r--src/node/src/constants.js241
-rw-r--r--src/node/src/credentials.js8
-rw-r--r--src/node/src/server.js30
-rw-r--r--src/node/test/call_test.js4
-rw-r--r--src/node/test/constant_test.js131
-rw-r--r--src/node/test/end_to_end_test.js17
10 files changed, 298 insertions, 316 deletions
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index e193e82179..c444ad0b7b 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -85,98 +85,6 @@ logger_state grpc_logger_state;
static char *pem_root_certs = NULL;
-void InitStatusConstants(Local<Object> exports) {
- Nan::HandleScope scope;
- Local<Object> status = Nan::New<Object>();
- Nan::Set(exports, Nan::New("status").ToLocalChecked(), status);
- Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_STATUS_OK));
- Nan::Set(status, Nan::New("OK").ToLocalChecked(), OK);
- Local<Value> CANCELLED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_CANCELLED));
- Nan::Set(status, Nan::New("CANCELLED").ToLocalChecked(), CANCELLED);
- Local<Value> UNKNOWN(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNKNOWN));
- Nan::Set(status, Nan::New("UNKNOWN").ToLocalChecked(), UNKNOWN);
- Local<Value> INVALID_ARGUMENT(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_INVALID_ARGUMENT));
- Nan::Set(status, Nan::New("INVALID_ARGUMENT").ToLocalChecked(),
- INVALID_ARGUMENT);
- Local<Value> DEADLINE_EXCEEDED(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_DEADLINE_EXCEEDED));
- Nan::Set(status, Nan::New("DEADLINE_EXCEEDED").ToLocalChecked(),
- DEADLINE_EXCEEDED);
- Local<Value> NOT_FOUND(Nan::New<Uint32, uint32_t>(GRPC_STATUS_NOT_FOUND));
- Nan::Set(status, Nan::New("NOT_FOUND").ToLocalChecked(), NOT_FOUND);
- Local<Value> ALREADY_EXISTS(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_ALREADY_EXISTS));
- Nan::Set(status, Nan::New("ALREADY_EXISTS").ToLocalChecked(), ALREADY_EXISTS);
- Local<Value> PERMISSION_DENIED(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_PERMISSION_DENIED));
- Nan::Set(status, Nan::New("PERMISSION_DENIED").ToLocalChecked(),
- PERMISSION_DENIED);
- Local<Value> UNAUTHENTICATED(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAUTHENTICATED));
- Nan::Set(status, Nan::New("UNAUTHENTICATED").ToLocalChecked(),
- UNAUTHENTICATED);
- Local<Value> RESOURCE_EXHAUSTED(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_RESOURCE_EXHAUSTED));
- Nan::Set(status, Nan::New("RESOURCE_EXHAUSTED").ToLocalChecked(),
- RESOURCE_EXHAUSTED);
- Local<Value> FAILED_PRECONDITION(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_FAILED_PRECONDITION));
- Nan::Set(status, Nan::New("FAILED_PRECONDITION").ToLocalChecked(),
- FAILED_PRECONDITION);
- Local<Value> ABORTED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_ABORTED));
- Nan::Set(status, Nan::New("ABORTED").ToLocalChecked(), ABORTED);
- Local<Value> OUT_OF_RANGE(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_OUT_OF_RANGE));
- Nan::Set(status, Nan::New("OUT_OF_RANGE").ToLocalChecked(), OUT_OF_RANGE);
- Local<Value> UNIMPLEMENTED(
- Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNIMPLEMENTED));
- Nan::Set(status, Nan::New("UNIMPLEMENTED").ToLocalChecked(), UNIMPLEMENTED);
- Local<Value> INTERNAL(Nan::New<Uint32, uint32_t>(GRPC_STATUS_INTERNAL));
- Nan::Set(status, Nan::New("INTERNAL").ToLocalChecked(), INTERNAL);
- Local<Value> UNAVAILABLE(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAVAILABLE));
- Nan::Set(status, Nan::New("UNAVAILABLE").ToLocalChecked(), UNAVAILABLE);
- Local<Value> DATA_LOSS(Nan::New<Uint32, uint32_t>(GRPC_STATUS_DATA_LOSS));
- Nan::Set(status, Nan::New("DATA_LOSS").ToLocalChecked(), DATA_LOSS);
-}
-
-void InitCallErrorConstants(Local<Object> exports) {
- Nan::HandleScope scope;
- Local<Object> call_error = Nan::New<Object>();
- Nan::Set(exports, Nan::New("callError").ToLocalChecked(), call_error);
- Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_CALL_OK));
- Nan::Set(call_error, Nan::New("OK").ToLocalChecked(), OK);
- Local<Value> CALL_ERROR(Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR));
- Nan::Set(call_error, Nan::New("ERROR").ToLocalChecked(), CALL_ERROR);
- Local<Value> NOT_ON_SERVER(
- Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_SERVER));
- Nan::Set(call_error, Nan::New("NOT_ON_SERVER").ToLocalChecked(),
- NOT_ON_SERVER);
- Local<Value> NOT_ON_CLIENT(
- Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_CLIENT));
- Nan::Set(call_error, Nan::New("NOT_ON_CLIENT").ToLocalChecked(),
- NOT_ON_CLIENT);
- Local<Value> ALREADY_INVOKED(
- Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_INVOKED));
- Nan::Set(call_error, Nan::New("ALREADY_INVOKED").ToLocalChecked(),
- ALREADY_INVOKED);
- Local<Value> NOT_INVOKED(
- Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_INVOKED));
- Nan::Set(call_error, Nan::New("NOT_INVOKED").ToLocalChecked(), NOT_INVOKED);
- Local<Value> ALREADY_FINISHED(
- Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_FINISHED));
- Nan::Set(call_error, Nan::New("ALREADY_FINISHED").ToLocalChecked(),
- ALREADY_FINISHED);
- Local<Value> TOO_MANY_OPERATIONS(
- Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS));
- Nan::Set(call_error, Nan::New("TOO_MANY_OPERATIONS").ToLocalChecked(),
- TOO_MANY_OPERATIONS);
- Local<Value> INVALID_FLAGS(
- Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_INVALID_FLAGS));
- Nan::Set(call_error, Nan::New("INVALID_FLAGS").ToLocalChecked(),
- INVALID_FLAGS);
-}
-
void InitOpTypeConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> op_type = Nan::New<Object>();
@@ -211,27 +119,6 @@ void InitOpTypeConstants(Local<Object> exports) {
RECV_CLOSE_ON_SERVER);
}
-void InitPropagateConstants(Local<Object> exports) {
- Nan::HandleScope scope;
- Local<Object> propagate = Nan::New<Object>();
- Nan::Set(exports, Nan::New("propagate").ToLocalChecked(), propagate);
- Local<Value> DEADLINE(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEADLINE));
- Nan::Set(propagate, Nan::New("DEADLINE").ToLocalChecked(), DEADLINE);
- Local<Value> CENSUS_STATS_CONTEXT(
- Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_STATS_CONTEXT));
- Nan::Set(propagate, Nan::New("CENSUS_STATS_CONTEXT").ToLocalChecked(),
- CENSUS_STATS_CONTEXT);
- Local<Value> CENSUS_TRACING_CONTEXT(
- Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT));
- Nan::Set(propagate, Nan::New("CENSUS_TRACING_CONTEXT").ToLocalChecked(),
- CENSUS_TRACING_CONTEXT);
- Local<Value> CANCELLATION(
- Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CANCELLATION));
- Nan::Set(propagate, Nan::New("CANCELLATION").ToLocalChecked(), CANCELLATION);
- Local<Value> DEFAULTS(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEFAULTS));
- Nan::Set(propagate, Nan::New("DEFAULTS").ToLocalChecked(), DEFAULTS);
-}
-
void InitConnectivityStateConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> channel_state = Nan::New<Object>();
@@ -252,28 +139,6 @@ void InitConnectivityStateConstants(Local<Object> exports) {
FATAL_FAILURE);
}
-void InitWriteFlags(Local<Object> exports) {
- Nan::HandleScope scope;
- Local<Object> write_flags = Nan::New<Object>();
- Nan::Set(exports, Nan::New("writeFlags").ToLocalChecked(), write_flags);
- Local<Value> BUFFER_HINT(Nan::New<Uint32, uint32_t>(GRPC_WRITE_BUFFER_HINT));
- Nan::Set(write_flags, Nan::New("BUFFER_HINT").ToLocalChecked(), BUFFER_HINT);
- Local<Value> NO_COMPRESS(Nan::New<Uint32, uint32_t>(GRPC_WRITE_NO_COMPRESS));
- Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS);
-}
-
-void InitLogConstants(Local<Object> exports) {
- Nan::HandleScope scope;
- Local<Object> log_verbosity = Nan::New<Object>();
- Nan::Set(exports, Nan::New("logVerbosity").ToLocalChecked(), log_verbosity);
- Local<Value> LOG_DEBUG(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_DEBUG));
- Nan::Set(log_verbosity, Nan::New("DEBUG").ToLocalChecked(), LOG_DEBUG);
- Local<Value> LOG_INFO(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_INFO));
- Nan::Set(log_verbosity, Nan::New("INFO").ToLocalChecked(), LOG_INFO);
- Local<Value> LOG_ERROR(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_ERROR));
- Nan::Set(log_verbosity, Nan::New("ERROR").ToLocalChecked(), LOG_ERROR);
-}
-
NAN_METHOD(MetadataKeyIsLegal) {
if (!info[0]->IsString()) {
return Nan::ThrowTypeError("headerKeyIsLegal's argument must be a string");
@@ -421,13 +286,8 @@ void init(Local<Object> exports) {
grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
init_logger();
- InitStatusConstants(exports);
- InitCallErrorConstants(exports);
InitOpTypeConstants(exports);
- InitPropagateConstants(exports);
InitConnectivityStateConstants(exports);
- InitWriteFlags(exports);
- InitLogConstants(exports);
grpc_pollset_work_run_loop = 0;
diff --git a/src/node/index.js b/src/node/index.js
index 76ab1744b0..0da3440eb7 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -59,6 +59,8 @@ var grpc = require('./src/grpc_extension');
var protobuf_js_5_common = require('./src/protobuf_js_5_common');
var protobuf_js_6_common = require('./src/protobuf_js_6_common');
+var constants = require('./src/constants.js');
+
grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii'));
/**
@@ -212,27 +214,27 @@ exports.Metadata = Metadata;
/**
* Status name to code number mapping
*/
-exports.status = grpc.status;
+exports.status = constants.status;
/**
* Propagate flag name to number mapping
*/
-exports.propagate = grpc.propagate;
+exports.propagate = constants.propagate;
/**
* Call error name to code number mapping
*/
-exports.callError = grpc.callError;
+exports.callError = constants.callError;
/**
* Write flag name to code number mapping
*/
-exports.writeFlags = grpc.writeFlags;
+exports.writeFlags = constants.writeFlags;
/**
* Log verbosity setting name to code number mapping
*/
-exports.logVerbosity = grpc.logVerbosity;
+exports.logVerbosity = constants.logVerbosity;
/**
* Credentials factories
diff --git a/src/node/jsdoc_conf.json b/src/node/jsdoc_conf.json
index c3a0174f0e..2d967753c1 100644
--- a/src/node/jsdoc_conf.json
+++ b/src/node/jsdoc_conf.json
@@ -11,7 +11,7 @@
"package": "package.json",
"readme": "src/node/README.md"
},
- "plugins": [],
+ "plugins": ["plugins/markdown"],
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
diff --git a/src/node/src/client.js b/src/node/src/client.js
index 43502da6af..16fe06a54d 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -58,6 +58,8 @@ var common = require('./common');
var Metadata = require('./metadata');
+var constants = require('./constants');
+
var EventEmitter = require('events').EventEmitter;
var stream = require('stream');
@@ -127,7 +129,8 @@ function _write(chunk, encoding, callback) {
but passing an object that causes a serialization failure is a misuse
of the API anyway, so that's OK. The primary purpose here is to give the
programmer a useful error and to stop the stream properly */
- this.call.cancelWithStatus(grpc.status.INTERNAL, 'Serialization failure');
+ this.call.cancelWithStatus(constants.status.INTERNAL,
+ 'Serialization failure');
callback(e);
}
if (_.isFinite(encoding)) {
@@ -185,9 +188,9 @@ function ClientReadableStream(call, deserialize) {
function _readsDone(status) {
/* jshint validthis: true */
if (!status) {
- status = {code: grpc.status.OK, details: 'OK'};
+ status = {code: constants.status.OK, details: 'OK'};
}
- if (status.code !== grpc.status.OK) {
+ if (status.code !== constants.status.OK) {
this.call.cancelWithStatus(status.code, status.details);
}
this.finished = true;
@@ -218,12 +221,12 @@ function _emitStatusIfDone() {
/* jshint validthis: true */
var status;
if (this.read_status && this.received_status) {
- if (this.read_status.code !== grpc.status.OK) {
+ if (this.read_status.code !== constants.status.OK) {
status = this.read_status;
} else {
status = this.received_status;
}
- if (status.code === grpc.status.OK) {
+ if (status.code === constants.status.OK) {
this.push(null);
} else {
var error = new Error(status.details);
@@ -262,7 +265,7 @@ function _read(size) {
try {
deserialized = self.deserialize(data);
} catch (e) {
- self._readsDone({code: grpc.status.INTERNAL,
+ self._readsDone({code: constants.status.INTERNAL,
details: 'Failed to parse server response'});
return;
}
@@ -510,7 +513,7 @@ Client.prototype.makeUnaryRequest = function(method, serialize, deserialize,
var deserialized;
emitter.emit('metadata', Metadata._fromCoreRepresentation(
response.metadata));
- if (status.code === grpc.status.OK) {
+ if (status.code === constants.status.OK) {
if (err) {
// Got a batch error, but OK status. Something went wrong
args.callback(err);
@@ -522,13 +525,13 @@ Client.prototype.makeUnaryRequest = function(method, serialize, deserialize,
/* Change status to indicate bad server response. This will result
* in passing an error to the callback */
status = {
- code: grpc.status.INTERNAL,
+ code: constants.status.INTERNAL,
details: 'Failed to parse server response'
};
}
}
}
- if (status.code !== grpc.status.OK) {
+ if (status.code !== constants.status.OK) {
error = new Error(status.details);
error.code = status.code;
error.metadata = status.metadata;
@@ -593,7 +596,7 @@ Client.prototype.makeClientStreamRequest = function(method, serialize,
var status = response.status;
var error;
var deserialized;
- if (status.code === grpc.status.OK) {
+ if (status.code === constants.status.OK) {
if (err) {
// Got a batch error, but OK status. Something went wrong
args.callback(err);
@@ -605,13 +608,13 @@ Client.prototype.makeClientStreamRequest = function(method, serialize,
/* Change status to indicate bad server response. This will result
* in passing an error to the callback */
status = {
- code: grpc.status.INTERNAL,
+ code: constants.status.INTERNAL,
details: 'Failed to parse server response'
};
}
}
}
- if (status.code !== grpc.status.OK) {
+ if (status.code !== constants.status.OK) {
error = new Error(response.status.details);
error.code = status.code;
error.metadata = status.metadata;
@@ -921,7 +924,7 @@ exports.waitForClientReady = function(client, deadline, callback) {
/**
* Map of status code names to status codes
*/
-exports.status = grpc.status;
+exports.status = constants.status;
/**
* See docs for client.callError
diff --git a/src/node/src/constants.js b/src/node/src/constants.js
new file mode 100644
index 0000000000..528dab120e
--- /dev/null
+++ b/src/node/src/constants.js
@@ -0,0 +1,241 @@
+/*
+ *
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @module
+ */
+
+/* The comments about status codes are copied verbatim (with some formatting
+ * modifications) from include/grpc/impl/codegen/status.h, for the purpose of
+ * including them in generated documentation.
+ */
+/**
+ * Enum of status codes that gRPC can return
+ * @readonly
+ * @enum {number}
+ */
+exports.status = {
+ /** Not an error; returned on success */
+ OK: 0,
+ /** The operation was cancelled (typically by the caller). */
+ CANCELLED: 1,
+ /**
+ * Unknown error. An example of where this error may be returned is
+ * if a status value received from another address space belongs to
+ * an error-space that is not known in this address space. Also
+ * errors raised by APIs that do not return enough error information
+ * may be converted to this error.
+ */
+ UNKNOWN: 2,
+ /**
+ * Client specified an invalid argument. Note that this differs
+ * from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
+ * that are problematic regardless of the state of the system
+ * (e.g., a malformed file name).
+ */
+ INVALID_ARGUMENT: 3,
+ /**
+ * Deadline expired before operation could complete. For operations
+ * that change the state of the system, this error may be returned
+ * even if the operation has completed successfully. For example, a
+ * successful response from a server could have been delayed long
+ * enough for the deadline to expire.
+ */
+ DEADLINE_EXCEEDED: 4,
+ /** Some requested entity (e.g., file or directory) was not found. */
+ NOT_FOUND: 5,
+ /**
+ * Some entity that we attempted to create (e.g., file or directory)
+ * already exists.
+ */
+ ALREADY_EXISTS: 6,
+ /**
+ * The caller does not have permission to execute the specified
+ * operation. PERMISSION_DENIED must not be used for rejections
+ * caused by exhausting some resource (use RESOURCE_EXHAUSTED
+ * instead for those errors). PERMISSION_DENIED must not be
+ * used if the caller can not be identified (use UNAUTHENTICATED
+ * instead for those errors).
+ */
+ PERMISSION_DENIED: 7,
+ /**
+ * Some resource has been exhausted, perhaps a per-user quota, or
+ * perhaps the entire file system is out of space.
+ */
+ RESOURCE_EXHAUSTED: 8,
+ /**
+ * Operation was rejected because the system is not in a state
+ * required for the operation's execution. For example, directory
+ * to be deleted may be non-empty, an rmdir operation is applied to
+ * a non-directory, etc.
+ *
+ * A litmus test that may help a service implementor in deciding
+ * between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+ *
+ * - Use UNAVAILABLE if the client can retry just the failing call.
+ * - Use ABORTED if the client should retry at a higher-level
+ * (e.g., restarting a read-modify-write sequence).
+ * - Use FAILED_PRECONDITION if the client should not retry until
+ * the system state has been explicitly fixed. E.g., if an "rmdir"
+ * fails because the directory is non-empty, FAILED_PRECONDITION
+ * should be returned since the client should not retry unless
+ * they have first fixed up the directory by deleting files from it.
+ * - Use FAILED_PRECONDITION if the client performs conditional
+ * REST Get/Update/Delete on a resource and the resource on the
+ * server does not match the condition. E.g., conflicting
+ * read-modify-write on the same resource.
+ */
+ FAILED_PRECONDITION: 9,
+ /**
+ * The operation was aborted, typically due to a concurrency issue
+ * like sequencer check failures, transaction aborts, etc.
+ *
+ * See litmus test above for deciding between FAILED_PRECONDITION,
+ * ABORTED, and UNAVAILABLE.
+ */
+ ABORTED: 10,
+ /**
+ * Operation was attempted past the valid range. E.g., seeking or
+ * reading past end of file.
+ *
+ * Unlike INVALID_ARGUMENT, this error indicates a problem that may
+ * be fixed if the system state changes. For example, a 32-bit file
+ * system will generate INVALID_ARGUMENT if asked to read at an
+ * offset that is not in the range [0,2^32-1], but it will generate
+ * OUT_OF_RANGE if asked to read from an offset past the current
+ * file size.
+ *
+ * There is a fair bit of overlap between FAILED_PRECONDITION and
+ * OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific
+ * error) when it applies so that callers who are iterating through
+ * a space can easily look for an OUT_OF_RANGE error to detect when
+ * they are done.
+ */
+ OUT_OF_RANGE: 11,
+ /** Operation is not implemented or not supported/enabled in this service. */
+ UNIMPLEMENTED: 12,
+ /**
+ * Internal errors. Means some invariants expected by underlying
+ * system has been broken. If you see one of these errors,
+ * something is very broken.
+ */
+ INTERNAL: 13,
+ /**
+ * The service is currently unavailable. This is a most likely a
+ * transient condition and may be corrected by retrying with
+ * a backoff.
+ *
+ * See litmus test above for deciding between FAILED_PRECONDITION,
+ * ABORTED, and UNAVAILABLE. */
+ UNAVAILABLE: 14,
+ /** Unrecoverable data loss or corruption. */
+ DATA_LOSS: 15,
+ /**
+ * The request does not have valid authentication credentials for the
+ * operation.
+ */
+ UNAUTHENTICATED: 16
+};
+
+/* The comments about propagation bit flags are copied rom
+ * include/grpc/impl/codegen/propagation_bits.h for the purpose of including
+ * them in generated documentation.
+ */
+/**
+ * Propagation flags: these can be bitwise or-ed to form the propagation option
+ * for calls.
+ *
+ * Users are encouraged to write propagation masks as deltas from the default.
+ * i.e. write `grpc.propagate.DEFAULTS & ~grpc.propagate.DEADLINE` to disable
+ * deadline propagation.
+ * @enum {number}
+ */
+exports.propagate = {
+ DEADLINE: 1,
+ CENSUS_STATS_CONTEXT: 2,
+ CENSUS_TRACING_CONTEXT: 4,
+ CANCELLATION: 8,
+ DEFAULTS: 65535
+};
+
+/* Many of the following comments are copied from
+ * include/grpc/impl/codegen/grpc_types.h
+ */
+/**
+ * Call error constants. Call errors almost always indicate bugs in the gRPC
+ * library, and these error codes are mainly useful for finding those bugs.
+ * @enum {number}
+ */
+exports.callError = {
+ OK: 0,
+ ERROR: 1,
+ NOT_ON_SERVER: 2,
+ NOT_ON_CLIENT: 3,
+ ALREADY_INVOKED: 5,
+ NOT_INVOKED: 6,
+ ALREADY_FINISHED: 7,
+ TOO_MANY_OPERATIONS: 8,
+ INVALID_FLAGS: 9,
+ INVALID_METADATA: 10,
+ INVALID_MESSAGE: 11,
+ NOT_SERVER_COMPLETION_QUEUE: 12,
+ BATCH_TOO_BIG: 13,
+ PAYLOAD_TYPE_MISMATCH: 14
+};
+
+/**
+ * Write flags: these can be bitwise or-ed to form write options that modify
+ * how data is written.
+ * @enum {number}
+ */
+exports.writeFlags = {
+ /**
+ * Hint that the write may be buffered and need not go out on the wire
+ * immediately. GRPC is free to buffer the message until the next non-buffered
+ * write, or until writes_done, but it need not buffer completely or at all.
+ */
+ BUFFER_HINT: 1,
+ /**
+ * Force compression to be disabled for a particular write
+ */
+ NO_COMPRESS: 2
+};
+
+/**
+ * @enum {number}
+ */
+exports.logVerbosity = {
+ DEBUG: 0,
+ INFO: 1,
+ ERROR: 2
+};
diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js
index 51ff1da01e..b1e86bbd09 100644
--- a/src/node/src/credentials.js
+++ b/src/node/src/credentials.js
@@ -71,6 +71,8 @@ var Metadata = require('./metadata.js');
var common = require('./common.js');
+var constants = require('./constants');
+
var _ = require('lodash');
/**
@@ -97,14 +99,14 @@ exports.createFromMetadataGenerator = function(metadata_generator) {
return CallCredentials.createFromPlugin(function(service_url, cb_data,
callback) {
metadata_generator({service_url: service_url}, function(error, metadata) {
- var code = grpc.status.OK;
+ var code = constants.status.OK;
var message = '';
if (error) {
message = error.message;
if (error.hasOwnProperty('code') && _.isFinite(error.code)) {
code = error.code;
} else {
- code = grpc.status.UNAUTHENTICATED;
+ code = constants.status.UNAUTHENTICATED;
}
if (!metadata) {
metadata = new Metadata();
@@ -125,7 +127,7 @@ exports.createFromGoogleCredential = function(google_credential) {
var service_url = auth_context.service_url;
google_credential.getRequestMetadata(service_url, function(err, header) {
if (err) {
- common.log(grpc.logVerbosity.INFO, 'Auth error:' + err);
+ common.log(constants.logVerbosity.INFO, 'Auth error:' + err);
callback(err);
return;
}
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 3450abed08..08417a74c1 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -57,6 +57,8 @@ var common = require('./common');
var Metadata = require('./metadata');
+var constants = require('./constants');
+
var stream = require('stream');
var Readable = stream.Readable;
@@ -75,7 +77,7 @@ var EventEmitter = require('events').EventEmitter;
function handleError(call, error) {
var statusMetadata = new Metadata();
var status = {
- code: grpc.status.UNKNOWN,
+ code: constants.status.UNKNOWN,
details: 'Unknown Error'
};
if (error.hasOwnProperty('message')) {
@@ -115,7 +117,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
var end_batch = {};
var statusMetadata = new Metadata();
var status = {
- code: grpc.status.OK,
+ code: constants.status.OK,
details: 'OK'
};
if (metadata) {
@@ -125,7 +127,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
try {
message = serialize(value);
} catch (e) {
- e.code = grpc.status.INTERNAL;
+ e.code = constants.status.INTERNAL;
handleError(call, e);
return;
}
@@ -151,7 +153,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
function setUpWritable(stream, serialize) {
stream.finished = false;
stream.status = {
- code : grpc.status.OK,
+ code : constants.status.OK,
details : 'OK',
metadata : new Metadata()
};
@@ -178,7 +180,7 @@ function setUpWritable(stream, serialize) {
* @param {Error} err The error object
*/
function setStatus(err) {
- var code = grpc.status.UNKNOWN;
+ var code = constants.status.UNKNOWN;
var details = 'Unknown Error';
var metadata = new Metadata();
if (err.hasOwnProperty('message')) {
@@ -284,7 +286,7 @@ function _write(chunk, encoding, callback) {
try {
message = this.serialize(chunk);
} catch (e) {
- e.code = grpc.status.INTERNAL;
+ e.code = constants.status.INTERNAL;
callback(e);
return;
}
@@ -353,7 +355,7 @@ function _read(size) {
try {
deserialized = self.deserialize(data);
} catch (e) {
- e.code = grpc.status.INTERNAL;
+ e.code = constants.status.INTERNAL;
self.emit('error', e);
return;
}
@@ -489,7 +491,7 @@ function handleUnary(call, handler, metadata) {
try {
emitter.request = handler.deserialize(result.read);
} catch (e) {
- e.code = grpc.status.INTERNAL;
+ e.code = constants.status.INTERNAL;
handleError(call, e);
return;
}
@@ -530,7 +532,7 @@ function handleServerStreaming(call, handler, metadata) {
try {
stream.request = handler.deserialize(result.read);
} catch (e) {
- e.code = grpc.status.INTERNAL;
+ e.code = constants.status.INTERNAL;
stream.emit('error', e);
return;
}
@@ -636,7 +638,7 @@ function Server(options) {
batch[grpc.opType.SEND_INITIAL_METADATA] =
(new Metadata())._getCoreRepresentation();
batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
- code: grpc.status.UNIMPLEMENTED,
+ code: constants.status.UNIMPLEMENTED,
details: '',
metadata: {}
};
@@ -699,7 +701,7 @@ Server.prototype.register = function(name, handler, serialize, deserialize,
};
var unimplementedStatusResponse = {
- code: grpc.status.UNIMPLEMENTED,
+ code: constants.status.UNIMPLEMENTED,
details: 'The server does not implement this method'
};
@@ -759,8 +761,8 @@ Server.prototype.addService = function(service, implementation) {
written in the proto file, instead of using JavaScript function
naming style */
if (implementation[attrs.originalName] === undefined) {
- common.log(grpc.logVerbosity.ERROR, 'Method handler ' + name + ' for ' +
- attrs.path + ' expected but not provided');
+ common.log(constants.logVerbosity.ERROR, 'Method handler ' + name +
+ ' for ' + attrs.path + ' expected but not provided');
impl = defaultHandler[method_type];
} else {
impl = _.bind(implementation[attrs.originalName], implementation);
@@ -790,7 +792,7 @@ Server.prototype.addProtoService = function(service, implementation) {
var options;
var protobuf_js_5_common = require('./protobuf_js_5_common');
var protobuf_js_6_common = require('./protobuf_js_6_common');
- common.log(grpc.logVerbosity.INFO,
+ common.log(constants.logVerbosity.INFO,
'Server#addProtoService is deprecated. Use addService instead');
if (protobuf_js_5_common.isProbablyProtobufJs5(service)) {
options = _.defaults(service.grpc_options, common.defaultGrpcOptions);
diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js
index eb268603ea..f25268e8e6 100644
--- a/src/node/test/call_test.js
+++ b/src/node/test/call_test.js
@@ -35,6 +35,7 @@
var assert = require('assert');
var grpc = require('../src/grpc_extension');
+var constants = require('../src/constants');
/**
* Helper function to return an absolute deadline given a relative timeout in
@@ -120,7 +121,8 @@ describe('call', function() {
var batch = {};
batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
call.startBatch(batch, function(err, response) {
- assert.strictEqual(response.status.code, grpc.status.DEADLINE_EXCEEDED);
+ assert.strictEqual(response.status.code,
+ constants.status.DEADLINE_EXCEEDED);
done();
});
});
diff --git a/src/node/test/constant_test.js b/src/node/test/constant_test.js
deleted file mode 100644
index 414b1ac9c0..0000000000
--- a/src/node/test/constant_test.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-'use strict';
-
-var assert = require('assert');
-var grpc = require('../src/grpc_extension');
-
-/**
- * List of all status names
- * @const
- * @type {Array.<string>}
- */
-var statusNames = [
- 'OK',
- 'CANCELLED',
- 'UNKNOWN',
- 'INVALID_ARGUMENT',
- 'DEADLINE_EXCEEDED',
- 'NOT_FOUND',
- 'ALREADY_EXISTS',
- 'PERMISSION_DENIED',
- 'UNAUTHENTICATED',
- 'RESOURCE_EXHAUSTED',
- 'FAILED_PRECONDITION',
- 'ABORTED',
- 'OUT_OF_RANGE',
- 'UNIMPLEMENTED',
- 'INTERNAL',
- 'UNAVAILABLE',
- 'DATA_LOSS'
-];
-
-/**
- * List of all call error names
- * @const
- * @type {Array.<string>}
- */
-var callErrorNames = [
- 'OK',
- 'ERROR',
- 'NOT_ON_SERVER',
- 'NOT_ON_CLIENT',
- 'ALREADY_INVOKED',
- 'NOT_INVOKED',
- 'ALREADY_FINISHED',
- 'TOO_MANY_OPERATIONS',
- 'INVALID_FLAGS'
-];
-
-/**
- * List of all propagate flag names
- * @const
- * @type {Array.<string>}
- */
-var propagateFlagNames = [
- 'DEADLINE',
- 'CENSUS_STATS_CONTEXT',
- 'CENSUS_TRACING_CONTEXT',
- 'CANCELLATION',
- 'DEFAULTS'
-];
-/*
- * List of all connectivity state names
- * @const
- * @type {Array.<string>}
- */
-var connectivityStateNames = [
- 'IDLE',
- 'CONNECTING',
- 'READY',
- 'TRANSIENT_FAILURE',
- 'FATAL_FAILURE'
-];
-
-describe('constants', function() {
- it('should have all of the status constants', function() {
- for (var i = 0; i < statusNames.length; i++) {
- assert(grpc.status.hasOwnProperty(statusNames[i]),
- 'status missing: ' + statusNames[i]);
- }
- });
- it('should have all of the call errors', function() {
- for (var i = 0; i < callErrorNames.length; i++) {
- assert(grpc.callError.hasOwnProperty(callErrorNames[i]),
- 'call error missing: ' + callErrorNames[i]);
- }
- });
- it('should have all of the propagate flags', function() {
- for (var i = 0; i < propagateFlagNames.length; i++) {
- assert(grpc.propagate.hasOwnProperty(propagateFlagNames[i]),
- 'call error missing: ' + propagateFlagNames[i]);
- }
- });
- it('should have all of the connectivity states', function() {
- for (var i = 0; i < connectivityStateNames.length; i++) {
- assert(grpc.connectivityState.hasOwnProperty(connectivityStateNames[i]),
- 'connectivity status missing: ' + connectivityStateNames[i]);
- }
- });
-});
diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js
index f127a41de9..af455e2716 100644
--- a/src/node/test/end_to_end_test.js
+++ b/src/node/test/end_to_end_test.js
@@ -35,6 +35,7 @@
var assert = require('assert');
var grpc = require('../src/grpc_extension');
+var constants = require('../src/constants');
/**
* This is used for testing functions with multiple asynchronous calls that
@@ -90,7 +91,7 @@ describe('end-to-end', function() {
client_close: true,
metadata: {},
status: {
- code: grpc.status.OK,
+ code: constants.status.OK,
details: status_text,
metadata: {}
}
@@ -107,7 +108,7 @@ describe('end-to-end', function() {
server_batch[grpc.opType.SEND_INITIAL_METADATA] = {};
server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {},
- code: grpc.status.OK,
+ code: constants.status.OK,
details: status_text
};
server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
@@ -141,7 +142,7 @@ describe('end-to-end', function() {
send_metadata: true,
client_close: true,
metadata: {server_key: ['server_value']},
- status: {code: grpc.status.OK,
+ status: {code: constants.status.OK,
details: status_text,
metadata: {}}
});
@@ -161,7 +162,7 @@ describe('end-to-end', function() {
};
server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {},
- code: grpc.status.OK,
+ code: constants.status.OK,
details: status_text
};
server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
@@ -198,7 +199,7 @@ describe('end-to-end', function() {
assert.deepEqual(response.metadata, {});
assert(response.send_message);
assert.strictEqual(response.read.toString(), reply_text);
- assert.deepEqual(response.status, {code: grpc.status.OK,
+ assert.deepEqual(response.status, {code: constants.status.OK,
details: status_text,
metadata: {}});
done();
@@ -220,7 +221,7 @@ describe('end-to-end', function() {
response_batch[grpc.opType.SEND_MESSAGE] = new Buffer(reply_text);
response_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {},
- code: grpc.status.OK,
+ code: constants.status.OK,
details: status_text
};
response_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
@@ -260,7 +261,7 @@ describe('end-to-end', function() {
send_message: true,
client_close: true,
status: {
- code: grpc.status.OK,
+ code: constants.status.OK,
details: status_text,
metadata: {}
}
@@ -290,7 +291,7 @@ describe('end-to-end', function() {
end_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {},
- code: grpc.status.OK,
+ code: constants.status.OK,
details: status_text
};
server_call.startBatch(end_batch, function(err, response) {