Files
RoboCommander/node_modules/neo4j-driver/lib/v1/internal/routing-util.js
2026-04-05 16:14:49 -04:00

175 lines
7.2 KiB
JavaScript

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _from = require('babel-runtime/core-js/array/from');
var _from2 = _interopRequireDefault(_from);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _error = require('../error');
var _integer = require('../integer');
var _integer2 = _interopRequireDefault(_integer);
var _serverVersion = require('./server-version');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var CALL_GET_SERVERS = 'CALL dbms.cluster.routing.getServers'; /**
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var GET_ROUTING_TABLE_PARAM = 'context';
var CALL_GET_ROUTING_TABLE = 'CALL dbms.cluster.routing.getRoutingTable({' + GET_ROUTING_TABLE_PARAM + '})';
var PROCEDURE_NOT_FOUND_CODE = 'Neo.ClientError.Procedure.ProcedureNotFound';
var UNAUTHORIZED_CODE = 'Neo.ClientError.Security.Unauthorized';
var RoutingUtil = function () {
function RoutingUtil(routingContext) {
(0, _classCallCheck3.default)(this, RoutingUtil);
this._routingContext = routingContext;
}
/**
* Invoke routing procedure using the given session.
* @param {Session} session the session to use.
* @param {string} routerAddress the URL of the router.
* @return {Promise<Record[]>} promise resolved with records returned by the procedure call or null if
* connection error happened.
*/
(0, _createClass3.default)(RoutingUtil, [{
key: 'callRoutingProcedure',
value: function callRoutingProcedure(session, routerAddress) {
return this._callAvailableRoutingProcedure(session).then(function (result) {
session.close();
return result.records;
}).catch(function (error) {
if (error.code === PROCEDURE_NOT_FOUND_CODE) {
// throw when getServers procedure not found because this is clearly a configuration issue
throw (0, _error.newError)('Server at ' + routerAddress + ' can\'t perform routing. Make sure you are connecting to a causal cluster', _error.SERVICE_UNAVAILABLE);
} else if (error.code === UNAUTHORIZED_CODE) {
// auth error is a sign of a configuration issue, rediscovery should not proceed
throw error;
} else {
// return nothing when failed to connect because code higher in the callstack is still able to retry with a
// different session towards a different router
return null;
}
});
}
}, {
key: 'parseTtl',
value: function parseTtl(record, routerAddress) {
try {
var now = (0, _integer.int)(Date.now());
var expires = record.get('ttl').multiply(1000).add(now);
// if the server uses a really big expire time like Long.MAX_VALUE this may have overflowed
if (expires.lessThan(now)) {
return _integer2.default.MAX_VALUE;
}
return expires;
} catch (error) {
throw (0, _error.newError)('Unable to parse TTL entry from router ' + routerAddress + ' from record:\n' + (0, _stringify2.default)(record), _error.PROTOCOL_ERROR);
}
}
}, {
key: 'parseServers',
value: function parseServers(record, routerAddress) {
try {
var servers = record.get('servers');
var routers = [];
var readers = [];
var writers = [];
servers.forEach(function (server) {
var role = server['role'];
var addresses = server['addresses'];
if (role === 'ROUTE') {
routers = parseArray(addresses);
} else if (role === 'WRITE') {
writers = parseArray(addresses);
} else if (role === 'READ') {
readers = parseArray(addresses);
} else {
throw (0, _error.newError)('Unknown server role "' + role + '"', _error.PROTOCOL_ERROR);
}
});
return {
routers: routers,
readers: readers,
writers: writers
};
} catch (ignore) {
throw (0, _error.newError)('Unable to parse servers entry from router ' + routerAddress + ' from record:\n' + (0, _stringify2.default)(record), _error.PROTOCOL_ERROR);
}
}
}, {
key: '_callAvailableRoutingProcedure',
value: function _callAvailableRoutingProcedure(session) {
var _this = this;
return session._run(null, null, function (connection, streamObserver) {
var serverVersionString = connection.server.version;
var serverVersion = _serverVersion.ServerVersion.fromString(serverVersionString);
if (serverVersion.compareTo(_serverVersion.VERSION_3_2_0) >= 0) {
var params = (0, _defineProperty3.default)({}, GET_ROUTING_TABLE_PARAM, _this._routingContext);
connection.run(CALL_GET_ROUTING_TABLE, params, streamObserver);
} else {
connection.run(CALL_GET_SERVERS, {}, streamObserver);
}
});
}
}]);
return RoutingUtil;
}();
exports.default = RoutingUtil;
function parseArray(addresses) {
if (!Array.isArray(addresses)) {
throw new TypeError('Array expected but got: ' + addresses);
}
return (0, _from2.default)(addresses);
}