| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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. |
| */ |
| |
| 'use strict'; |
| |
| import BinaryCommunicator from "./internal/BinaryCommunicator"; |
| import ArgumentChecker from "./internal/ArgumentChecker"; |
| import Logger from "./internal/Logger"; |
| |
| import Router from "./internal/Router"; |
| import {IgniteClientConfiguration} from "./IgniteClientConfiguration"; |
| import {CacheConfiguration} from "./CacheConfiguration"; |
| import { CacheClient } from "./CacheClient"; |
| import BinaryUtils from "./internal/BinaryUtils"; |
| import MessageBuffer from "./internal/MessageBuffer"; |
| |
| /** |
| * State of Ignite client. |
| * |
| * @typedef IgniteClient.STATE |
| * @enum |
| * @readonly |
| * @property DISCONNECTED The client is not connected to any Ignite node, |
| * operations with the Ignite 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 an Ignite node, |
| * operations with the Ignite server are not allowed. |
| * If disconnect() method is called, the client moves to DISCONNECTED state. |
| * If not possible to connect to any Ignite node, the client moves to DISCONNECTED state. |
| * If connection to an Ignite node is successful, the client moves to CONNECTED state. |
| * @property CONNECTED The client is connected to an Ignite node, |
| * all operations with the Ignite server are allowed. |
| * If connection with the Ignite node is lost, the client moves to CONNECTING state. |
| * If disconnect() method is called, the client moves to DISCONNECTED state. |
| */ |
| export enum STATE { |
| DISCONNECTED = 0, |
| CONNECTING = 1, |
| CONNECTED = 2 |
| } |
| |
| export type IgniteClientOnStateChanged = (state: STATE, reason: string) => void; |
| |
| /** |
| * Class representing Ignite client. |
| * |
| */ |
| export class IgniteClient { |
| |
| private _router: Router; |
| |
| private _communicator: BinaryCommunicator; |
| |
| /** |
| * Public constructor. |
| * |
| * @param {IgniteClientOnStateChanged} [onStateChanged] - |
| * callback called everytime when the client has moved to a new state {@link STATE}. |
| * |
| * @return {IgniteClient} - new IgniteClient instance. |
| */ |
| constructor(onStateChanged: IgniteClientOnStateChanged = null) { |
| this._router = new Router(onStateChanged); |
| this._communicator = new BinaryCommunicator(this._router); |
| } |
| |
| static get STATE() { |
| return STATE; |
| } |
| |
| /** |
| * 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: IgniteClientConfiguration): Promise<void> { |
| 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): Promise<CacheClient> { |
| 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(): Promise<string[]> { |
| 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: string, cacheConfig: CacheConfiguration = null) { |
| return new CacheClient(name, cacheConfig, this._communicator); |
| } |
| |
| /** |
| * @ignore |
| */ |
| async _writeCacheNameOrConfig(buffer: MessageBuffer, name: string, cacheConfig: CacheConfiguration) { |
| if (cacheConfig) { |
| await cacheConfig._write(this._communicator, buffer, name); |
| } |
| else { |
| BinaryCommunicator.writeString(buffer, name); |
| } |
| } |
| } |