UNPKG

@gridgain/thin-client

Version:

NodeJS Client for Gridgain Community Edition

292 lines (267 loc) 9.95 kB
/* * Copyright 2019 GridGain Systems, Inc. and Contributors. * * Licensed under the GridGain Community Edition License (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.gridgain.com/products/software/community-edition/gridgain-community-edition-license * * 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. */ 'use strict'; const CacheClient = require('./CacheClient'); const IgniteClientConfiguration = require('./IgniteClientConfiguration'); const CacheConfiguration = require('./CacheConfiguration'); const BinaryUtils = require('./internal/BinaryUtils'); const BinaryCommunicator = require('./internal/BinaryCommunicator'); const ArgumentChecker = require('./internal/ArgumentChecker'); const Logger = require('./internal/Logger'); /** * State of GridGain client. * * @typedef IgniteClient.STATE * @enum * @readonly * @property DISCONNECTED The client is not connected to any GridGain node, * operations with the GridGain server are not allowed. * This is initial state after a client instance creation. * If connect() method is called, the client moves to CONNECTING state. * @property CONNECTING The client tries to connect to a GridGain node, * operations with the GridGain server are not allowed. * If disconnect() method is called, the client moves to DISCONNECTED state. * If not possible to connect to any GridGain node, the client moves to DISCONNECTED state. * If connection to a GridGain node is successful, the client moves to CONNECTED state. * @property CONNECTED The client is connected to a GridGain node, * all operations with the GridGain server are allowed. * If connection with the GridGain node is lost, the client moves to CONNECTING state. * If disconnect() method is called, the client moves to DISCONNECTED state. */ const STATE = Object.freeze({ DISCONNECTED : 0, CONNECTING : 1, CONNECTED : 2 }); /** * Class representing GridGain client. * */ class IgniteClient { /** * Public constructor. * * @param {IgniteClient.onStateChanged} [onStateChanged] - * callback called everytime when the client has moved to a new state {@link IgniteClient.STATE}. * * @return {IgniteClient} - new IgniteClient instance. */ constructor(onStateChanged = null) { const Router = require('./internal/Router'); this._router = new Router(onStateChanged); this._communicator = new BinaryCommunicator(this._router); } static get STATE() { return STATE; } /** * onStateChanged callback. * @callback IgniteClient.onStateChanged * @param {IgniteClient.STATE} state - the new state of the client. * @param {string} reason - the reason why the state has been changed. */ /** * Connects the client. * * Should be called from DISCONNECTED state only. * Moves the client to CONNECTING state. * * @async * * @param {IgniteClientConfiguration} config - the client configuration. * * @throws {IllegalStateError} if the client is not in DISCONNECTED {@link IgniteClient.STATE}. * @throws {IgniteClientError} if other error. */ async connect(config) { ArgumentChecker.notEmpty(config, 'config'); ArgumentChecker.hasType(config, 'config', false, IgniteClientConfiguration); await this._router.connect(this._communicator, config); } /** * Disconnects the client. * * Moves the client to DISCONNECTED state from any other state. * Does nothing if the client already disconnected. */ disconnect() { this._router.disconnect(); } /** * Creates new cache with the provided name and optional configuration. * * @async * * @param {string} name - cache name. * @param {CacheConfiguration} [cacheConfig] - cache configuration. * * @return {Promise<CacheClient>} - new cache client instance for the created cache. * * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}. * @throws {OperationError} if cache with the provided name already exists. * @throws {IgniteClientError} if other error. */ async createCache(name, cacheConfig = null) { ArgumentChecker.notEmpty(name, 'name'); ArgumentChecker.hasType(cacheConfig, 'cacheConfig', false, CacheConfiguration); await this._communicator.send( cacheConfig ? BinaryUtils.OPERATION.CACHE_CREATE_WITH_CONFIGURATION : BinaryUtils.OPERATION.CACHE_CREATE_WITH_NAME, async (payload) => { await this._writeCacheNameOrConfig(payload, name, cacheConfig); }); return this._getCache(name, cacheConfig); } /** * Gets existing cache with the provided name * or creates new one with the provided name and optional configuration. * * @async * * @param {string} name - cache name. * @param {CacheConfiguration} [cacheConfig] - cache configuration (ignored if cache * with the provided name already exists). * * @return {Promise<CacheClient>} - new cache client instance for the existing or created cache. * * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}. * @throws {IgniteClientError} if other error. */ async getOrCreateCache(name, cacheConfig = null) { ArgumentChecker.notEmpty(name, 'name'); ArgumentChecker.hasType(cacheConfig, 'cacheConfig', false, CacheConfiguration); await this._communicator.send( cacheConfig ? BinaryUtils.OPERATION.CACHE_GET_OR_CREATE_WITH_CONFIGURATION : BinaryUtils.OPERATION.CACHE_GET_OR_CREATE_WITH_NAME, async (payload) => { await this._writeCacheNameOrConfig(payload, name, cacheConfig); }); return this._getCache(name, cacheConfig); } /** * Gets cache client instance of cache with the provided name. * The method does not check if the cache with the provided name exists. * * @param {string} name - cache name. * * @return {CacheClient} - new cache client instance. * * @throws {IgniteClientError} if error. */ getCache(name) { ArgumentChecker.notEmpty(name, 'name'); return this._getCache(name); } /** * Destroys cache with the provided name. * * @async * * @param {string} name - cache name. * * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}. * @throws {OperationError} if cache with the provided name does not exist. * @throws {IgniteClientError} if other error. */ async destroyCache(name) { ArgumentChecker.notEmpty(name, 'name'); const cacheId = CacheClient._calculateId(name); await this._communicator.send( BinaryUtils.OPERATION.CACHE_DESTROY, async (payload) => { payload.writeInteger(cacheId); }); } /** * Returns configuration of cache with the provided name. * * @async * * @param {string} name - cache name. * * @return {Promise<CacheConfiguration>} - cache configuration * * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}. * @throws {OperationError} if cache with the provided name does not exist. * @throws {IgniteClientError} if other error. */ async getCacheConfiguration(name) { ArgumentChecker.notEmpty(name, 'name'); let config; await this._communicator.send( BinaryUtils.OPERATION.CACHE_GET_CONFIGURATION, async (payload) => { payload.writeInteger(CacheClient._calculateId(name)); payload.writeByte(0); }, async (payload) => { config = new CacheConfiguration(); await config._read(this._communicator, payload); }); return config; } /** * Gets existing cache names. * * @async * * @return {Promise<Array<string>>} - array with the existing cache names. * The array is empty if no caches exist. * * @throws {IllegalStateError} if the client is not in CONNECTED {@link IgniteClient.STATE}. * @throws {IgniteClientError} if other error. */ async cacheNames() { let names; await this._communicator.send( BinaryUtils.OPERATION.CACHE_GET_NAMES, null, async (payload) => { names = await this._communicator.readStringArray(payload); }); return names; } /** * Enables/disables the library debug output (including errors logging). * Disabled by default. * * @param {boolean} value - true to enable, false to disable */ setDebug(value) { Logger.debug = value; } /** Private methods */ /** * @ignore */ _getCache(name, cacheConfig = null) { return new CacheClient(name, cacheConfig, this._communicator); } /** * @ignore */ async _writeCacheNameOrConfig(buffer, name, cacheConfig) { if (cacheConfig) { await cacheConfig._write(this._communicator, buffer, name); } else { BinaryCommunicator.writeString(buffer, name); } } } module.exports = IgniteClient;