Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
d565b3f42d | |||
a2aab715ed | |||
bf89354564 | |||
254ddda8a2 | |||
16c081020a |
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES5" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -23,7 +23,7 @@ Install using `npm install node-eventstore-client`
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
- Node.js >= 0.12
|
- Node.js >= 4.0
|
||||||
- Modules: [long](https://www.npmjs.org/package/long), [protobufjs](https://www.npmjs.org/package/protobufjs), [uuid](https://www.npmjs.org/package/uuid) (installed via `npm install`)
|
- Modules: [long](https://www.npmjs.org/package/long), [protobufjs](https://www.npmjs.org/package/protobufjs), [uuid](https://www.npmjs.org/package/uuid) (installed via `npm install`)
|
||||||
|
|
||||||
### API Documentation
|
### API Documentation
|
||||||
@ -112,7 +112,7 @@ To generate a test event, open a separate console and run:
|
|||||||
|
|
||||||
To run the tests it is recommended that you use an in-memory instance of the eventstore so you don't pollute your dev instance.
|
To run the tests it is recommended that you use an in-memory instance of the eventstore so you don't pollute your dev instance.
|
||||||
|
|
||||||
EventStore.ClusterNode.exe --memdb
|
EventStore.ClusterNode.exe --run-projections=all --memdb
|
||||||
|
|
||||||
To execute the tests suites simply run
|
To execute the tests suites simply run
|
||||||
|
|
||||||
|
97
index.d.ts
vendored
97
index.d.ts
vendored
@ -16,7 +16,7 @@ export class UserCredentials {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PersistentSubscriptionSettings {
|
export class PersistentSubscriptionSettings {
|
||||||
constructor(resolveLinkTos: boolean, startFrom: Long|number, extraStatistics: boolean, messageTimeout: number,
|
constructor(resolveLinkTos: boolean, startFrom: number, extraStatistics: boolean, messageTimeout: number,
|
||||||
maxRetryCount: number, liveBufferSize: number, readBatchSize: number, historyBufferSize: number,
|
maxRetryCount: number, liveBufferSize: number, readBatchSize: number, historyBufferSize: number,
|
||||||
checkPointAfter: number, minCheckPointCount: number, maxCheckPointCount: number,
|
checkPointAfter: number, minCheckPointCount: number, maxCheckPointCount: number,
|
||||||
maxSubscriberCount: number, namedConsumerStrategy: string)
|
maxSubscriberCount: number, namedConsumerStrategy: string)
|
||||||
@ -26,7 +26,7 @@ export class PersistentSubscriptionSettings {
|
|||||||
export namespace SystemConsumerStrategies {
|
export namespace SystemConsumerStrategies {
|
||||||
const DispatchToSingle: string;
|
const DispatchToSingle: string;
|
||||||
const RoundRobin: string;
|
const RoundRobin: string;
|
||||||
const Pinned: string
|
const Pinned: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GossipSeed {
|
export class GossipSeed {
|
||||||
@ -41,7 +41,7 @@ export class WrongExpectedVersionError {
|
|||||||
readonly action: string;
|
readonly action: string;
|
||||||
readonly message: string;
|
readonly message: string;
|
||||||
readonly stream?: string;
|
readonly stream?: string;
|
||||||
readonly expectedVersion?: Long;
|
readonly expectedVersion?: number;
|
||||||
readonly transactionId?: Long;
|
readonly transactionId?: Long;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ export interface Logger {
|
|||||||
error(fmt: string, ...args: any[]): void;
|
error(fmt: string, ...args: any[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NoOpLogger implements Logger {
|
export class NoopLogger implements Logger {
|
||||||
constructor()
|
constructor()
|
||||||
debug(fmt: string, ...args: any[]): void;
|
debug(fmt: string, ...args: any[]): void;
|
||||||
info(fmt: string, ...args: any[]): void;
|
info(fmt: string, ...args: any[]): void;
|
||||||
@ -98,16 +98,17 @@ export class FileLogger implements Logger {
|
|||||||
error(fmt: string, ...args: any[]): void;
|
error(fmt: string, ...args: any[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose results
|
//
|
||||||
|
|
||||||
export interface WriteResult {
|
export interface WriteResult {
|
||||||
readonly nextExpectedVersion: Long;
|
readonly nextExpectedVersion: number;
|
||||||
readonly logPosition: Position;
|
readonly logPosition: Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RecordedEvent {
|
export interface RecordedEvent {
|
||||||
readonly eventStreamId: string;
|
readonly eventStreamId: string;
|
||||||
readonly eventId: string;
|
readonly eventId: string;
|
||||||
readonly eventNumber: Long;
|
readonly eventNumber: number;
|
||||||
readonly eventType: string;
|
readonly eventType: string;
|
||||||
readonly createdEpoch: number;
|
readonly createdEpoch: number;
|
||||||
readonly data?: Buffer;
|
readonly data?: Buffer;
|
||||||
@ -122,17 +123,17 @@ export interface ResolvedEvent {
|
|||||||
readonly isResolved: boolean;
|
readonly isResolved: boolean;
|
||||||
readonly originalPosition?: Position;
|
readonly originalPosition?: Position;
|
||||||
readonly originalStreamId: string;
|
readonly originalStreamId: string;
|
||||||
readonly originalEventNumber: Long;
|
readonly originalEventNumber: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StreamEventsSlice {
|
export interface StreamEventsSlice {
|
||||||
readonly status: string; // TODO: enum
|
readonly status: string; // TODO: enum
|
||||||
readonly stream: string;
|
readonly stream: string;
|
||||||
readonly fromEventNumber: Long;
|
readonly fromEventNumber: number;
|
||||||
readonly readDirection: string; // TODO: enum
|
readonly readDirection: string; // TODO: enum
|
||||||
readonly events: ResolvedEvent[];
|
readonly events: ResolvedEvent[];
|
||||||
readonly nextEventNumber: Long;
|
readonly nextEventNumber: number;
|
||||||
readonly lastEventNumber: Long;
|
readonly lastEventNumber: number;
|
||||||
readonly isEndOfStream: boolean;
|
readonly isEndOfStream: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +159,7 @@ export interface EventStoreTransaction {
|
|||||||
export interface EventReadResult {
|
export interface EventReadResult {
|
||||||
readonly status: string;
|
readonly status: string;
|
||||||
readonly stream: string;
|
readonly stream: string;
|
||||||
readonly eventNumber: Long;
|
readonly eventNumber: number;
|
||||||
readonly event: ResolvedEvent | null;
|
readonly event: ResolvedEvent | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +167,7 @@ export interface EventStoreSubscription {
|
|||||||
readonly isSubscribedToAll: boolean;
|
readonly isSubscribedToAll: boolean;
|
||||||
readonly streamId: string;
|
readonly streamId: string;
|
||||||
readonly lastCommitPosition: Position;
|
readonly lastCommitPosition: Position;
|
||||||
readonly lastEventNumber: Long;
|
readonly lastEventNumber: number;
|
||||||
|
|
||||||
close(): void;
|
close(): void;
|
||||||
unsubscribe(): void;
|
unsubscribe(): void;
|
||||||
@ -193,7 +194,7 @@ export interface EventStorePersistentSubscription {
|
|||||||
export interface RawStreamMetadataResult {
|
export interface RawStreamMetadataResult {
|
||||||
readonly stream: string;
|
readonly stream: string;
|
||||||
readonly isStreamDeleted: boolean;
|
readonly isStreamDeleted: boolean;
|
||||||
readonly metastreamVersion: Long;
|
readonly metastreamVersion: number;
|
||||||
readonly streamMetadata: any;
|
readonly streamMetadata: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,19 +249,19 @@ export interface EventStoreNodeConnection {
|
|||||||
connect(): Promise<void>;
|
connect(): Promise<void>;
|
||||||
close(): void;
|
close(): void;
|
||||||
// write actions
|
// write actions
|
||||||
deleteStream(stream: string, expectedVersion: Long|number, hardDelete?: boolean, userCredentials?: UserCredentials): Promise<DeleteResult>;
|
deleteStream(stream: string, expectedVersion: number, hardDelete?: boolean, userCredentials?: UserCredentials): Promise<DeleteResult>;
|
||||||
appendToStream(stream: string, expectedVersion: Long|number, eventOrEvents: EventData | EventData[], userCredentials?: UserCredentials): Promise<WriteResult>;
|
appendToStream(stream: string, expectedVersion: number, eventOrEvents: EventData | EventData[], userCredentials?: UserCredentials): Promise<WriteResult>;
|
||||||
startTransaction(stream: string, expectedVersion: Long|number, userCredentials?: UserCredentials): Promise<EventStoreTransaction>;
|
startTransaction(stream: string, expectedVersion: number, userCredentials?: UserCredentials): Promise<EventStoreTransaction>;
|
||||||
continueTransaction(transactionId: number, userCredentials?: UserCredentials): EventStoreTransaction;
|
continueTransaction(transactionId: number, userCredentials?: UserCredentials): EventStoreTransaction;
|
||||||
// read actions
|
// read actions
|
||||||
readEvent(stream: string, eventNumber: Long|number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<EventReadResult>;
|
readEvent(stream: string, eventNumber: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<EventReadResult>;
|
||||||
readStreamEventsForward(stream: string, start: Long|number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
readStreamEventsForward(stream: string, start: number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
||||||
readStreamEventsBackward(stream: string, start: Long|number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
readStreamEventsBackward(stream: string, start: number, count: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<StreamEventsSlice>;
|
||||||
readAllEventsForward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
readAllEventsForward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
||||||
readAllEventsBackward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
readAllEventsBackward(position: Position, maxCount: number, resolveLinkTos?: boolean, userCredentials?: UserCredentials): Promise<AllEventsSlice>;
|
||||||
// subscription actions
|
// subscription actions
|
||||||
subscribeToStream(stream: string, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
subscribeToStream(stream: string, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
||||||
subscribeToStreamFrom(stream: string, lastCheckpoint: Long|number|null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
subscribeToStreamFrom(stream: string, lastCheckpoint: number | null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
||||||
subscribeToAll(resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
subscribeToAll(resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreSubscription>, userCredentials?: UserCredentials): Promise<EventStoreSubscription>;
|
||||||
subscribeToAllFrom(lastCheckpoint: Position | null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
subscribeToAllFrom(lastCheckpoint: Position | null, resolveLinkTos: boolean, eventAppeared: EventAppearedCallback<EventStoreCatchUpSubscription>, liveProcessingStarted?: LiveProcessingStartedCallback, subscriptionDropped?: SubscriptionDroppedCallback<EventStoreCatchUpSubscription>, userCredentials?: UserCredentials, readBatchSize?: number): EventStoreCatchUpSubscription;
|
||||||
// persistent subscriptions
|
// persistent subscriptions
|
||||||
@ -269,7 +270,7 @@ export interface EventStoreNodeConnection {
|
|||||||
deletePersistentSubscription(stream: string, groupName: string, userCredentials?: PersistentSubscriptionSettings): Promise<PersistentSubscriptionDeleteResult>
|
deletePersistentSubscription(stream: string, groupName: string, userCredentials?: PersistentSubscriptionSettings): Promise<PersistentSubscriptionDeleteResult>
|
||||||
connectToPersistentSubscription(stream: string, groupName: string, eventAppeared: EventAppearedCallback<EventStorePersistentSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStorePersistentSubscription>, userCredentials?: UserCredentials, bufferSize?: number, autoAck?: boolean): Promise<EventStorePersistentSubscription>;
|
connectToPersistentSubscription(stream: string, groupName: string, eventAppeared: EventAppearedCallback<EventStorePersistentSubscription>, subscriptionDropped?: SubscriptionDroppedCallback<EventStorePersistentSubscription>, userCredentials?: UserCredentials, bufferSize?: number, autoAck?: boolean): Promise<EventStorePersistentSubscription>;
|
||||||
// metadata actions
|
// metadata actions
|
||||||
setStreamMetadataRaw(stream: string, expectedMetastreamVersion: Long|number, metadata: any, userCredentials?: UserCredentials): Promise<WriteResult>;
|
setStreamMetadataRaw(stream: string, expectedMetastreamVersion: number, metadata: any, userCredentials?: UserCredentials): Promise<WriteResult>;
|
||||||
getStreamMetadataRaw(stream: string, userCredentials?: UserCredentials): Promise<RawStreamMetadataResult>;
|
getStreamMetadataRaw(stream: string, userCredentials?: UserCredentials): Promise<RawStreamMetadataResult>;
|
||||||
|
|
||||||
on(event: "connected" | "disconnected" | "reconnecting" | "closed" | "error" | "heartbeatInfo", listener: (arg: Error | string | TcpEndPoint | HeartbeatInfo) => void): this;
|
on(event: "connected" | "disconnected" | "reconnecting" | "closed" | "error" | "heartbeatInfo", listener: (arg: Error | string | TcpEndPoint | HeartbeatInfo) => void): this;
|
||||||
@ -313,3 +314,55 @@ export interface ConnectionSettings {
|
|||||||
export function createConnection(settings: ConnectionSettings, endPointOrGossipSeed: string | TcpEndPoint | GossipSeed[], connectionName?: string): EventStoreNodeConnection;
|
export function createConnection(settings: ConnectionSettings, endPointOrGossipSeed: string | TcpEndPoint | GossipSeed[], connectionName?: string): EventStoreNodeConnection;
|
||||||
export function createJsonEventData(eventId: string, event: any, metadata?: any, type?: string): EventData;
|
export function createJsonEventData(eventId: string, event: any, metadata?: any, type?: string): EventData;
|
||||||
export function createEventData(eventId: string, type: string, isJson: boolean, data: Buffer, metadata?: Buffer): EventData;
|
export function createEventData(eventId: string, type: string, isJson: boolean, data: Buffer, metadata?: Buffer): EventData;
|
||||||
|
|
||||||
|
// Projections
|
||||||
|
export interface ProjectionDetails {
|
||||||
|
coreProcessingTime: number,
|
||||||
|
version: number,
|
||||||
|
epoch: number,
|
||||||
|
effectiveName: string,
|
||||||
|
writesInProgress: number,
|
||||||
|
readsInProgress: number,
|
||||||
|
partitionsCached: number,
|
||||||
|
status: string,
|
||||||
|
stateReason: string,
|
||||||
|
name: string,
|
||||||
|
mode: string,
|
||||||
|
position: string,
|
||||||
|
progress: number,
|
||||||
|
lastCheckpoint: string,
|
||||||
|
eventsProcessedAfterRestart: number,
|
||||||
|
statusUrl: string,
|
||||||
|
stateUrl: string,
|
||||||
|
resultUrl: string,
|
||||||
|
queryUrl: string,
|
||||||
|
enableCommandUrl: string,
|
||||||
|
disableCommandUrl: string,
|
||||||
|
checkpointStatus: string,
|
||||||
|
bufferedEvents: number,
|
||||||
|
writePendingEventsBeforeCheckpoint: number,
|
||||||
|
writePendingEventsAfterCheckpoint: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ProjectionsManager {
|
||||||
|
constructor(log: Logger, httpEndPoint: string, operationTimeout: number);
|
||||||
|
enable(name: string, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
disable(name: string, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
abort(name: string, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
createOneTime(query: string, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
createTransient(name: string, query: string, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
createContinuous(name: string, query: string, trackEmittedStreams: boolean, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
listAll(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
|
||||||
|
listOneTime(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
|
||||||
|
listContinuous(userCredentials: UserCredentials): Promise<ProjectionDetails[]>;
|
||||||
|
getStatus(name: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
getState(name: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
getPartitionState(name: string, partitionId: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
getResult(name: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
getPartitionResult(name: string, partitionId: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
getStatistics(name: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
getQuery(name: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
getState(name: string, userCredentials: UserCredentials): Promise<string>;
|
||||||
|
updateQuery(name: string, query: string, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
deleteQuery(name: string, deleteEmittedStreams: boolean, userCredentials: UserCredentials): Promise<void>;
|
||||||
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "node-eventstore-client",
|
"name": "node-eventstore-client",
|
||||||
"version": "0.2.0",
|
"version": "0.1.11",
|
||||||
"description": "A port of the EventStore .Net ClientAPI to Node.js",
|
"description": "A port of the EventStore .Net ClientAPI to Node.js",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"types": "index.d.ts",
|
"types": "index.d.ts",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"engineStrict": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm lib/dist.js",
|
"clean": "rm lib/dist.js",
|
||||||
"build": "webpack",
|
"build": "webpack",
|
||||||
|
@ -51,10 +51,12 @@ module.exports.PersistentSubscriptionSettings = require('./persistentSubscriptio
|
|||||||
module.exports.SystemConsumerStrategies = require('./systemConsumerStrategies');
|
module.exports.SystemConsumerStrategies = require('./systemConsumerStrategies');
|
||||||
module.exports.GossipSeed = require('./gossipSeed');
|
module.exports.GossipSeed = require('./gossipSeed');
|
||||||
module.exports.EventStoreConnection = require('./eventStoreConnection');
|
module.exports.EventStoreConnection = require('./eventStoreConnection');
|
||||||
|
module.exports.ProjectionsManager = require('./projections/projectionsManager');
|
||||||
// Expose errors
|
// Expose errors
|
||||||
module.exports.WrongExpectedVersionError = require('./errors/wrongExpectedVersionError');
|
module.exports.WrongExpectedVersionError = require('./errors/wrongExpectedVersionError');
|
||||||
module.exports.StreamDeletedError = require('./errors/streamDeletedError');
|
module.exports.StreamDeletedError = require('./errors/streamDeletedError');
|
||||||
module.exports.AccessDeniedError = require('./errors/accessDeniedError');
|
module.exports.AccessDeniedError = require('./errors/accessDeniedError');
|
||||||
|
module.exports.ProjectionCommandFailedError = require('./errors/projectionCommandFailedError');
|
||||||
// Expose enums/constants
|
// Expose enums/constants
|
||||||
module.exports.expectedVersion = expectedVersion;
|
module.exports.expectedVersion = expectedVersion;
|
||||||
module.exports.positions = positions;
|
module.exports.positions = positions;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
var Long = require('long');
|
|
||||||
|
|
||||||
module.exports.notNullOrEmpty = function(value, name) {
|
module.exports.notNullOrEmpty = function(value, name) {
|
||||||
if (value === null)
|
if (value === null)
|
||||||
throw new TypeError(name + " should not be null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
@ -12,18 +10,9 @@ module.exports.notNull = function(value, name) {
|
|||||||
throw new TypeError(name + " should not be null.");
|
throw new TypeError(name + " should not be null.");
|
||||||
};
|
};
|
||||||
|
|
||||||
function isInteger(value, name) {
|
module.exports.isInteger = function(value, name) {
|
||||||
if (typeof value !== 'number' || value % 1 !== 0)
|
if (typeof value !== 'number' || value % 1 !== 0)
|
||||||
throw new TypeError(name + " should be an integer.");
|
throw new TypeError(name + " should be an integer.");
|
||||||
}
|
|
||||||
module.exports.isInteger = isInteger;
|
|
||||||
|
|
||||||
module.exports.isLongOrInteger = function(value, name) {
|
|
||||||
if (typeof value === 'number') {
|
|
||||||
return isInteger(value, name);
|
|
||||||
} else if (!Long.isLong(value)) {
|
|
||||||
throw new TypeError(name + " should be a Long|number.");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isArrayOf = function(expectedType, value, name) {
|
module.exports.isArrayOf = function(expectedType, value, name) {
|
||||||
|
@ -9,8 +9,6 @@ var SubscriptionsManager = require('./subscriptionsManager');
|
|||||||
var VolatileSubscriptionOperation = require('../clientOperations/volatileSubscriptionOperation');
|
var VolatileSubscriptionOperation = require('../clientOperations/volatileSubscriptionOperation');
|
||||||
var ConnectToPersistentSubscriptionOperation = require('../clientOperations/connectToPersistentSubscriptionOperation');
|
var ConnectToPersistentSubscriptionOperation = require('../clientOperations/connectToPersistentSubscriptionOperation');
|
||||||
var messages = require('./messages');
|
var messages = require('./messages');
|
||||||
var ClientMessage = require('../messages/clientMessage');
|
|
||||||
var createBufferSegment = require('../common/bufferSegment');
|
|
||||||
|
|
||||||
var TcpPackage = require('../systemData/tcpPackage');
|
var TcpPackage = require('../systemData/tcpPackage');
|
||||||
var TcpCommand = require('../systemData/tcpCommand');
|
var TcpCommand = require('../systemData/tcpCommand');
|
||||||
@ -30,14 +28,12 @@ const ConnectingPhase = {
|
|||||||
EndPointDiscovery: 'endpointDiscovery',
|
EndPointDiscovery: 'endpointDiscovery',
|
||||||
ConnectionEstablishing: 'connectionEstablishing',
|
ConnectionEstablishing: 'connectionEstablishing',
|
||||||
Authentication: 'authentication',
|
Authentication: 'authentication',
|
||||||
Identification: 'identification',
|
|
||||||
Connected: 'connected'
|
Connected: 'connected'
|
||||||
};
|
};
|
||||||
|
|
||||||
const TimerPeriod = 200;
|
const TimerPeriod = 200;
|
||||||
const TimerTickMessage = new messages.TimerTickMessage();
|
const TimerTickMessage = new messages.TimerTickMessage();
|
||||||
const EmptyGuid = '00000000-0000-0000-0000-000000000000';
|
const EmptyGuid = '00000000-0000-0000-0000-000000000000';
|
||||||
const ClientVersion = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@ -47,6 +43,7 @@ const ClientVersion = 1;
|
|||||||
* @property {Number} totalOperationCount
|
* @property {Number} totalOperationCount
|
||||||
*/
|
*/
|
||||||
function EventStoreConnectionLogicHandler(esConnection, settings) {
|
function EventStoreConnectionLogicHandler(esConnection, settings) {
|
||||||
|
EventEmitter.call(this);
|
||||||
this._esConnection = esConnection;
|
this._esConnection = esConnection;
|
||||||
this._settings = settings;
|
this._settings = settings;
|
||||||
this._queue = new SimpleQueuedHandler();
|
this._queue = new SimpleQueuedHandler();
|
||||||
@ -395,21 +392,10 @@ EventStoreConnectionLogicHandler.prototype._tcpConnectionEstablished = function(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this._goToIdentifiedState();
|
this._goToConnectedState();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EventStoreConnectionLogicHandler.prototype._goToIdentifiedState = function() {
|
|
||||||
this._connectingPhase = ConnectingPhase.Identification;
|
|
||||||
this._identityInfo = {
|
|
||||||
correlationId: uuid.v4(),
|
|
||||||
timeStamp: Date.now()
|
|
||||||
};
|
|
||||||
var dto = new ClientMessage.IdentifyClient({version: ClientVersion, connectionName: this._esConnection.connectionName});
|
|
||||||
var buf = dto.constructor.encode(dto).finish();
|
|
||||||
this._connection.enqueueSend(new TcpPackage(TcpCommand.IdentifyClient, TcpFlags.None, this._identityInfo.correlationId, null, null, createBufferSegment(buf)))
|
|
||||||
};
|
|
||||||
|
|
||||||
EventStoreConnectionLogicHandler.prototype._goToConnectedState = function() {
|
EventStoreConnectionLogicHandler.prototype._goToConnectedState = function() {
|
||||||
this._state = ConnectionState.Connected;
|
this._state = ConnectionState.Connected;
|
||||||
this._connectingPhase = ConnectingPhase.Connected;
|
this._connectingPhase = ConnectingPhase.Connected;
|
||||||
@ -513,16 +499,6 @@ EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connecti
|
|||||||
if (pkg.command === TcpCommand.NotAuthenticated)
|
if (pkg.command === TcpCommand.NotAuthenticated)
|
||||||
this.emit('authenticationFailed', "Not authenticated");
|
this.emit('authenticationFailed', "Not authenticated");
|
||||||
|
|
||||||
this._goToIdentifiedState();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkg.command === TcpCommand.ClientIdentified)
|
|
||||||
{
|
|
||||||
if (this._state === ConnectionState.Connecting
|
|
||||||
&& this._identityInfo.correlationId === pkg.correlationId)
|
|
||||||
{
|
|
||||||
this._goToConnectedState();
|
this._goToConnectedState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -642,12 +618,8 @@ EventStoreConnectionLogicHandler.prototype._timerTick = function() {
|
|||||||
else if (this._connectingPhase === ConnectingPhase.Authentication && (Date.now() - this._authInfo.timeStamp) >= this._settings.operationTimeout)
|
else if (this._connectingPhase === ConnectingPhase.Authentication && (Date.now() - this._authInfo.timeStamp) >= this._settings.operationTimeout)
|
||||||
{
|
{
|
||||||
this.emit('authenticationFailed', "Authentication timed out.");
|
this.emit('authenticationFailed', "Authentication timed out.");
|
||||||
if (this._clientVersion === 1) {
|
|
||||||
this._goToIdentifiedState();
|
|
||||||
} else {
|
|
||||||
this._goToConnectedState();
|
this._goToConnectedState();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (this._connectingPhase === ConnectingPhase.Authentication || this._connectingPhase === ConnectingPhase.Connected)
|
else if (this._connectingPhase === ConnectingPhase.Authentication || this._connectingPhase === ConnectingPhase.Connected)
|
||||||
this._manageHeartbeats();
|
this._manageHeartbeats();
|
||||||
break;
|
break;
|
||||||
|
10
src/errors/projectionCommandFailedError.js
Normal file
10
src/errors/projectionCommandFailedError.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const util = require('util');
|
||||||
|
|
||||||
|
function ProjectionCommandFailedError(httpStatusCode, message) {
|
||||||
|
Error.captureStackTrace(this, this.constructor);
|
||||||
|
this.httpStatusCode = httpStatusCode;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
util.inherits(ProjectionCommandFailedError, Error);
|
||||||
|
|
||||||
|
module.exports = ProjectionCommandFailedError;
|
@ -1,6 +1,5 @@
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var Long = require('long');
|
|
||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var ensure = require('./common/utils/ensure');
|
var ensure = require('./common/utils/ensure');
|
||||||
|
|
||||||
@ -38,6 +37,7 @@ const MaxReadSize = 4096;
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function EventStoreNodeConnection(settings, clusterSettings, endpointDiscoverer, connectionName) {
|
function EventStoreNodeConnection(settings, clusterSettings, endpointDiscoverer, connectionName) {
|
||||||
|
EventEmitter.call(this);
|
||||||
this._connectionName = connectionName || ['ES-', uuid.v4()].join('');
|
this._connectionName = connectionName || ['ES-', uuid.v4()].join('');
|
||||||
this._settings = settings;
|
this._settings = settings;
|
||||||
this._clusterSettings = clusterSettings;
|
this._clusterSettings = clusterSettings;
|
||||||
@ -101,16 +101,15 @@ EventStoreNodeConnection.prototype.close = function() {
|
|||||||
* Delete a stream (async)
|
* Delete a stream (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long|number} expectedVersion
|
* @param {number} expectedVersion
|
||||||
* @param {boolean} [hardDelete]
|
* @param {boolean} [hardDelete]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<DeleteResult>}
|
* @returns {Promise.<DeleteResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersion, hardDelete, userCredentials) {
|
EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersion, hardDelete, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isLongOrInteger(expectedVersion, "expectedVersion");
|
ensure.isInteger(expectedVersion, "expectedVersion");
|
||||||
expectedVersion = Long.fromValue(expectedVersion);
|
hardDelete = !!hardDelete;
|
||||||
hardDelete = Boolean(hardDelete);
|
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -130,15 +129,14 @@ EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersi
|
|||||||
* Append events to a stream (async)
|
* Append events to a stream (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream The name of the stream to which to append.
|
* @param {string} stream The name of the stream to which to append.
|
||||||
* @param {Long|number} expectedVersion The version at which we currently expect the stream to be in order that an optimistic concurrency check can be performed.
|
* @param {number} expectedVersion The version at which we currently expect the stream to be in order that an optimistic concurrency check can be performed.
|
||||||
* @param {EventData[]|EventData} events The event(s) to append.
|
* @param {EventData[]|EventData} events The event(s) to append.
|
||||||
* @param {UserCredentials} [userCredentials] User credentials
|
* @param {UserCredentials} [userCredentials] User credentials
|
||||||
* @returns {Promise.<WriteResult>}
|
* @returns {Promise.<WriteResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVersion, events, userCredentials) {
|
EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVersion, events, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isLongOrInteger(expectedVersion, "expectedVersion");
|
ensure.isInteger(expectedVersion, "expectedVersion");
|
||||||
expectedVersion = Long.fromValue(expectedVersion);
|
|
||||||
if (!Array.isArray(events))
|
if (!Array.isArray(events))
|
||||||
events = [events];
|
events = [events];
|
||||||
ensure.isArrayOf(EventData, events, "events");
|
ensure.isArrayOf(EventData, events, "events");
|
||||||
@ -160,14 +158,13 @@ EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVer
|
|||||||
* Start a transaction (async)
|
* Start a transaction (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long|number} expectedVersion
|
* @param {number} expectedVersion
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<EventStoreTransaction>}
|
* @returns {Promise.<EventStoreTransaction>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedVersion, userCredentials) {
|
EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedVersion, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isLongOrInteger(expectedVersion, "expectedVersion");
|
ensure.isInteger(expectedVersion, "expectedVersion");
|
||||||
expectedVersion = Long.fromValue(expectedVersion);
|
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -238,20 +235,21 @@ EventStoreNodeConnection.prototype.commitTransaction = function(transaction, use
|
|||||||
* Read a single event (async)
|
* Read a single event (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long|number} eventNumber
|
* @param {number} eventNumber
|
||||||
* @param {boolean} [resolveLinkTos]
|
* @param {boolean} [resolveLinkTos]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<EventReadResult>}
|
* @returns {Promise.<EventReadResult>}
|
||||||
*/
|
*/
|
||||||
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isLongOrInteger(eventNumber, "eventNumber");
|
ensure.isInteger(eventNumber, "eventNumber");
|
||||||
eventNumber = Long.fromValue(eventNumber);
|
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
||||||
resolveLinkTos = Boolean(resolveLinkTos);
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string.");
|
||||||
if (eventNumber.compare(-1) < 0) throw new Error("eventNumber out of range.");
|
if (typeof eventNumber !== 'number' || eventNumber % 1 !== 0) throw new TypeError("eventNumber must be an integer.");
|
||||||
|
if (eventNumber < -1) throw new Error("eventNumber out of range.");
|
||||||
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean.");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -270,7 +268,7 @@ EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, res
|
|||||||
* Reading a specific stream forwards (async)
|
* Reading a specific stream forwards (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long|number} start
|
* @param {number} start
|
||||||
* @param {number} count
|
* @param {number} count
|
||||||
* @param {boolean} [resolveLinkTos]
|
* @param {boolean} [resolveLinkTos]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
@ -280,13 +278,12 @@ EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
|||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isLongOrInteger(start, "start");
|
ensure.isInteger(start, "start");
|
||||||
start = Long.fromValue(start);
|
|
||||||
ensure.nonNegative(start, "start");
|
ensure.nonNegative(start, "start");
|
||||||
ensure.isInteger(count, "count");
|
ensure.isInteger(count, "count");
|
||||||
ensure.positive(count, "count");
|
ensure.positive(count, "count");
|
||||||
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = Boolean(resolveLinkTos);
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -305,7 +302,7 @@ EventStoreNodeConnection.prototype.readStreamEventsForward = function(
|
|||||||
* Reading a specific stream backwards (async)
|
* Reading a specific stream backwards (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long|number} start
|
* @param {number} start
|
||||||
* @param {number} count
|
* @param {number} count
|
||||||
* @param {boolean} [resolveLinkTos]
|
* @param {boolean} [resolveLinkTos]
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
@ -315,12 +312,11 @@ EventStoreNodeConnection.prototype.readStreamEventsBackward = function(
|
|||||||
stream, start, count, resolveLinkTos, userCredentials
|
stream, start, count, resolveLinkTos, userCredentials
|
||||||
) {
|
) {
|
||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
ensure.isLongOrInteger(start, "start");
|
ensure.isInteger(start, "start");
|
||||||
start = Long.fromValue(start);
|
|
||||||
ensure.isInteger(count, "count");
|
ensure.isInteger(count, "count");
|
||||||
ensure.positive(count, "count");
|
ensure.positive(count, "count");
|
||||||
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = Boolean(resolveLinkTos);
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -351,7 +347,7 @@ EventStoreNodeConnection.prototype.readAllEventsForward = function(
|
|||||||
ensure.isInteger(maxCount, "maxCount");
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
ensure.positive(maxCount, "maxCount");
|
ensure.positive(maxCount, "maxCount");
|
||||||
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = Boolean(resolveLinkTos);
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -382,7 +378,7 @@ EventStoreNodeConnection.prototype.readAllEventsBackward = function(
|
|||||||
ensure.isInteger(maxCount, "maxCount");
|
ensure.isInteger(maxCount, "maxCount");
|
||||||
ensure.positive(maxCount, "maxCount");
|
ensure.positive(maxCount, "maxCount");
|
||||||
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize));
|
||||||
resolveLinkTos = Boolean(resolveLinkTos);
|
resolveLinkTos = !!resolveLinkTos;
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -432,7 +428,7 @@ EventStoreNodeConnection.prototype.subscribeToStream = function(
|
|||||||
* Subscribe to a stream from position
|
* Subscribe to a stream from position
|
||||||
* @public
|
* @public
|
||||||
* @param {!string} stream
|
* @param {!string} stream
|
||||||
* @param {?number|Position} lastCheckpoint
|
* @param {?number} lastCheckpoint
|
||||||
* @param {!boolean} resolveLinkTos
|
* @param {!boolean} resolveLinkTos
|
||||||
* @param {!function} eventAppeared
|
* @param {!function} eventAppeared
|
||||||
* @param {function} [liveProcessingStarted]
|
* @param {function} [liveProcessingStarted]
|
||||||
@ -446,10 +442,7 @@ EventStoreNodeConnection.prototype.subscribeToStreamFrom = function(
|
|||||||
userCredentials, readBatchSize
|
userCredentials, readBatchSize
|
||||||
) {
|
) {
|
||||||
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be a non-empty string.");
|
if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be a non-empty string.");
|
||||||
if (lastCheckpoint !== null) {
|
if (lastCheckpoint !== null && typeof lastCheckpoint !== 'number') throw new TypeError("lastCheckpoint must be a number or null.");
|
||||||
ensure.isLongOrInteger(lastCheckpoint);
|
|
||||||
lastCheckpoint = Long.fromValue(lastCheckpoint);
|
|
||||||
}
|
|
||||||
if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function.");
|
if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function.");
|
||||||
|
|
||||||
var catchUpSubscription =
|
var catchUpSubscription =
|
||||||
@ -539,7 +532,7 @@ EventStoreNodeConnection.prototype.connectToPersistentSubscription = function(
|
|||||||
subscriptionDropped = subscriptionDropped || null;
|
subscriptionDropped = subscriptionDropped || null;
|
||||||
userCredentials = userCredentials || null;
|
userCredentials = userCredentials || null;
|
||||||
bufferSize = bufferSize === undefined ? 10 : bufferSize;
|
bufferSize = bufferSize === undefined ? 10 : bufferSize;
|
||||||
autoAck = autoAck === undefined ? true : Boolean(autoAck);
|
autoAck = autoAck === undefined ? true : !!autoAck;
|
||||||
|
|
||||||
var subscription = new EventStorePersistentSubscription(
|
var subscription = new EventStorePersistentSubscription(
|
||||||
groupName, stream, eventAppeared, subscriptionDropped, userCredentials, this._settings.log,
|
groupName, stream, eventAppeared, subscriptionDropped, userCredentials, this._settings.log,
|
||||||
@ -631,7 +624,7 @@ EventStoreNodeConnection.prototype.setStreamMetadata = function() {
|
|||||||
* Set stream metadata with raw object (async)
|
* Set stream metadata with raw object (async)
|
||||||
* @public
|
* @public
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long|number} expectedMetastreamVersion
|
* @param {number} expectedMetastreamVersion
|
||||||
* @param {object} metadata
|
* @param {object} metadata
|
||||||
* @param {UserCredentials} [userCredentials]
|
* @param {UserCredentials} [userCredentials]
|
||||||
* @returns {Promise.<WriteResult>}
|
* @returns {Promise.<WriteResult>}
|
||||||
@ -642,8 +635,6 @@ EventStoreNodeConnection.prototype.setStreamMetadataRaw = function(
|
|||||||
ensure.notNullOrEmpty(stream, "stream");
|
ensure.notNullOrEmpty(stream, "stream");
|
||||||
if (systemStreams.isMetastream(stream))
|
if (systemStreams.isMetastream(stream))
|
||||||
throw new Error(util.format("Setting metadata for metastream '%s' is not supported.", stream));
|
throw new Error(util.format("Setting metadata for metastream '%s' is not supported.", stream));
|
||||||
ensure.isLongOrInteger(expectedMetastreamVersion, "expectedMetastreamVersion");
|
|
||||||
expectedMetastreamVersion = Long.fromValue(expectedMetastreamVersion);
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
function cb(err, result) {
|
function cb(err, result) {
|
||||||
@ -686,12 +677,12 @@ EventStoreNodeConnection.prototype.getStreamMetadataRaw = function(stream, userC
|
|||||||
var evnt = res.event.originalEvent;
|
var evnt = res.event.originalEvent;
|
||||||
var version = evnt ? evnt.eventNumber : -1;
|
var version = evnt ? evnt.eventNumber : -1;
|
||||||
var data = evnt ? JSON.parse(evnt.data.toString()) : null;
|
var data = evnt ? JSON.parse(evnt.data.toString()) : null;
|
||||||
return new results.RawStreamMetadataResult(stream, false, Long.fromValue(version), data);
|
return new results.RawStreamMetadataResult(stream, false, version, data);
|
||||||
case results.EventReadStatus.NotFound:
|
case results.EventReadStatus.NotFound:
|
||||||
case results.EventReadStatus.NoStream:
|
case results.EventReadStatus.NoStream:
|
||||||
return new results.RawStreamMetadataResult(stream, false, Long.fromValue(-1), null);
|
return new results.RawStreamMetadataResult(stream, false, -1, null);
|
||||||
case results.EventReadStatus.StreamDeleted:
|
case results.EventReadStatus.StreamDeleted:
|
||||||
return new results.RawStreamMetadataResult(stream, true, Long.fromValue(0x7fffffff), null);
|
return new results.RawStreamMetadataResult(stream, true, 0x7fffffff, null);
|
||||||
default:
|
default:
|
||||||
throw new Error(util.format("Unexpected ReadEventResult: %s.", res.status));
|
throw new Error(util.format("Unexpected ReadEventResult: %s.", res.status));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
var EventStoreCatchUpSubscription = require('./eventStoreCatchUpSubscription');
|
var EventStoreCatchUpSubscription = require('./eventStoreCatchUpSubscription');
|
||||||
var SliceReadStatus = require('./sliceReadStatus');
|
var SliceReadStatus = require('./sliceReadStatus');
|
||||||
@ -15,8 +14,8 @@ function EventStoreStreamCatchUpSubscription(
|
|||||||
|
|
||||||
//Ensure.NotNullOrEmpty(streamId, "streamId");
|
//Ensure.NotNullOrEmpty(streamId, "streamId");
|
||||||
|
|
||||||
this._lastProcessedEventNumber = fromEventNumberExclusive === null ? Long.fromNumber(-1) : fromEventNumberExclusive;
|
this._lastProcessedEventNumber = fromEventNumberExclusive === null ? -1 : fromEventNumberExclusive;
|
||||||
this._nextReadEventNumber = fromEventNumberExclusive === null ? Long.fromNumber(0) : fromEventNumberExclusive.add(1);
|
this._nextReadEventNumber = fromEventNumberExclusive === null ? 0 : fromEventNumberExclusive + 1;
|
||||||
}
|
}
|
||||||
util.inherits(EventStoreStreamCatchUpSubscription, EventStoreCatchUpSubscription);
|
util.inherits(EventStoreStreamCatchUpSubscription, EventStoreCatchUpSubscription);
|
||||||
|
|
||||||
@ -48,14 +47,14 @@ EventStoreStreamCatchUpSubscription.prototype._readEventsTill = function(
|
|||||||
return processEvents(slice.events, 0)
|
return processEvents(slice.events, 0)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
self._nextReadEventNumber = slice.nextEventNumber;
|
self._nextReadEventNumber = slice.nextEventNumber;
|
||||||
var done = Promise.resolve(lastEventNumber === null ? slice.isEndOfStream : slice.nextEventNumber.compare(lastEventNumber) > 0);
|
var done = Promise.resolve(lastEventNumber === null ? slice.isEndOfStream : slice.nextEventNumber > lastEventNumber);
|
||||||
if (!done && slice.isEndOfStream)
|
if (!done && slice.isEndOfStream)
|
||||||
return delay(100, false);
|
return delay(100, false);
|
||||||
return done;
|
return done;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case SliceReadStatus.StreamNotFound:
|
case SliceReadStatus.StreamNotFound:
|
||||||
if (lastEventNumber && lastEventNumber.compare(-1) !== 0)
|
if (lastEventNumber && lastEventNumber !== -1)
|
||||||
throw new Error(util.format("Impossible: stream %s disappeared in the middle of catching up subscription.", self.streamId));
|
throw new Error(util.format("Impossible: stream %s disappeared in the middle of catching up subscription.", self.streamId));
|
||||||
return true;
|
return true;
|
||||||
case SliceReadStatus.StreamDeleted:
|
case SliceReadStatus.StreamDeleted:
|
||||||
@ -81,7 +80,7 @@ EventStoreStreamCatchUpSubscription.prototype._readEventsTill = function(
|
|||||||
EventStoreStreamCatchUpSubscription.prototype._tryProcess = function(e) {
|
EventStoreStreamCatchUpSubscription.prototype._tryProcess = function(e) {
|
||||||
var processed = false;
|
var processed = false;
|
||||||
var promise;
|
var promise;
|
||||||
if (e.originalEventNumber.compare(this._lastProcessedEventNumber) > 0) {
|
if (e.originalEventNumber > this._lastProcessedEventNumber) {
|
||||||
promise = this._eventAppeared(this, e);
|
promise = this._eventAppeared(this, e);
|
||||||
this._lastProcessedEventNumber = e.originalEventNumber;
|
this._lastProcessedEventNumber = e.originalEventNumber;
|
||||||
processed = true;
|
processed = true;
|
||||||
@ -89,7 +88,7 @@ EventStoreStreamCatchUpSubscription.prototype._tryProcess = function(e) {
|
|||||||
if (this._verbose)
|
if (this._verbose)
|
||||||
this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %d).",
|
this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %d).",
|
||||||
this.isSubscribedToAll ? '<all>' : this.streamId, processed ? "processed" : "skipping",
|
this.isSubscribedToAll ? '<all>' : this.streamId, processed ? "processed" : "skipping",
|
||||||
e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalEventNumber);
|
e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalEventNumber)
|
||||||
return (promise && promise.then) ? promise : Promise.resolve();
|
return (promise && promise.then) ? promise : Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ message NewEvent {
|
|||||||
|
|
||||||
message EventRecord {
|
message EventRecord {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int64 event_number = 2;
|
required int32 event_number = 2;
|
||||||
required bytes event_id = 3;
|
required bytes event_id = 3;
|
||||||
required string event_type = 4;
|
required string event_type = 4;
|
||||||
required int32 data_content_type = 5;
|
required int32 data_content_type = 5;
|
||||||
@ -48,7 +48,7 @@ message ResolvedEvent {
|
|||||||
|
|
||||||
message WriteEvents {
|
message WriteEvents {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int64 expected_version = 2;
|
required int32 expected_version = 2;
|
||||||
repeated NewEvent events = 3;
|
repeated NewEvent events = 3;
|
||||||
required bool require_master = 4;
|
required bool require_master = 4;
|
||||||
}
|
}
|
||||||
@ -56,16 +56,15 @@ message WriteEvents {
|
|||||||
message WriteEventsCompleted {
|
message WriteEventsCompleted {
|
||||||
required OperationResult result = 1;
|
required OperationResult result = 1;
|
||||||
optional string message = 2;
|
optional string message = 2;
|
||||||
required int64 first_event_number = 3;
|
required int32 first_event_number = 3;
|
||||||
required int64 last_event_number = 4;
|
required int32 last_event_number = 4;
|
||||||
optional int64 prepare_position = 5;
|
optional int64 prepare_position = 5;
|
||||||
optional int64 commit_position = 6;
|
optional int64 commit_position = 6;
|
||||||
optional int64 current_version = 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeleteStream {
|
message DeleteStream {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int64 expected_version = 2;
|
required int32 expected_version = 2;
|
||||||
required bool require_master = 3;
|
required bool require_master = 3;
|
||||||
optional bool hard_delete = 4;
|
optional bool hard_delete = 4;
|
||||||
}
|
}
|
||||||
@ -79,7 +78,7 @@ message DeleteStreamCompleted {
|
|||||||
|
|
||||||
message TransactionStart {
|
message TransactionStart {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int64 expected_version = 2;
|
required int32 expected_version = 2;
|
||||||
required bool require_master = 3;
|
required bool require_master = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,15 +109,15 @@ message TransactionCommitCompleted {
|
|||||||
required int64 transaction_id = 1;
|
required int64 transaction_id = 1;
|
||||||
required OperationResult result = 2;
|
required OperationResult result = 2;
|
||||||
optional string message = 3;
|
optional string message = 3;
|
||||||
required int64 first_event_number = 4;
|
required int32 first_event_number = 4;
|
||||||
required int64 last_event_number = 5;
|
required int32 last_event_number = 5;
|
||||||
optional int64 prepare_position = 6;
|
optional int64 prepare_position = 6;
|
||||||
optional int64 commit_position = 7;
|
optional int64 commit_position = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ReadEvent {
|
message ReadEvent {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int64 event_number = 2;
|
required int32 event_number = 2;
|
||||||
required bool resolve_link_tos = 3;
|
required bool resolve_link_tos = 3;
|
||||||
required bool require_master = 4;
|
required bool require_master = 4;
|
||||||
}
|
}
|
||||||
@ -142,7 +141,7 @@ message ReadEventCompleted {
|
|||||||
|
|
||||||
message ReadStreamEvents {
|
message ReadStreamEvents {
|
||||||
required string event_stream_id = 1;
|
required string event_stream_id = 1;
|
||||||
required int64 from_event_number = 2;
|
required int32 from_event_number = 2;
|
||||||
required int32 max_count = 3;
|
required int32 max_count = 3;
|
||||||
required bool resolve_link_tos = 4;
|
required bool resolve_link_tos = 4;
|
||||||
required bool require_master = 5;
|
required bool require_master = 5;
|
||||||
@ -161,8 +160,8 @@ message ReadStreamEventsCompleted {
|
|||||||
|
|
||||||
repeated ResolvedIndexedEvent events = 1;
|
repeated ResolvedIndexedEvent events = 1;
|
||||||
required ReadStreamResult result = 2;
|
required ReadStreamResult result = 2;
|
||||||
required int64 next_event_number = 3;
|
required int32 next_event_number = 3;
|
||||||
required int64 last_event_number = 4;
|
required int32 last_event_number = 4;
|
||||||
required bool is_end_of_stream = 5;
|
required bool is_end_of_stream = 5;
|
||||||
required int64 last_commit_position = 6;
|
required int64 last_commit_position = 6;
|
||||||
|
|
||||||
@ -200,7 +199,7 @@ message CreatePersistentSubscription {
|
|||||||
required string subscription_group_name = 1;
|
required string subscription_group_name = 1;
|
||||||
required string event_stream_id = 2;
|
required string event_stream_id = 2;
|
||||||
required bool resolve_link_tos = 3;
|
required bool resolve_link_tos = 3;
|
||||||
required int64 start_from = 4;
|
required int32 start_from = 4;
|
||||||
required int32 message_timeout_milliseconds = 5;
|
required int32 message_timeout_milliseconds = 5;
|
||||||
required bool record_statistics = 6;
|
required bool record_statistics = 6;
|
||||||
required int32 live_buffer_size = 7;
|
required int32 live_buffer_size = 7;
|
||||||
@ -224,7 +223,7 @@ message UpdatePersistentSubscription {
|
|||||||
required string subscription_group_name = 1;
|
required string subscription_group_name = 1;
|
||||||
required string event_stream_id = 2;
|
required string event_stream_id = 2;
|
||||||
required bool resolve_link_tos = 3;
|
required bool resolve_link_tos = 3;
|
||||||
required int64 start_from = 4;
|
required int32 start_from = 4;
|
||||||
required int32 message_timeout_milliseconds = 5;
|
required int32 message_timeout_milliseconds = 5;
|
||||||
required bool record_statistics = 6;
|
required bool record_statistics = 6;
|
||||||
required int32 live_buffer_size = 7;
|
required int32 live_buffer_size = 7;
|
||||||
@ -302,7 +301,7 @@ message PersistentSubscriptionNakEvents {
|
|||||||
message PersistentSubscriptionConfirmation {
|
message PersistentSubscriptionConfirmation {
|
||||||
required int64 last_commit_position = 1;
|
required int64 last_commit_position = 1;
|
||||||
required string subscription_id = 2;
|
required string subscription_id = 2;
|
||||||
optional int64 last_event_number = 3;
|
optional int32 last_event_number = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PersistentSubscriptionStreamEventAppeared {
|
message PersistentSubscriptionStreamEventAppeared {
|
||||||
@ -316,7 +315,7 @@ message SubscribeToStream {
|
|||||||
|
|
||||||
message SubscriptionConfirmation {
|
message SubscriptionConfirmation {
|
||||||
required int64 last_commit_position = 1;
|
required int64 last_commit_position = 1;
|
||||||
optional int64 last_event_number = 2;
|
optional int32 last_event_number = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StreamEventAppeared {
|
message StreamEventAppeared {
|
||||||
@ -376,11 +375,3 @@ message ScavengeDatabaseCompleted {
|
|||||||
required int32 total_time_ms = 3;
|
required int32 total_time_ms = 3;
|
||||||
required int64 total_space_saved = 4;
|
required int64 total_space_saved = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IdentifyClient {
|
|
||||||
required int32 version = 1;
|
|
||||||
optional string connection_name = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ClientIdentified {
|
|
||||||
}
|
|
@ -1,6 +1,4 @@
|
|||||||
var SystemConsumerStrategies = require('./systemConsumerStrategies');
|
var SystemConsumerStrategies = require('./systemConsumerStrategies');
|
||||||
var ensure = require('./common/utils/ensure');
|
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
function PersistentSubscriptionSettings(
|
function PersistentSubscriptionSettings(
|
||||||
resolveLinkTos, startFrom, extraStatistics, messageTimeout,
|
resolveLinkTos, startFrom, extraStatistics, messageTimeout,
|
||||||
@ -8,9 +6,6 @@ function PersistentSubscriptionSettings(
|
|||||||
checkPointAfter, minCheckPointCount, maxCheckPointCount,
|
checkPointAfter, minCheckPointCount, maxCheckPointCount,
|
||||||
maxSubscriberCount, namedConsumerStrategy
|
maxSubscriberCount, namedConsumerStrategy
|
||||||
) {
|
) {
|
||||||
ensure.isLongOrInteger(startFrom);
|
|
||||||
startFrom = Long.fromValue(startFrom);
|
|
||||||
|
|
||||||
this.resolveLinkTos = resolveLinkTos;
|
this.resolveLinkTos = resolveLinkTos;
|
||||||
this.startFrom = startFrom;
|
this.startFrom = startFrom;
|
||||||
this.extraStatistics = extraStatistics;
|
this.extraStatistics = extraStatistics;
|
||||||
|
56
src/projections/projectionDetails.js
Normal file
56
src/projections/projectionDetails.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
function ProjectionDetails(
|
||||||
|
coreProcessingTime,
|
||||||
|
version,
|
||||||
|
epoch,
|
||||||
|
effectiveName,
|
||||||
|
writesInProgress,
|
||||||
|
readsInProgress,
|
||||||
|
partitionsCached,
|
||||||
|
status,
|
||||||
|
stateReason,
|
||||||
|
name,
|
||||||
|
mode,
|
||||||
|
position,
|
||||||
|
progress,
|
||||||
|
lastCheckpoint,
|
||||||
|
eventsProcessedAfterRestart,
|
||||||
|
statusUrl,
|
||||||
|
stateUrl,
|
||||||
|
resultUrl,
|
||||||
|
queryUrl,
|
||||||
|
enableCommandUrl,
|
||||||
|
disableCommandUrl,
|
||||||
|
checkpointStatus,
|
||||||
|
bufferedEvents,
|
||||||
|
writePendingEventsBeforeCheckpoint,
|
||||||
|
writePendingEventsAfterCheckpoint
|
||||||
|
) {
|
||||||
|
this.coreProcessingTime = coreProcessingTime;
|
||||||
|
this.version = version;
|
||||||
|
this.epoch = epoch;
|
||||||
|
this.effectiveName = effectiveName;
|
||||||
|
this.writesInProgress = writesInProgress;
|
||||||
|
this.readsInProgress = readsInProgress;
|
||||||
|
this.partitionsCached = partitionsCached;
|
||||||
|
this.status = status;
|
||||||
|
this.stateReason = stateReason;
|
||||||
|
this.name = name;
|
||||||
|
this.mode = mode;
|
||||||
|
this.position = position;
|
||||||
|
this.progress = progress;
|
||||||
|
this.lastCheckpoint = lastCheckpoint;
|
||||||
|
this.eventsProcessedAfterRestart = eventsProcessedAfterRestart;
|
||||||
|
this.statusUrl = statusUrl;
|
||||||
|
this.stateUrl = stateUrl;
|
||||||
|
this.resultUrl = resultUrl;
|
||||||
|
this.queryUrl = queryUrl;
|
||||||
|
this.enableCommandUrl = enableCommandUrl;
|
||||||
|
this.disableCommandUrl = disableCommandUrl;
|
||||||
|
this.checkpointStatus = checkpointStatus;
|
||||||
|
this.bufferedEvents = bufferedEvents;
|
||||||
|
this.writePendingEventsBeforeCheckpoint = writePendingEventsBeforeCheckpoint;
|
||||||
|
this.writePendingEventsAfterCheckpoint = writePendingEventsAfterCheckpoint;
|
||||||
|
Object.freeze(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ProjectionDetails;
|
170
src/projections/projectionsClient.js
Normal file
170
src/projections/projectionsClient.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
const http = require('http');
|
||||||
|
const url = require('url');
|
||||||
|
const util = require('util');
|
||||||
|
const ProjectionCommandFailedError = require('../errors/projectionCommandFailedError');
|
||||||
|
|
||||||
|
const HTTP_OK = 200;
|
||||||
|
const HTTP_CREATED = 201;
|
||||||
|
|
||||||
|
function safeParseJson(json) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(json);
|
||||||
|
} catch(e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProjectionsClient(log, operationTimeout) {
|
||||||
|
this._log = log;
|
||||||
|
this._operationTimeout = operationTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.enable = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendPost(httpEndPoint + '/projection/' + name + '/command/enable', '', userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.disable = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendPost(httpEndPoint + '/projection/' + name + '/command/disable', '', userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.abort = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendPost(httpEndPoint + '/projection/' + name + '/command/abort', '', userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.createOneTime = function(httpEndPoint, query, userCredentials) {
|
||||||
|
return this.sendPost(httpEndPoint + '/projections/onetime?type=JS', query, userCredentials, HTTP_CREATED);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.createTransient = function(httpEndPoint, name, query, userCredentials) {
|
||||||
|
return this.sendPost(httpEndPoint + '/projections/transient?name=' + name + '&type=JS', query, userCredentials, HTTP_CREATED);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.createContinuous = function(httpEndPoint, name, query, trackEmittedStreams, userCredentials) {
|
||||||
|
return this.sendPost(httpEndPoint + '/projections/continuous?name=' + name + '&type=JS&emit=1&trackEmittedStreams=' + trackEmittedStreams, query, userCredentials, HTTP_CREATED);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.listAll = function(httpEndPoint, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projections/any', userCredentials, HTTP_OK)
|
||||||
|
.then(function (json) {
|
||||||
|
var r = safeParseJson(json);
|
||||||
|
if (r && r.projections) return r.projections;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.listOneTime = function(httpEndPoint, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projections/onetime', userCredentials, HTTP_OK)
|
||||||
|
.then(function (json) {
|
||||||
|
var r = safeParseJson(json);
|
||||||
|
if (r && r.projections) return r.projections;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.listContinuous = function(httpEndPoint, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projections/continuous', userCredentials, HTTP_OK)
|
||||||
|
.then(function (json) {
|
||||||
|
var r = safeParseJson(json);
|
||||||
|
if (r && r.projections) return r.projections;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.getStatus = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projection/' + name, userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.getState = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projection/' + name + '/state', userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.getPartitionState = function(httpEndPoint, name, partitionId, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projection/' + name + '/state?partition=' + partitionId, userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.getResult = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projection/' + name + '/result', userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.getPartitionResult = function(httpEndPoint, name, partitionId, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projection/' + name + '/result?partition=' + partitionId, userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.getStatistics = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projection/' + name + '/statistics', userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.getQuery = function(httpEndPoint, name, userCredentials) {
|
||||||
|
return this.sendGet(httpEndPoint + '/projection/' + name + '/query', userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.updateQuery = function(httpEndPoint, name, query, userCredentials) {
|
||||||
|
return this.sendPut(httpEndPoint + '/projection/' + name + '/query?type=JS', query, userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.delete = function(httpEndPoint, name, deleteEmittedStreams, userCredentials) {
|
||||||
|
return this.sendDelete(httpEndPoint + '/projection/' + name + '?deleteEmittedStreams=' + deleteEmittedStreams, userCredentials, HTTP_OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.request = function(method, _url, data, userCredentials, expectedCode) {
|
||||||
|
const options = url.parse(_url);
|
||||||
|
options.method = method;
|
||||||
|
if (userCredentials) {
|
||||||
|
options.auth = [userCredentials.username, userCredentials.password].join(':');
|
||||||
|
}
|
||||||
|
var self = this;
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
const timeout = setTimeout(function () {
|
||||||
|
reject(new Error(util.format('Request timed out for %s on %s', method, _url)))
|
||||||
|
}, self._operationTimeout);
|
||||||
|
const req = http.request(options, function (res) {
|
||||||
|
const hasExpectedCode = res.statusCode === expectedCode;
|
||||||
|
var result = '';
|
||||||
|
res.setEncoding('utf8');
|
||||||
|
res.on('data', function (chunk) {
|
||||||
|
result += chunk;
|
||||||
|
});
|
||||||
|
res.on('end', function () {
|
||||||
|
if (hasExpectedCode) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
resolve(result);
|
||||||
|
} else {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
reject(new ProjectionCommandFailedError(
|
||||||
|
res.statusCode,
|
||||||
|
util.format('Server returned %d (%s) for %s on %s', res.statusCode, res.statusMessage, method, _url)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
req.on('error', reject);
|
||||||
|
if (data) {
|
||||||
|
req.setHeader('Content-Type', 'application/json');
|
||||||
|
req.write(data);
|
||||||
|
}
|
||||||
|
req.end();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function voidResult() {}
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.sendGet = function(_url, userCredentials, expectedCode) {
|
||||||
|
return this.request('GET', _url, null, userCredentials, expectedCode);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.sendPost = function(_url, data, userCredentials, expectedCode) {
|
||||||
|
return this.request('POST', _url, data, userCredentials, expectedCode)
|
||||||
|
.then(voidResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.sendPut = function(_url, data, userCredentials, expectedCode) {
|
||||||
|
return this.request('PUT', _url, data, userCredentials, expectedCode)
|
||||||
|
.then(voidResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProjectionsClient.prototype.sendDelete = function(_url, data, userCredentials, expectedCode) {
|
||||||
|
return this.request('DELETE', _url, data, userCredentials, expectedCode)
|
||||||
|
.then(voidResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ProjectionsClient;
|
202
src/projections/projectionsManager.js
Normal file
202
src/projections/projectionsManager.js
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
const ensure = require('../common/utils/ensure');
|
||||||
|
const ProjectionsClient = require('./projectionsClient');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of ProjectionsManager.
|
||||||
|
* @param {Logger} log Instance of Logger to use for logging.
|
||||||
|
* @param {string} httpEndPoint HTTP endpoint of an Event Store server.
|
||||||
|
* @param {number} operationTimeout Operation timeout in milliseconds.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function ProjectionsManager(log, httpEndPoint, operationTimeout) {
|
||||||
|
ensure.notNull(log, "log");
|
||||||
|
ensure.notNull(httpEndPoint, "httpEndPoint");
|
||||||
|
this._client = new ProjectionsClient(log, operationTimeout);
|
||||||
|
this._httpEndPoint = httpEndPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables a projection.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param userCredentials Credentials for a user with permission to enable a projection.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.enable = function(name, userCredentials) {
|
||||||
|
return this._client.enable(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aborts and disables a projection without writing a checkpoint.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param userCredentials Credentials for a user with permission to disable a projection.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.disable = function(name, userCredentials) {
|
||||||
|
return this._client.disable(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables a projection.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param userCredentials Credentials for a user with permission to disable a projection.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.abort = function(name, userCredentials) {
|
||||||
|
return this._client.abort(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a one-time query.
|
||||||
|
* @param query The JavaScript source code for the query.
|
||||||
|
* @param userCredentials Credentials for a user with permission to create a query.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.createOneTime = function(query, userCredentials) {
|
||||||
|
return this._client.createOneTime(this._httpEndPoint, query, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a one-time query.
|
||||||
|
* @param name A name for the query.
|
||||||
|
* @param query The JavaScript source code for the query.
|
||||||
|
* @param userCredentials Credentials for a user with permission to create a query.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.createTransient = function(name, query, userCredentials) {
|
||||||
|
return this._client.createTransient(this._httpEndPoint, query, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a one-time query.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param query The JavaScript source code for the query.
|
||||||
|
* @param trackEmittedStreams Whether the streams emitted by this projection should be tracked.
|
||||||
|
* @param userCredentials Credentials for a user with permission to create a query.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.createContinuous = function(name, query, trackEmittedStreams, userCredentials) {
|
||||||
|
return this._client.createContinuous(this._httpEndPoint, name, query, trackEmittedStreams, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists the status of all projections.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<ProjectionDetails[]>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.listAll = function(userCredentials) {
|
||||||
|
return this._client.listAll(this._httpEndPoint, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists the status of all one-time projections.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<ProjectionDetails[]>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.listOneTime = function(userCredentials) {
|
||||||
|
return this._client.listOneTime(this._httpEndPoint, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists the status of all continuous projections.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<ProjectionDetails[]>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.listContinuous = function(userCredentials) {
|
||||||
|
return this._client.listContinuous(this._httpEndPoint, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the status of a projection.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<string>} String of JSON containing projection status.
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.getStatus = function(name, userCredentials) {
|
||||||
|
return this._client.getStatus(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the state of a projection.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<string>} String of JSON containing projection state.
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.getState = function(name, userCredentials) {
|
||||||
|
return this._client.getState(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the state of a projection for a specified partition.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param partitionId The id of the partition.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<string>} String of JSON containing projection state.
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.getPartitionState = function(name, partitionId, userCredentials) {
|
||||||
|
return this._client.getPartitionState(this._httpEndPoint, name, partitionId, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the state of a projection.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<string>} String of JSON containing projection state.
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.getResult = function(name, userCredentials) {
|
||||||
|
return this._client.getResult(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the state of a projection for a specified partition.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param partitionId The id of the partition.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<string>} String of JSON containing projection state.
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.getPartitionResult = function(name, partitionId, userCredentials) {
|
||||||
|
return this._client.getPartitionResult(this._httpEndPoint, name, partitionId, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the statistics of a projection.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<string>} String of JSON containing projection statistics.
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.getStatistics = function(name, userCredentials) {
|
||||||
|
return this._client.getStatistics(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the status of a query.
|
||||||
|
* @param name The name of the query.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<string>} String of JSON containing query status.
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.getQuery = function(name, userCredentials) {
|
||||||
|
return this._client.getQuery(this._httpEndPoint, name, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the definition of a query.
|
||||||
|
* @param name The name of the query.
|
||||||
|
* @param query The JavaScript source code for the query.
|
||||||
|
* @param userCredentials Credentials for the operation.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.updateQuery = function(name, query, userCredentials) {
|
||||||
|
return this._client.updateQuery(this._httpEndPoint, name, query, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the definition of a query.
|
||||||
|
* @param name The name of the projection.
|
||||||
|
* @param deleteEmittedStreams Whether to delete the streams that were emitted by this projection.
|
||||||
|
* @param userCredentials Credentials for a user with permission to delete a projection.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
ProjectionsManager.prototype.delete = function(name, deleteEmittedStreams, userCredentials) {
|
||||||
|
return this._client.delete(this._httpEndPoint, name, deleteEmittedStreams, userCredentials);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ProjectionsManager;
|
@ -44,7 +44,7 @@ Object.freeze(EventReadStatus);
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} eventStreamId
|
* @property {string} eventStreamId
|
||||||
* @property {string} eventId
|
* @property {string} eventId
|
||||||
* @property {Long} eventNumber
|
* @property {number} eventNumber
|
||||||
* @property {string} eventType
|
* @property {string} eventType
|
||||||
* @property {number} createdEpoch
|
* @property {number} createdEpoch
|
||||||
* @property {?Buffer} data
|
* @property {?Buffer} data
|
||||||
@ -73,7 +73,7 @@ function RecordedEvent(ev) {
|
|||||||
* @property {boolean} isResolved
|
* @property {boolean} isResolved
|
||||||
* @property {?Position} originalPosition
|
* @property {?Position} originalPosition
|
||||||
* @property {string} originalStreamId
|
* @property {string} originalStreamId
|
||||||
* @property {Long} originalEventNumber
|
* @property {number} originalEventNumber
|
||||||
*/
|
*/
|
||||||
function ResolvedEvent(ev) {
|
function ResolvedEvent(ev) {
|
||||||
this.event = ev.event === null ? null : new RecordedEvent(ev.event);
|
this.event = ev.event === null ? null : new RecordedEvent(ev.event);
|
||||||
@ -90,12 +90,12 @@ function ResolvedEvent(ev) {
|
|||||||
*
|
*
|
||||||
* @param {string} status
|
* @param {string} status
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long} eventNumber
|
* @param {number} eventNumber
|
||||||
* @param {object} event
|
* @param {object} event
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} status
|
* @property {string} status
|
||||||
* @property {string} stream
|
* @property {string} stream
|
||||||
* @property {Long} eventNumber
|
* @property {number} eventNumber
|
||||||
* @property {ResolvedEvent} event
|
* @property {ResolvedEvent} event
|
||||||
*/
|
*/
|
||||||
function EventReadResult(status, stream, eventNumber, event) {
|
function EventReadResult(status, stream, eventNumber, event) {
|
||||||
@ -110,7 +110,7 @@ function EventReadResult(status, stream, eventNumber, event) {
|
|||||||
* @param {number} nextExpectedVersion
|
* @param {number} nextExpectedVersion
|
||||||
* @param {Position} logPosition
|
* @param {Position} logPosition
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {Long} nextExpectedVersion
|
* @property {number} nextExpectedVersion
|
||||||
* @property {Position} logPosition
|
* @property {Position} logPosition
|
||||||
*/
|
*/
|
||||||
function WriteResult(nextExpectedVersion, logPosition) {
|
function WriteResult(nextExpectedVersion, logPosition) {
|
||||||
@ -122,20 +122,20 @@ function WriteResult(nextExpectedVersion, logPosition) {
|
|||||||
/**
|
/**
|
||||||
* @param {string} status
|
* @param {string} status
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {Long} fromEventNumber
|
* @param {number} fromEventNumber
|
||||||
* @param {string} readDirection
|
* @param {string} readDirection
|
||||||
* @param {object[]} events
|
* @param {object[]} events
|
||||||
* @param {Long} nextEventNumber
|
* @param {number} nextEventNumber
|
||||||
* @param {Long} lastEventNumber
|
* @param {number} lastEventNumber
|
||||||
* @param {boolean} isEndOfStream
|
* @param {boolean} isEndOfStream
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} status
|
* @property {string} status
|
||||||
* @property {string} stream
|
* @property {string} stream
|
||||||
* @property {Long} fromEventNumber
|
* @property {number} fromEventNumber
|
||||||
* @property {string} readDirection
|
* @property {string} readDirection
|
||||||
* @property {ResolvedEvent[]} events
|
* @property {ResolvedEvent[]} events
|
||||||
* @property {Long} nextEventNumber
|
* @property {number} nextEventNumber
|
||||||
* @property {Long} lastEventNumber
|
* @property {number} lastEventNumber
|
||||||
* @property {boolean} isEndOfStream
|
* @property {boolean} isEndOfStream
|
||||||
*/
|
*/
|
||||||
function StreamEventsSlice(
|
function StreamEventsSlice(
|
||||||
@ -185,12 +185,12 @@ function DeleteResult(logPosition) {
|
|||||||
/**
|
/**
|
||||||
* @param {string} stream
|
* @param {string} stream
|
||||||
* @param {boolean} isStreamDeleted
|
* @param {boolean} isStreamDeleted
|
||||||
* @param {Long} metastreamVersion
|
* @param {number} metastreamVersion
|
||||||
* @param {object} streamMetadata
|
* @param {object} streamMetadata
|
||||||
* @constructor
|
* @constructor
|
||||||
* @property {string} stream
|
* @property {string} stream
|
||||||
* @property {boolean} isStreamDeleted
|
* @property {boolean} isStreamDeleted
|
||||||
* @property {Long} metastreamVersion
|
* @property {number} metastreamVersion
|
||||||
* @property {object} streamMetadata
|
* @property {object} streamMetadata
|
||||||
*/
|
*/
|
||||||
function RawStreamMetadataResult(stream, isStreamDeleted, metastreamVersion, streamMetadata) {
|
function RawStreamMetadataResult(stream, isStreamDeleted, metastreamVersion, streamMetadata) {
|
||||||
|
@ -71,9 +71,7 @@ const TcpCommand = {
|
|||||||
NotHandled: 0xF1,
|
NotHandled: 0xF1,
|
||||||
Authenticate: 0xF2,
|
Authenticate: 0xF2,
|
||||||
Authenticated: 0xF3,
|
Authenticated: 0xF3,
|
||||||
NotAuthenticated: 0xF4,
|
NotAuthenticated: 0xF4
|
||||||
IdentifyClient: 0xF5,
|
|
||||||
ClientIdentified: 0xF6
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var _reverseLookup = {};
|
var _reverseLookup = {};
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
var ANY_VERSION = Long.fromNumber(client.expectedVersion.any);
|
|
||||||
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Append One Event To Stream Happy Path': function(test) {
|
'Append One Event To Stream Happy Path': function(test) {
|
||||||
test.expect(2);
|
test.expect(2);
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
this.conn.appendToStream(this.testStreamName, ANY_VERSION, event)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, event)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual("nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(0));
|
test.areEqual("nextExpectedVersion", result.nextExpectedVersion, 0);
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -29,9 +25,9 @@ module.exports = {
|
|||||||
else
|
else
|
||||||
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
||||||
}
|
}
|
||||||
this.conn.appendToStream(this.testStreamName, ANY_VERSION, events)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, events)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(expectedVersion));
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, expectedVersion);
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -49,9 +45,9 @@ module.exports = {
|
|||||||
else
|
else
|
||||||
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
events.push(client.createJsonEventData(uuid.v4(), {b: Math.random(), a: uuid.v4()}, null, 'otherEvent'));
|
||||||
}
|
}
|
||||||
this.conn.appendToStream(this.testStreamName, ANY_VERSION, events)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, events)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(expectedVersion));
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, expectedVersion);
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -64,9 +60,9 @@ module.exports = {
|
|||||||
const largeData = Buffer.alloc(3 * 1024 *1024, " ");
|
const largeData = Buffer.alloc(3 * 1024 *1024, " ");
|
||||||
const event = client.createJsonEventData(uuid.v4(), {a: largeData.toString()}, null, 'largePayloadEvent');
|
const event = client.createJsonEventData(uuid.v4(), {a: largeData.toString()}, null, 'largePayloadEvent');
|
||||||
|
|
||||||
this.conn.appendToStream(this.testStreamName, ANY_VERSION, event)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, event)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(0));
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, 0);
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -77,7 +73,7 @@ module.exports = {
|
|||||||
'Append To Stream Wrong Expected Version': function(test) {
|
'Append To Stream Wrong Expected Version': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
this.conn.appendToStream(this.testStreamName, Long.fromNumber(10), event)
|
this.conn.appendToStream(this.testStreamName, 10, event)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Append succeeded but should have failed.");
|
test.fail("Append succeeded but should have failed.");
|
||||||
test.done();
|
test.done();
|
||||||
@ -92,10 +88,10 @@ module.exports = {
|
|||||||
'Append To Stream Deleted': function(test) {
|
'Append To Stream Deleted': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, NOSTREAM_VERSION, true)
|
this.conn.deleteStream(this.testStreamName, client.expectedVersion.noStream, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
return self.conn.appendToStream(self.testStreamName, ANY_VERSION, event)
|
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, event)
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Append succeeded but should have failed.");
|
test.fail("Append succeeded but should have failed.");
|
||||||
@ -112,10 +108,10 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$w: "$admins"}};
|
var metadata = {$acl: {$w: "$admins"}};
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, NOSTREAM_VERSION, metadata)
|
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.noStream, metadata)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
var event = client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'testEvent');
|
||||||
return self.conn.appendToStream(self.testStreamName, ANY_VERSION, event)
|
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.any, event)
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Append succeeded but should have failed.");
|
test.fail("Append succeeded but should have failed.");
|
||||||
|
@ -78,7 +78,7 @@ function testLiveEvent(name, event, evNumber) {
|
|||||||
this.ok(event.originalPosition instanceof client.Position, name + ".originalPosition is not an instance of Position");
|
this.ok(event.originalPosition instanceof client.Position, name + ".originalPosition is not an instance of Position");
|
||||||
this.ok(event.originalStreamId, name + ".originalStreamId not defined (or null)");
|
this.ok(event.originalStreamId, name + ".originalStreamId not defined (or null)");
|
||||||
if (typeof evNumber === 'number') {
|
if (typeof evNumber === 'number') {
|
||||||
this.ok(event.originalEventNumber.toNumber() === evNumber, name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber);
|
this.ok(event.originalEventNumber === evNumber, name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber);
|
||||||
} else {
|
} else {
|
||||||
this.ok(typeof event.originalEventNumber === 'number', name + ".originalEventNumber is not a number");
|
this.ok(typeof event.originalEventNumber === 'number', name + ".originalEventNumber is not a number");
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ function testReadEvent(name, event, evNumber) {
|
|||||||
this.ok(event.originalPosition === null, name + ".originalPosition is not null");
|
this.ok(event.originalPosition === null, name + ".originalPosition is not null");
|
||||||
this.ok(event.originalStreamId, name + ".originalStreamId not defined (or null)");
|
this.ok(event.originalStreamId, name + ".originalStreamId not defined (or null)");
|
||||||
if (typeof evNumber === 'number') {
|
if (typeof evNumber === 'number') {
|
||||||
this.ok(event.originalEventNumber.toNumber() === evNumber, name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber);
|
this.ok(event.originalEventNumber === evNumber, name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber);
|
||||||
} else {
|
} else {
|
||||||
this.ok(typeof event.originalEventNumber === 'number', name + ".originalEventNumber is not a number");
|
this.ok(typeof event.originalEventNumber === 'number', name + ".originalEventNumber is not a number");
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
@ -17,7 +16,7 @@ module.exports = {
|
|||||||
'Test Delete Stream Soft Happy Path': function(test) {
|
'Test Delete Stream Soft Happy Path': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, Long.fromNumber(1), false)
|
this.conn.deleteStream(this.testStreamName, 1, false)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
||||||
@ -35,7 +34,7 @@ module.exports = {
|
|||||||
'Test Delete Stream Hard Happy Path': function(test) {
|
'Test Delete Stream Hard Happy Path': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, Long.fromNumber(1), true)
|
this.conn.deleteStream(this.testStreamName, 1, true)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.ok(result.logPosition, "No log position in result.");
|
test.ok(result.logPosition, "No log position in result.");
|
||||||
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
return self.conn.getStreamMetadataRaw(self.testStreamName);
|
||||||
@ -52,7 +51,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
'Test Delete Stream With Wrong Expected Version': function(test) {
|
'Test Delete Stream With Wrong Expected Version': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
this.conn.deleteStream(this.testStreamName, Long.fromNumber(10))
|
this.conn.deleteStream(this.testStreamName, 10)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Delete succeeded but should have failed.");
|
test.fail("Delete succeeded but should have failed.");
|
||||||
test.done();
|
test.done();
|
||||||
@ -69,7 +68,7 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.any, {$acl: {$d: "$admins"}})
|
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.any, {$acl: {$d: "$admins"}})
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.deleteStream(self.testStreamName, Long.fromNumber(10));
|
return self.conn.deleteStream(self.testStreamName, 10);
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Delete succeeded but should have failed.");
|
test.fail("Delete succeeded but should have failed.");
|
||||||
@ -87,7 +86,7 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, 1, true)
|
this.conn.deleteStream(this.testStreamName, 1, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.deleteStream(self.testStreamName, Long.fromNumber(1), true);
|
return self.conn.deleteStream(self.testStreamName, 1, true);
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("Delete succeeded but should have failed.");
|
test.fail("Delete succeeded but should have failed.");
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
|
var util = require('util');
|
||||||
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
const Long = require('long');
|
|
||||||
|
|
||||||
const EMPTY_VERSION = Long.fromNumber(client.expectedVersion.emptyStream);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Set Stream Metadata Raw': function(test) {
|
'Test Set Stream Metadata Raw': function(test) {
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, EMPTY_VERSION, {$maxCount: 100})
|
this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.emptyStream, {$maxCount: 100})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
|
47
test/projections_test.js
Normal file
47
test/projections_test.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
const client = require('../src/client');
|
||||||
|
const userCredentials = new client.UserCredentials('admin', 'changeit');
|
||||||
|
|
||||||
|
const log = new client.NoopLogger();
|
||||||
|
const httpEndpoint = 'http://127.0.0.1:2113';
|
||||||
|
const operationTimeout = 5000;
|
||||||
|
|
||||||
|
const simpleProjection = "\
|
||||||
|
fromStream('$stats-127.0.0.1:2113')\
|
||||||
|
.when({\
|
||||||
|
$init: function(){\
|
||||||
|
return {\
|
||||||
|
count: 0\
|
||||||
|
}\
|
||||||
|
},\
|
||||||
|
$any: function(s,e){\
|
||||||
|
s.count += 1;\
|
||||||
|
}\
|
||||||
|
})\
|
||||||
|
";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setUp: function(cb) {
|
||||||
|
this.projectionsManager = new client.ProjectionsManager(log, httpEndpoint, operationTimeout);
|
||||||
|
cb();
|
||||||
|
},
|
||||||
|
'Create One Time Projection Happy Path': function(test) {
|
||||||
|
test.expect(1);
|
||||||
|
|
||||||
|
this.projectionsManager.createOneTime(simpleProjection, userCredentials)
|
||||||
|
.then(function (result) {
|
||||||
|
test.equal(result, undefined);
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(test.done);
|
||||||
|
},
|
||||||
|
'List All Happy Path': function(test) {
|
||||||
|
test.expect(1);
|
||||||
|
this.projectionsManager.listAll(userCredentials)
|
||||||
|
.then(function (projections) {
|
||||||
|
test.ok(projections.length > 0, "no projections");
|
||||||
|
test.done();
|
||||||
|
})
|
||||||
|
.catch(test.done);
|
||||||
|
}
|
||||||
|
//TODO: other tests
|
||||||
|
};
|
@ -1,9 +1,7 @@
|
|||||||
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
|
||||||
var ANY_VERSION = Long.fromNumber(client.expectedVersion.any);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
@ -14,7 +12,7 @@ module.exports = {
|
|||||||
this.expectedEventType = 'anEvent';
|
this.expectedEventType = 'anEvent';
|
||||||
this.expectedEventId = uuid.v4();
|
this.expectedEventId = uuid.v4();
|
||||||
var event = client.createJsonEventData(this.expectedEventId, this.expectedEvent, null, this.expectedEventType);
|
var event = client.createJsonEventData(this.expectedEventId, this.expectedEvent, null, this.expectedEventType);
|
||||||
this.conn.appendToStream(this.testStreamName, NOSTREAM_VERSION, event)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, event)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
cb();
|
cb();
|
||||||
})
|
})
|
||||||
@ -23,11 +21,11 @@ module.exports = {
|
|||||||
'Read Event Happy Path': function(test) {
|
'Read Event Happy Path': function(test) {
|
||||||
test.expect(8);
|
test.expect(8);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.readEvent(this.testStreamName, Long.fromNumber(0))
|
this.conn.readEvent(this.testStreamName, 0)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.Success);
|
test.areEqual('status', result.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('stream', result.stream, self.testStreamName);
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(0));
|
test.areEqual('eventNumber', result.eventNumber, 0);
|
||||||
test.ok(result.event !== null, "event is null.");
|
test.ok(result.event !== null, "event is null.");
|
||||||
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
|
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
|
||||||
var event = JSON.parse(result.event.originalEvent.data.toString());
|
var event = JSON.parse(result.event.originalEvent.data.toString());
|
||||||
@ -43,11 +41,11 @@ module.exports = {
|
|||||||
'Read Event From Non-Existing Stream': function(test) {
|
'Read Event From Non-Existing Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var anotherStream = 'test' + uuid.v4();
|
var anotherStream = 'test' + uuid.v4();
|
||||||
this.conn.readEvent(anotherStream, Long.fromNumber(0))
|
this.conn.readEvent(anotherStream, 0)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.NoStream);
|
test.areEqual('status', result.status, client.eventReadStatus.NoStream);
|
||||||
test.areEqual('stream', result.stream, anotherStream);
|
test.areEqual('stream', result.stream, anotherStream);
|
||||||
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(0));
|
test.areEqual('eventNumber', result.eventNumber, 0);
|
||||||
test.areEqual('event', result.event, null);
|
test.areEqual('event', result.event, null);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -60,12 +58,12 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, 0, true)
|
this.conn.deleteStream(this.testStreamName, 0, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.readEvent(self.testStreamName, Long.fromNumber(0))
|
return self.conn.readEvent(self.testStreamName, 0)
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.StreamDeleted);
|
test.areEqual('status', result.status, client.eventReadStatus.StreamDeleted);
|
||||||
test.areEqual('stream', result.stream, self.testStreamName);
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(0));
|
test.areEqual('eventNumber', result.eventNumber, 0);
|
||||||
test.areEqual('event', result.event, null);
|
test.areEqual('event', result.event, null);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -76,11 +74,11 @@ module.exports = {
|
|||||||
'Read Event With Inexisting Version': function(test) {
|
'Read Event With Inexisting Version': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
return self.conn.readEvent(self.testStreamName, Long.fromNumber(1))
|
return self.conn.readEvent(self.testStreamName, 1)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.NotFound);
|
test.areEqual('status', result.status, client.eventReadStatus.NotFound);
|
||||||
test.areEqual('stream', result.stream, self.testStreamName);
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(1));
|
test.areEqual('eventNumber', result.eventNumber, 1);
|
||||||
test.areEqual('event', result.event, null);
|
test.areEqual('event', result.event, null);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -96,9 +94,9 @@ module.exports = {
|
|||||||
$r: '$admins'
|
$r: '$admins'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.conn.setStreamMetadataRaw(self.testStreamName, NOSTREAM_VERSION, metadata)
|
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.readEvent(self.testStreamName, Long.fromNumber(0));
|
return self.conn.readEvent(self.testStreamName, 0);
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.fail("readEvent succeeded but should have failed.");
|
test.fail("readEvent succeeded but should have failed.");
|
||||||
@ -120,13 +118,13 @@ module.exports = {
|
|||||||
a: largeData.toString()
|
a: largeData.toString()
|
||||||
}, null, 'largePayloadEvent');
|
}, null, 'largePayloadEvent');
|
||||||
|
|
||||||
this.conn.appendToStream(this.testStreamName, ANY_VERSION, largeEvent)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.any, largeEvent)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
self.conn.readEvent(self.testStreamName, Long.fromNumber(1))
|
self.conn.readEvent(self.testStreamName, 1)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.areEqual('status', result.status, client.eventReadStatus.Success);
|
test.areEqual('status', result.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('stream', result.stream, self.testStreamName);
|
test.areEqual('stream', result.stream, self.testStreamName);
|
||||||
test.areEqual('eventNumber', result.eventNumber, Long.fromNumber(1));
|
test.areEqual('eventNumber', result.eventNumber, 1);
|
||||||
test.ok(result.event !== null, "event is null.");
|
test.ok(result.event !== null, "event is null.");
|
||||||
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
|
test.ok(result.event.originalEvent !== null, "event.originalEvent is null.");
|
||||||
var event = JSON.parse(result.event.originalEvent.data.toString());
|
var event = JSON.parse(result.event.originalEvent.data.toString());
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
const streamSize = 100;
|
const streamSize = 100;
|
||||||
|
|
||||||
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
this.eventsData = [];
|
this.eventsData = [];
|
||||||
for(var i = 0; i < streamSize; i++)
|
for(var i = 0; i < streamSize; i++)
|
||||||
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
this.conn.appendToStream(this.testStreamName, NOSTREAM_VERSION, this.eventsData)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, this.eventsData)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
cb();
|
cb();
|
||||||
})
|
})
|
||||||
@ -20,19 +18,19 @@ module.exports = {
|
|||||||
'Read Stream Events Backward Happy Path': function(test) {
|
'Read Stream Events Backward Happy Path': function(test) {
|
||||||
test.expect(7 + (streamSize * 6));
|
test.expect(7 + (streamSize * 6));
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.readStreamEventsBackward(this.testStreamName, Long.fromNumber(streamSize-1), streamSize)
|
this.conn.readStreamEventsBackward(this.testStreamName, streamSize-1, streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize-1));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
||||||
test.areEqual('slice.readDirection', slice.readDirection, 'backward');
|
test.areEqual('slice.readDirection', slice.readDirection, 'backward');
|
||||||
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, Long.fromNumber(-1));
|
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, -1);
|
||||||
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, Long.fromNumber(streamSize-1));
|
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, streamSize-1);
|
||||||
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
||||||
for(var i = 0; i < streamSize; i++) {
|
for(var i = 0; i < streamSize; i++) {
|
||||||
var reverseIndex = streamSize - i - 1;
|
var reverseIndex = streamSize - i - 1;
|
||||||
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[reverseIndex]);
|
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[reverseIndex]);
|
||||||
test.areEqual('slice.events[' + i + '].originalEventNumber', slice.events[i].originalEventNumber, Long.fromNumber(reverseIndex));
|
test.areEqual('slice.events[' + i + '].originalEventNumber', slice.events[i].originalEventNumber, reverseIndex);
|
||||||
}
|
}
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -43,11 +41,11 @@ module.exports = {
|
|||||||
'Read Stream Events Backward With Non-Existing Stream': function(test) {
|
'Read Stream Events Backward With Non-Existing Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var anotherStream = 'test' + uuid.v4();
|
var anotherStream = 'test' + uuid.v4();
|
||||||
this.conn.readStreamEventsBackward(anotherStream, Long.fromNumber(streamSize-1), streamSize)
|
this.conn.readStreamEventsBackward(anotherStream, streamSize-1, streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
||||||
test.areEqual('slice.stream', slice.stream, anotherStream);
|
test.areEqual('slice.stream', slice.stream, anotherStream);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize-1));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -58,14 +56,14 @@ module.exports = {
|
|||||||
'Read Stream Events Backward With Deleted Stream': function(test) {
|
'Read Stream Events Backward With Deleted Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, Long.fromNumber(streamSize-1), true)
|
this.conn.deleteStream(this.testStreamName, streamSize-1, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.readStreamEventsBackward(self.testStreamName, Long.fromNumber(streamSize-1), streamSize)
|
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize-1, streamSize)
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize-1));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize-1);
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -76,11 +74,11 @@ module.exports = {
|
|||||||
'Read Stream Events Backward With Inexisting Version': function(test) {
|
'Read Stream Events Backward With Inexisting Version': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
return self.conn.readStreamEventsBackward(self.testStreamName, Long.fromNumber(streamSize * 2), streamSize)
|
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize * 2, streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize*2));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize*2);
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -92,9 +90,9 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$r: '$admins'}};
|
var metadata = {$acl: {$r: '$admins'}};
|
||||||
this.conn.setStreamMetadataRaw(self.testStreamName, NOSTREAM_VERSION, metadata)
|
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
||||||
.then(function(){
|
.then(function(){
|
||||||
return self.conn.readStreamEventsBackward(self.testStreamName, Long.fromNumber(streamSize-1), streamSize);
|
return self.conn.readStreamEventsBackward(self.testStreamName, streamSize-1, streamSize);
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.fail("readStreamEventsBackward succeeded but should have failed.");
|
test.fail("readStreamEventsBackward succeeded but should have failed.");
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
const streamSize = 100;
|
const streamSize = 100;
|
||||||
|
|
||||||
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
this.eventsData = [];
|
this.eventsData = [];
|
||||||
for(var i = 0; i < streamSize; i++)
|
for(var i = 0; i < streamSize; i++)
|
||||||
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
this.eventsData.push(client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, null, 'anEvent'));
|
||||||
this.conn.appendToStream(this.testStreamName, NOSTREAM_VERSION, this.eventsData)
|
this.conn.appendToStream(this.testStreamName, client.expectedVersion.noStream, this.eventsData)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
cb();
|
cb();
|
||||||
})
|
})
|
||||||
@ -20,14 +18,14 @@ module.exports = {
|
|||||||
'Read Stream Events Forward Happy Path': function(test) {
|
'Read Stream Events Forward Happy Path': function(test) {
|
||||||
test.expect(7 + (streamSize * 11));
|
test.expect(7 + (streamSize * 11));
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.readStreamEventsForward(this.testStreamName, Long.fromNumber(0), streamSize)
|
this.conn.readStreamEventsForward(this.testStreamName, 0, streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(0));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
||||||
test.areEqual('slice.readDirection', slice.readDirection, 'forward');
|
test.areEqual('slice.readDirection', slice.readDirection, 'forward');
|
||||||
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, Long.fromNumber(streamSize));
|
test.areEqual('slice.nextEventNumber', slice.nextEventNumber, streamSize);
|
||||||
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, Long.fromNumber(streamSize-1));
|
test.areEqual('slice.lastEventNumber', slice.lastEventNumber, streamSize-1);
|
||||||
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
test.areEqual('slice.isEndOfStream', slice.isEndOfStream, true);
|
||||||
for(var i = 0; i < streamSize; i++) {
|
for(var i = 0; i < streamSize; i++) {
|
||||||
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[i]);
|
test.eventEqualEventData('slice.events[' + i + ']', slice.events[i], self.eventsData[i]);
|
||||||
@ -42,11 +40,11 @@ module.exports = {
|
|||||||
'Read Stream Events Forward With Non-Existing Stream': function(test) {
|
'Read Stream Events Forward With Non-Existing Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var anotherStream = 'test' + uuid.v4();
|
var anotherStream = 'test' + uuid.v4();
|
||||||
this.conn.readStreamEventsForward(anotherStream, Long.fromNumber(0), streamSize)
|
this.conn.readStreamEventsForward(anotherStream, 0, streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
test.areEqual('slice.status', slice.status, client.sliceReadStatus.StreamNotFound);
|
||||||
test.areEqual('slice.stream', slice.stream, anotherStream);
|
test.areEqual('slice.stream', slice.stream, anotherStream);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(0));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -57,14 +55,14 @@ module.exports = {
|
|||||||
'Read Stream Events Forward With Deleted Stream': function(test) {
|
'Read Stream Events Forward With Deleted Stream': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, Long.fromNumber(streamSize-1), true)
|
this.conn.deleteStream(this.testStreamName, streamSize-1, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.readStreamEventsForward(self.testStreamName, Long.fromNumber(0), streamSize)
|
return self.conn.readStreamEventsForward(self.testStreamName, 0, streamSize)
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.StreamDeleted);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(0));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, 0);
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -75,11 +73,11 @@ module.exports = {
|
|||||||
'Read Stream Events Forward With Inexisting Version': function(test) {
|
'Read Stream Events Forward With Inexisting Version': function(test) {
|
||||||
test.expect(4);
|
test.expect(4);
|
||||||
var self = this;
|
var self = this;
|
||||||
return self.conn.readStreamEventsForward(self.testStreamName, Long.fromNumber(streamSize * 2), streamSize)
|
return self.conn.readStreamEventsForward(self.testStreamName, streamSize * 2, streamSize)
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
test.areEqual('slice.status', slice.status, client.eventReadStatus.Success);
|
||||||
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
test.areEqual('slice.stream', slice.stream, self.testStreamName);
|
||||||
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, Long.fromNumber(streamSize*2));
|
test.areEqual('slice.fromEventNumber', slice.fromEventNumber, streamSize*2);
|
||||||
test.areEqual('slice.events.length', slice.events.length, 0);
|
test.areEqual('slice.events.length', slice.events.length, 0);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
@ -91,9 +89,9 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$r: '$admins'}};
|
var metadata = {$acl: {$r: '$admins'}};
|
||||||
this.conn.setStreamMetadataRaw(self.testStreamName, NOSTREAM_VERSION, metadata)
|
this.conn.setStreamMetadataRaw(self.testStreamName, client.expectedVersion.noStream, metadata)
|
||||||
.then(function(){
|
.then(function(){
|
||||||
return self.conn.readStreamEventsForward(self.testStreamName, Long.fromNumber(0), streamSize);
|
return self.conn.readStreamEventsForward(self.testStreamName, 0, streamSize);
|
||||||
})
|
})
|
||||||
.then(function(slice) {
|
.then(function(slice) {
|
||||||
test.fail("readStreamEventsForward succeeded but should have failed.");
|
test.fail("readStreamEventsForward succeeded but should have failed.");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
var util = require('util');
|
||||||
var uuid = require('uuid');
|
var uuid = require('uuid');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
var Long = require('long');
|
|
||||||
|
|
||||||
function createRandomEvent() {
|
function createRandomEvent() {
|
||||||
return client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, {createdAt: Date.now()}, 'testEvent');
|
return client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, {createdAt: Date.now()}, 'testEvent');
|
||||||
@ -22,7 +22,7 @@ function delayOnlyFirst(count, action) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Test Subscribe to Stream From Beginning (null)': function(test) {
|
'Test Subscribe to Stream From Beginning (null)': function(test) {
|
||||||
test.expect(32);
|
test.expect(36);
|
||||||
var self = this;
|
var self = this;
|
||||||
var liveProcessing = false;
|
var liveProcessing = false;
|
||||||
var catchUpEvents = [];
|
var catchUpEvents = [];
|
||||||
@ -57,11 +57,15 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
function subscriptionDropped(connection, reason, error) {
|
function subscriptionDropped(connection, reason, error) {
|
||||||
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
||||||
test.testLiveEvent('liveEvents[0]', liveEvents[0], 2);
|
test.testLiveEvent('liveEvents[0]', liveEvents[0]);
|
||||||
test.testLiveEvent('liveEvents[1]', liveEvents[1], 3);
|
test.testLiveEvent('liveEvents[1]', liveEvents[1]);
|
||||||
|
test.ok(liveEvents[0].originalEventNumber, 2);
|
||||||
|
test.ok(liveEvents[1].originalEventNumber, 3);
|
||||||
test.ok(catchUpEvents.length === 2, "Expecting 2 catchUp event, got " + catchUpEvents.length);
|
test.ok(catchUpEvents.length === 2, "Expecting 2 catchUp event, got " + catchUpEvents.length);
|
||||||
test.testReadEvent('catchUpEvents[0]', catchUpEvents[0], 0);
|
test.testReadEvent('catchUpEvents[0]', catchUpEvents[0]);
|
||||||
test.testReadEvent('catchUpEvents[1]', catchUpEvents[1], 1);
|
test.testReadEvent('catchUpEvents[1]', catchUpEvents[1]);
|
||||||
|
test.ok(liveEvents[0].originalEventNumber, 0);
|
||||||
|
test.ok(liveEvents[1].originalEventNumber, 1);
|
||||||
done(error);
|
done(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +82,7 @@ module.exports = {
|
|||||||
.catch(test.done);
|
.catch(test.done);
|
||||||
},
|
},
|
||||||
'Test Subscribe to Stream From 0': function(test) {
|
'Test Subscribe to Stream From 0': function(test) {
|
||||||
test.expect(26);
|
test.expect(29);
|
||||||
var self = this;
|
var self = this;
|
||||||
var liveProcessing = false;
|
var liveProcessing = false;
|
||||||
var catchUpEvents = [];
|
var catchUpEvents = [];
|
||||||
@ -113,17 +117,20 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
function subscriptionDropped(connection, reason, error) {
|
function subscriptionDropped(connection, reason, error) {
|
||||||
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
test.ok(liveEvents.length === 2, "Expecting 2 live event, got " + liveEvents.length);
|
||||||
test.testLiveEvent('liveEvents[0]', liveEvents[0], 2);
|
test.testLiveEvent('liveEvents[0]', liveEvents[0]);
|
||||||
test.testLiveEvent('liveEvents[1]', liveEvents[1], 3);
|
test.testLiveEvent('liveEvents[1]', liveEvents[1]);
|
||||||
|
test.ok(liveEvents[0].originalEventNumber, 2);
|
||||||
|
test.ok(liveEvents[1].originalEventNumber, 3);
|
||||||
test.ok(catchUpEvents.length === 1, "Expecting 1 catchUp event, got " + catchUpEvents.length);
|
test.ok(catchUpEvents.length === 1, "Expecting 1 catchUp event, got " + catchUpEvents.length);
|
||||||
test.testReadEvent('catchUpEvents[0]', catchUpEvents[0], 1);
|
test.testReadEvent('catchUpEvents[0]', catchUpEvents[0]);
|
||||||
|
test.ok(liveEvents[0].originalEventNumber, 1);
|
||||||
done(error);
|
done(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = [createRandomEvent(), createRandomEvent()];
|
var events = [createRandomEvent(), createRandomEvent()];
|
||||||
this.conn.appendToStream(self.testStreamName, client.expectedVersion.noStream, events)
|
this.conn.appendToStream(self.testStreamName, client.expectedVersion.noStream, events)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var subscription = self.conn.subscribeToStreamFrom(self.testStreamName, Long.fromNumber(0), false, eventAppeared, liveProcessingStarted, subscriptionDropped);
|
var subscription = self.conn.subscribeToStreamFrom(self.testStreamName, 0, false, eventAppeared, liveProcessingStarted, subscriptionDropped);
|
||||||
|
|
||||||
test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName);
|
test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName);
|
||||||
test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false);
|
test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
const uuid = require('uuid');
|
const uuid = require('uuid');
|
||||||
const client = require('../src/client');
|
const client = require('../src/client');
|
||||||
const Long = require('long');
|
|
||||||
|
|
||||||
function delay(ms) {
|
function delay(ms) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
@ -59,7 +58,7 @@ module.exports = {
|
|||||||
.then(function(subscription) {
|
.then(function(subscription) {
|
||||||
test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName);
|
test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName);
|
||||||
test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false);
|
test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false);
|
||||||
test.areEqual("subscription.lastEventNumber", subscription.lastEventNumber, Long.fromNumber(client.expectedVersion.emptyStream));
|
test.areEqual("subscription.lastEventNumber", subscription.lastEventNumber, client.expectedVersion.emptyStream);
|
||||||
|
|
||||||
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.emptyStream, publishedEvents);
|
return self.conn.appendToStream(self.testStreamName, client.expectedVersion.emptyStream, publishedEvents);
|
||||||
})
|
})
|
||||||
|
@ -2,17 +2,13 @@ var uuid = require('uuid');
|
|||||||
var Long = require('long');
|
var Long = require('long');
|
||||||
var client = require('../src/client');
|
var client = require('../src/client');
|
||||||
|
|
||||||
var ANY_VERSION = Long.fromNumber(client.expectedVersion.any);
|
|
||||||
var NOSTREAM_VERSION = Long.fromNumber(client.expectedVersion.noStream);
|
|
||||||
var EMPTY_VERSION = Long.fromNumber(client.expectedVersion.emptyStream);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setUp: function(cb) {
|
setUp: function(cb) {
|
||||||
cb();
|
cb();
|
||||||
},
|
},
|
||||||
'Start A Transaction Happy Path': function(test) {
|
'Start A Transaction Happy Path': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
this.conn.startTransaction(this.testStreamName, NOSTREAM_VERSION)
|
this.conn.startTransaction(this.testStreamName, client.expectedVersion.noStream)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
test.ok(Long.isLong(trx.transactionId), "trx.transactionId should be a Long.");
|
test.ok(Long.isLong(trx.transactionId), "trx.transactionId should be a Long.");
|
||||||
test.done();
|
test.done();
|
||||||
@ -36,7 +32,7 @@ module.exports = {
|
|||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream)
|
this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.startTransaction(self.testStreamName, ANY_VERSION);
|
return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any);
|
||||||
})
|
})
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
test.fail("Start Transaction with deleted stream succeeded.");
|
test.fail("Start Transaction with deleted stream succeeded.");
|
||||||
@ -54,9 +50,9 @@ module.exports = {
|
|||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
var metadata = {$acl: {$w: "$admins"}};
|
var metadata = {$acl: {$w: "$admins"}};
|
||||||
this.conn.setStreamMetadataRaw(this.testStreamName, EMPTY_VERSION, metadata)
|
this.conn.setStreamMetadataRaw(this.testStreamName, -1, metadata)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.startTransaction(self.testStreamName, ANY_VERSION);
|
return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any);
|
||||||
})
|
})
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
test.fail("Start Transaction with no access succeeded.");
|
test.fail("Start Transaction with no access succeeded.");
|
||||||
@ -71,7 +67,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
'Continue A Transaction Happy Path': function(test) {
|
'Continue A Transaction Happy Path': function(test) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.startTransaction(this.testStreamName, EMPTY_VERSION)
|
this.conn.startTransaction(this.testStreamName, client.expectedVersion.emptyStream)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random()}, null, 'anEvent'))
|
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random()}, null, 'anEvent'))
|
||||||
.then(function () {
|
.then(function () {
|
||||||
@ -92,7 +88,7 @@ module.exports = {
|
|||||||
'Write/Commit Transaction Happy Path': function(test) {
|
'Write/Commit Transaction Happy Path': function(test) {
|
||||||
test.expect(2);
|
test.expect(2);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.startTransaction(this.testStreamName, EMPTY_VERSION)
|
this.conn.startTransaction(this.testStreamName, client.expectedVersion.emptyStream)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
self.events = [];
|
self.events = [];
|
||||||
for(var i = 0; i < 15; i++) {
|
for(var i = 0; i < 15; i++) {
|
||||||
@ -115,7 +111,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
test.ok(result.logPosition, "Missing result.logPosition");
|
test.ok(result.logPosition, "Missing result.logPosition");
|
||||||
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, Long.fromNumber(self.events.length-1));
|
test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, self.events.length-1);
|
||||||
test.done();
|
test.done();
|
||||||
})
|
})
|
||||||
.catch(test.done);
|
.catch(test.done);
|
||||||
@ -143,9 +139,9 @@ module.exports = {
|
|||||||
'Write/Commit Transaction With Deleted Stream': function(test) {
|
'Write/Commit Transaction With Deleted Stream': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.deleteStream(this.testStreamName, EMPTY_VERSION, true)
|
this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream, true)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return self.conn.startTransaction(self.testStreamName, ANY_VERSION);
|
return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any);
|
||||||
})
|
})
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
||||||
@ -167,10 +163,10 @@ module.exports = {
|
|||||||
'Write/Commit Transaction With No Write Access': function(test) {
|
'Write/Commit Transaction With No Write Access': function(test) {
|
||||||
test.expect(1);
|
test.expect(1);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.conn.startTransaction(this.testStreamName, ANY_VERSION)
|
this.conn.startTransaction(this.testStreamName, client.expectedVersion.any)
|
||||||
.then(function(trx) {
|
.then(function(trx) {
|
||||||
var metadata = {$acl: {$w: "$admins"}};
|
var metadata = {$acl: {$w: "$admins"}};
|
||||||
return self.conn.setStreamMetadataRaw(self.testStreamName, EMPTY_VERSION, metadata)
|
return self.conn.setStreamMetadataRaw(self.testStreamName, -1, metadata)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent'))
|
||||||
.then(function () {
|
.then(function () {
|
||||||
|
Reference in New Issue
Block a user