barracuda-client-api
Version:
API Client to connect to Barracuda Enterprise Service Bus
540 lines (477 loc) • 17.8 kB
text/typescript
import { loglevels } from "./logging/index";
import {
BarracudaPublisherCommandType,
BarracudaBridgeReadQueryCommands,
IBarracudaSubscriptionStatus,
} from "./BarracudaClient";
export enum BarracudaConnectionStatus {
/**
* Triggered when websockets connect
* @type {BarracudaConnectionStatus.connected}
*/
connected = "connected",
/**
* Triggered when Barracuda Bridge acknowledges connection.
* It means the server registered the client internally and assigned a client id
* communicated back.
* @type {BarracudaConnectionStatus.connectedAck}
*/
connectedAck = "connectedAck",
/**
* Intermittent state of while connecting to websockets
*/
connecting = "connecting",
disconnected = "disconnected",
/**
* Triggered when the connection over websockets have failed
* @type {BarracudaConnectionStatus.connectionError}
*/
connectionError = "connection-error",
/**
* Indicates the BCjs is reconnecting
* @type {BarracudaConnectionStatus.reconnecting}
*/
reconnecting = "reconnecting",
/**
* Initial state when a client instance is created
* @type {BarracudaConnectionStatus.unknown}
*/
unknown = "unknown",
/**
* During closing, errors and messages are handled differently.
* @type {BarracudaConnectionStatus.closing}
*/
closing = "closing",
}
export type BarracudaErrorHandler =
| ((error: Error, bc: IBarracudaClient) => void)
| undefined;
export interface BarracudaAuthenticationProps {
readonly gaToken?: string;
}
export interface BarracudaPublishingProps extends BarracudaAuthenticationProps {
readonly publishRestEndPoint?: string;
readonly onError?: BarracudaErrorHandler;
}
export type SubscriptionUpdateHandler = (
subscriptionStatus: IBarracudaSubscriptionStatus,
bc: IBarracudaClient
) => void;
export type ConnectionStateChangeHandler = (
state: BarracudaConnectionStatus,
bc: IBarracudaClient
) => void;
export interface BarracudaConnectionHandlers {
readonly onConnectionError?: BarracudaErrorHandler;
readonly onError?: BarracudaErrorHandler;
/**
* Set handler to subscribe to connection status changes
*/
readonly onConnectionStateChange?: ConnectionStateChangeHandler;
/**
* Set handler for subscription status changes. Use to report errors for a specific subscription.
* Needs to be supported by Barracuda Bridge Server, BBS needs to report subscription level errors back to the UI using the IBarracudaBridgeSubscriptionStatus
* @param {IBarracudaSubscriptionStatus} subscriptionStatus
*/
readonly onSubscriptionUpdate?: SubscriptionUpdateHandler;
}
export interface BarracudaConnectionProps
extends BarracudaConnectionHandlers,
BarracudaAuthenticationProps {
readonly reconnect?: boolean;
readonly endpoint?: string;
readonly instance?: string;
readonly appName?: string;
readonly appVersion?: string;
}
export interface IBarracudaLoggingProps {
loglevel?: loglevels;
readonly serverDebug?: boolean;
}
export interface BarracudaDefaultProps
extends BarracudaConnectionProps,
BarracudaPublishingProps,
IBarracudaLoggingProps {}
export type BarracudaBridgeMessageType =
| "IBarracudaBridgeRequestResponse"
| "IBarracudaBridgeConnectionStatus"
| "IBarracudaBridgeSubscriptionResponse"
| "IBarracudaBridgeSubscriptionStatus"
| "IBarracudaBridgeRequest"
| "IBarracudaBridgeSubscriptionRequest"
| "IBarracudaBridgeCommandRequest"
| "IBarracudaBridgeCommandRequestResponse"
| "IBarracudaBridgePing"
| "IBarracudaBridgePong";
export interface IBarracudaBridgeMessage {
messageType: BarracudaBridgeMessageType;
}
export interface IBarracudaBridgeRequestResponse
extends IBarracudaBridgeMessage {
requestId: string;
subscriptionId?: string;
success?: boolean;
error?: string;
}
export type BarracudaBridgeAckStatus = "Connected";
export interface IBarracudaBridgeConnectionStatus
extends IBarracudaBridgeMessage {
status: BarracudaBridgeAckStatus;
host: string;
clientId: string;
apiMajor: number;
apiMinor: number;
buildVersion: string;
}
export enum BarracudaTopicInfoType {
barracuda_keys = "barracuda_keys",
documentsCount = "documentsCount",
size = "size",
}
export enum BarracudaBridgeResponseCommandTypes {
sow = "SOW",
publish = "Publish",
groupBegin = "GroupBegin",
groupEnd = "GroupEnd",
oof = "OOF",
}
export interface IBarracudaBridgeSubscriptionResponse<T>
extends IBarracudaBridgeMessage {
subscriptionId: string;
messages: BarracudaBridgeSubscriptionMessage<T>[];
}
export interface BarracudaBridgeSubscriptionMessage<T> {
command: BarracudaBridgeResponseCommandTypes;
data: T;
}
export enum BarracudaBridgeSubscriptionStatus {
unknown = "unknown",
subscriptionRequestAcknowledged = "subscriptionRequestAcknowledged",
subscribed = "subscribed",
heartbeat = "heartbeat",
lastMsg = "lastMsg",
error = "error",
unsubscribeRequestAcknowledged = "unsubscribeRequestAcknowledged",
unsubscribed = "unsubscribed",
}
export interface BarracudaBuildInfo {
name: string;
version: string;
}
export interface IBarracudaClient extends BarracudaConnectionProps {
loglevel: loglevels;
readonly connectionState: BarracudaConnectionStatus;
readonly uid: string;
/**
* A shorter version of uid
*/
readonly logUid: string;
readonly connectionAckMessage: IBarracudaBridgeConnectionStatus | undefined;
readonly lastConnectionProps: BarracudaConnectionProps;
readonly defaultConnectionProps: BarracudaConnectionProps;
connect(props: BarracudaConnectionProps): Promise<BarracudaConnectionProps>;
_emulateServerDisconnect(): void;
/** @deprecated
* Will trigger closing the client asynchronously, the client and underlying websocket will confirm the close with the server.
*/
close(): void;
connectionCounter: number;
bcLog(props: BarracudaConnectionProps): string;
disconnect(): Promise<{ code: number; reason: string }>;
}
export interface IBarracudaClientPublisher extends IBarracudaClient {
/**
* Sends a message to a topic on Barracuda Enterprise Service Bus.
* *Note* Currently uses Francesco's REST -> Kafka service for testing.
* @param {string} topic, equivalent to AMPS topic, or MongoDb collection
* @param msg to send, it could be a {string} or any {object} and {JSON.stringify} will be used for serialization
* @param type see {BarracudaPublisherCommandType} types.
* - replace - publish message and replace existing content; in MongoDB it would be -> replaceOne upsert:true
* - upsert - updates message and reinsert it if it doesn't exist based on configured key/s; in MongoDB it would be -> updateOne upsert:true
* - update - updates message and skipped if message doesn't exist based on configured key/s; in MongoDB it would be -> updateOne upsert:false
* - delete - deletes message based on configured key/s.
* @param props
*/
send(
topic: string,
msg: any,
type: BarracudaPublisherCommandType,
props?: BarracudaPublishingProps
): Promise<{ reply?: string; message?: string } | undefined>;
}
export interface IBarracudaClientConsumer extends IBarracudaClient {
subscriptions: IBarracudaSubscriptionStatus[];
previousSessionSubscriptions: IBarracudaSubscriptionStatus[];
/**
* Snaps a static latest state from Barracuda Enterprise Service Bus
* @param {string} instance, preferred use of instances as environment + namespaces; for example, stabledev-local-cigam-barracuda. . *Note* translates internally to MongoDb database
* @param {string} topic, equivalent to AMPS topic, or MongoDb collection
* @param {(m: (IBarracudaBridgeRequestResponse | IBarracudaBridgeSubscriptionResponse)) => void} message
* @param {string} filter, use Mongo/Mango query expressions https://github.com/cloudant/mango
* @param {number} top, default is 50,000 documents
* @param project
* @param sort
* @param heartbeatPeriod
* @returns {Promise<string>} which is a subscriptionId. This is needed because of large snapshots, underlying implementation uses a subscription that could be canceled using {IBarracudaClientConsumer.unsubscribe}
*/
snapshot<T>(
instance: string,
topic: string,
message: (
m:
| IBarracudaBridgeRequestResponse
| IBarracudaBridgeSubscriptionResponse<T>
) => void,
filter?: string,
top?: number,
project?: string[],
sort?: BarracudaQuerySort,
heartbeatPeriod?: number
): Promise<string>;
/**
* @deprecated use subscribeQuery instead...
* Snaps and subscribe to changed documents stream from Barracuda Enterprise Service Bus
* @param {string} instance, preferred use of instances as environment + namespaces; for example, stabledev-local-cigam-barracuda. . *Note* translates internally to MongoDb database
* @param {string} topic, equivalent to AMPS topic, or MongoDb collection
* @param {(m: (IBarracudaBridgeRequestResponse | IBarracudaBridgeSubscriptionResponse)) => void} message
* @param {string} filter, use Mongo/Mango query expressions https://github.com/cloudant/mango
* @param {number} top, default is 50,000 documents
* @param project
* @param sort
* @param heartbeatPeriod
* @returns {Promise<string>}
*/
snapshotAndSubscribe<T>(
instance: string,
topic: string,
message: (
m:
| IBarracudaBridgeRequestResponse
| IBarracudaBridgeSubscriptionResponse<T>
) => void,
filter?: string,
top?: number,
project?: string[],
sort?: BarracudaQuerySort,
heartbeatPeriod?: number
): Promise<string>;
/**
* @deprecated use subscribeQuery instead...
* Snaps and subscribe to change event stream from Barracuda Enterprise Service Bus
* @param {string} instance, preferred use of instances as environment + namespaces; for example, stabledev-local-cigam-barracuda. . *Note* translates internally to MongoDb database
* @param {string} topic, equivalent to AMPS topic, or MongoDb collection
* @param {(m: (IBarracudaBridgeRequestResponse | IBarracudaBridgeSubscriptionResponse)) => void} message
* @param {string} filter, use Mongo/Mango query expressions https://github.com/cloudant/mango
* @param {number} top, default is 50,000 documents
* @param project
* @param sort
* @param heartbeatPeriod
* @returns {Promise<string>}
*/
snapshotAndDiffSubscribe<T>(
instance: string,
topic: string,
message: (
m:
| IBarracudaBridgeRequestResponse
| IBarracudaBridgeSubscriptionResponse<T>
) => void,
filter?: string,
top?: number,
project?: string[],
sort?: BarracudaQuerySort,
heartbeatPeriod?: number
): Promise<string>;
/**
* @deprecated use subscribeQuery instead...
* Subscribes to change event stream from Barracuda Enterprise Service Bus
* @param {string} instance, preferred use of instances as environment + namespaces; for example, stabledev-local-cigam-barracuda. . *Note* translates internally to MongoDb database
* @param {string} topic, equivalent to AMPS topic, or MongoDb collection
* @param {(m: (IBarracudaBridgeRequestResponse | IBarracudaBridgeSubscriptionResponse)) => void} message
* @param {string} filter, use Mongo/Mango query expressions https://github.com/cloudant/mango
* @param {number} top, default is 50,000 documents
* @param project
* @param sort
* @param heartbeatPeriod
* @returns {Promise<string>}
*/
subscribeDiff<T>(
instance: string,
topic: string,
message: (
m:
| IBarracudaBridgeRequestResponse
| IBarracudaBridgeSubscriptionResponse<T>
) => void,
filter?: string,
top?: number,
project?: string[],
sort?: BarracudaQuerySort,
heartbeatPeriod?: number
): Promise<string>;
/**
* @deprecated use subscribeQuery instead...
* Subscribe to changed documents stream from Barracuda Enterprise Service Bus
* @param {string} instance, preferred use of instances as environment + namespaces; for example, stabledev-local-cigam-barracuda. . *Note* translates internally to MongoDb database
* @param {string} topic, equivalent to AMPS topic, or MongoDb collection
* @param {(m: (IBarracudaBridgeRequestResponse | IBarracudaBridgeSubscriptionResponse)) => void} message
* @param {string} filter, use Mongo/Mango query expressions https://github.com/cloudant/mango
* @param {number} top, default is 50,000 documents
* @param project
* @param sort
* @param heartbeatPeriod
* @returns {Promise<string>}
*/
subscribe<T>(
instance: string,
topic: string,
message: (
m:
| IBarracudaBridgeRequestResponse
| IBarracudaBridgeSubscriptionResponse<T>
) => void,
filter?: string,
top?: number,
project?: string[],
sort?: BarracudaQuerySort,
heartbeatPeriod?: number
): Promise<string>;
/**
* Unsubscribe an active subscription
* @param {string} subscriptionId
*/
unsubscribe(subscriptionId: string): void;
/**
* Utility function with simple query based interface. Combined subscribe, subscribeDiff, snapshot, snapshotAndSubscribe, snapshotAndDiffSubscribe into one interface.
* @param {BarracudaBridgeQueryCommands} commandType
* @param {BarracudaQuery<T>} queryDetails
* @returns {Promise<QuerySubscription>}
*/
subscribeQuery<T>(
commandType: BarracudaBridgeReadQueryCommands,
queryDetails: BarracudaQuery<T>
): Promise<QuerySubscription>;
/**
* Requests details about a specific topic. For example, keys for that topic, number of documents or size of topic.
* @param {string} topic
* @param {BarracudaTopicInfoType} infoType
* @returns {Promise<any>}
*/
getTopicInfo(
topic: string,
infoType: BarracudaTopicInfoType,
instance?: string
): Promise<any>;
/**
* Set handler for subscription stale event. If a message or a heartbeat is received for a subscription, that timer will be reset.
* @param onStale, handler triggered when a subscription is stale.
* @param seconds, amount of seconds before considering a subscription is stale.
*/
setOnStaleSubscriptionAlert(
onStale: SubscriptionUpdateHandler,
seconds?: number
): void;
/**
* Aggregates results from a topic using a pipeline, for more details and examples visit https://docs.mongodb.com/manual/reference/command/aggregate/
* *Note* Due to performance impact of multiple rountrips, this function will not validate topic/instance names provided, it will only return an empty result set.
* @param topic - it needs to be a correct topic name
* @param {any[]} pipeline - array of Mongo pipeline of operations
* @param instance - if not provided, the default constructor one will be used
* @param maxTimeMS with a default of 5 seconds
* @param batchSize with a default of 50,000 documents
* @returns {Promise<any[] | undefined>}
*/
aggregate<T>(
topic: any,
pipeline: Record<string, any>[],
instance?: any,
maxTimeMS?: number,
batchSize?: number
): Promise<any[] | undefined>;
}
export interface IBarracudaClientFullDuplex
extends IBarracudaClient,
IBarracudaClientConsumer,
IBarracudaClientPublisher {}
export interface BarracudaQuerySort {
[id: string]: -1 | 1;
}
/**
* provide Barracuda query attributes
*/
export interface BarracudaQuery<T> {
/**
* required for every query
*/
topic: string;
/**
* Will use default instance specified in constructor, and could be overridden by passing an instance here.
* The server was tested to validate if the passed instance is correct, will throw an error if not.
*/
instance?: string;
/**
* filters in Mango query
*/
filter?: string;
/**
* If not specified, a default 50,000 value is used to protect the server from accidental abuse. if you expect your query to return more than 50k documents, please manually override it here.
*/
top?: number;
/**
* A list of fields to be projected, for example ['deskId', 'userId', 'address.zipcode']. fields 'keys' that are part of the barracuda_keys index will be sent irrespective of projection.
*/
project?: string[] | undefined;
/**
* Mango query like sorting, for example { "deskId': -1 }.
*/
sort?: BarracudaQuerySort;
onMessage: (
batch: BarracudaBridgeSubscriptionMessage<T>[],
subscriptionId: string
) => void;
/**
* Subscription level heartbeats in seconds. default is zero, which means 'no heartbeats' for this subscription request. Use to detect stale subscriptions, combine with setOnStaleSubscriptionAlert for ultimate awesomeness
*/
heartbeatPeriod?: number;
/**
* Maximum number of insert/updates/deletes per message.
*/
batchSize?: number;
/**
* Maximum period of milliseconds that the server will wait before sending a batch of updates.
*/
batchPeriod?: number;
// /**
// * Enables oof features, please used only when absolutely needed due to performance execution cost
// */
// oof: oofType;
excludeFromRecovery?: boolean;
/**
* Used when aggregation command
*/
pipeline?: Record<string, any>[],
}
//
// export enum oofType {
// /**
// * Default when none are provided
// * @type {oofType.none}
// */
// none = "none",
// /**
// * Default when none are provided
// * when oof accrues, you will only get _id field
// * @type {oofType.id}
// */
// id = "id",
// /**
// * Strongly discouraged due to it's performance impact
// * when oof accrues, you will get _id and the primary keys
// * @type {oofType.keys}
// */
// keys = "keys",
// }
export interface QuerySubscription {
subscriptionId: string;
unsubscribe: () => void;
}