blob: 2913389f512c86c956cb5a0c1a5deb6e4870b030 [file]
/**
* 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.
*/
import { deserializeError } from '../error.utils.js';
import {
type ClusterNodeRoleKey,
type ClusterNodeStatusKey,
type TransportProtocolKey,
mapClusterNodeRole,
mapClusterNodeStatus,
mapTransportProtocol,
} from './cluster.type.js';
export type ClusterNode = {
id: number
name: string
address: string
role: ClusterNodeRoleKey
status: ClusterNodeStatusKey
}
type DeserializedClusterNode = { length: number, data: ClusterNode }
const CLUSTER_NODE_MIN_BUFFER_SIZE = 16; // 4 + 1 + 4 + 1 + 4 + 1 + 1;
export const deserializeNode = (b: Buffer, pos = 0): DeserializedClusterNode => {
if (b.length - pos < CLUSTER_NODE_MIN_BUFFER_SIZE)
deserializeError(
'cluster node', pos, b.length, CLUSTER_NODE_MIN_BUFFER_SIZE
);
const id = b.readUInt32LE(pos);
pos += 4;
const nameLen = b.readUInt32LE(pos);
if (b.length - pos < 4 + nameLen)
deserializeError(
'cluster node', pos, b.length, 4 + nameLen, { id, nameLen }
);
const name = b.subarray(pos + 4, pos + 4 + nameLen).toString();
pos += nameLen + 4;
const addrLen = b.readUInt32LE(pos);
if (b.length - pos < 4 + addrLen)
deserializeError(
'cluster node', pos, b.length, 4 + addrLen, { id, nameLen, name, addrLen }
);
const address = b.subarray(pos + 4, pos + 4 + addrLen).toString();
pos += addrLen + 4;
if (b.length - pos < 2)
deserializeError(
'cluster node', pos, b.length, 2, { id, nameLen, name, addrLen, address }
);
const role = mapClusterNodeRole(b.readUInt8(pos));
pos += 1;
const status = mapClusterNodeStatus(b.readUInt8(pos));
pos += 1;
return {
length: 4 + nameLen + 4 + addrLen + 4 + 1 + 1,
data: {
id,
name,
address,
role,
status
}
}
};
export type ClusterMetadata = {
// Name of the cluster.
name: string,
// Unique identifier of the cluster.
id: number,
// Transport used for cluster communication
// (for binary protocol it's u8, 1=TCP, 2=QUIC, 3=HTTP).
transport: TransportProtocolKey,
// List of all nodes in the cluster.
nodes: ClusterNode[],
};
// min = 4 + 1 + 4 + 1 + 1 + 4 + CLUSTER_NODE_MIN_BUFFER_SIZE;
const CLUSTER_METADATA_MIN_SIZE = 15 + CLUSTER_NODE_MIN_BUFFER_SIZE;
export const deserializeMetadata = (b: Buffer, pos = 0): ClusterMetadata => {
if (b.length - pos < CLUSTER_METADATA_MIN_SIZE)
deserializeError(
'cluster metadata', pos, b.length, CLUSTER_METADATA_MIN_SIZE
);
const nameLen = b.readUInt32LE(pos);
if (b.length - pos < 4 + nameLen)
deserializeError(
'cluster metadata', pos, b.length, 4 + nameLen, { nameLen }
);
const name = b.subarray(pos + 4, pos + 4 + nameLen).toString();
pos += nameLen + 4;
if (b.length - pos < 4 + 1 + 4)
deserializeError(
'cluster metadata', pos, b.length, 4 + 1 + 4, { nameLen, name }
);
const id = b.readUInt32LE(pos);
pos += 4;
const transport = mapTransportProtocol(b.readUInt8(pos));
pos += 1;
const nodeCount = b.readUInt32LE(pos);
pos += 4;
const nodes: ClusterNode[] = [];
for (let i = 0; i < nodeCount; i++) {
const { length, data } = deserializeNode(b, pos);
nodes.push(data);
pos += length;
}
return {
name,
id,
transport,
nodes
}
};