@dolittle/sdk.projections
Version:
Dolittle is a decentralized, distributed, event-driven microservice platform built to harness the power of events.
195 lines • 23.4 kB
JavaScript
;
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectionProcessor = void 0;
const luxon_1 = require("luxon");
const wrappers_pb_1 = require("google-protobuf/google/protobuf/wrappers_pb");
const sdk_events_1 = require("@dolittle/sdk.events");
const sdk_events_processing_1 = require("@dolittle/sdk.events.processing");
const sdk_protobuf_1 = require("@dolittle/sdk.protobuf");
const sdk_services_1 = require("@dolittle/sdk.services");
const Projections_pb_1 = require("@dolittle/contracts/Runtime/Events.Processing/Projections_pb");
const State_pb_1 = require("@dolittle/contracts/Runtime/Projections/State_pb");
const DeleteReadModelInstance_1 = require("../DeleteReadModelInstance");
const EventPropertyKeySelector_1 = require("../EventPropertyKeySelector");
const EventSourceIdKeySelector_1 = require("../EventSourceIdKeySelector");
const Key_1 = require("../Key");
const PartitionIdKeySelector_1 = require("../PartitionIdKeySelector");
const ProjectionContext_1 = require("../ProjectionContext");
const UnknownKeySelectorType_1 = require("../UnknownKeySelectorType");
const Conversion_1 = require("../Copies/MongoDB/Conversion");
const UnknownMongoDBConversion_1 = require("../Copies/MongoDB/UnknownMongoDBConversion");
const StaticKeySelector_1 = require("../StaticKeySelector");
const EventOccurredKeySelector_1 = require("../EventOccurredKeySelector");
/**
* Represents an implementation of {@link Internal.EventProcessor} for {@link Projection}.
* @template T The type of the projection read model.
*/
class ProjectionProcessor extends sdk_events_processing_1.Internal.EventProcessor {
/**
* Initializes a new instance of {@link ProjectionProcessor}.
* @param {IProjection<T>} _projection - The projection.
* @param {IEventTypes} _eventTypes - The registered event types for this projection.
*/
constructor(_projection, _eventTypes) {
super('Projection', _projection.projectionId);
this._projection = _projection;
this._eventTypes = _eventTypes;
}
/** @inheritdoc */
get registerArguments() {
const registerArguments = new Projections_pb_1.ProjectionRegistrationRequest();
registerArguments.setProjectionid(sdk_protobuf_1.Guids.toProtobuf(this._projection.projectionId.value));
registerArguments.setScopeid(sdk_protobuf_1.Guids.toProtobuf(this._projection.scopeId.value));
registerArguments.setInitialstate(JSON.stringify(this._projection.initialState));
registerArguments.setCopies(this.createCopiesSpecification());
if (this._projection.hasAlias) {
registerArguments.setAlias(this._projection.alias.value);
}
const events = [];
for (const eventSelector of this._projection.events) {
const selector = new Projections_pb_1.ProjectionEventSelector();
selector.setEventtype(sdk_protobuf_1.Artifacts.toProtobuf(eventSelector.eventType));
this.setKeySelector(selector, eventSelector.keySelector);
events.push(selector);
}
registerArguments.setEventsList(events);
return registerArguments;
}
setKeySelector(protobufSelector, selector) {
if (selector instanceof EventPropertyKeySelector_1.EventPropertyKeySelector) {
const propertyKeySelector = new Projections_pb_1.EventPropertyKeySelector();
propertyKeySelector.setPropertyname(selector.propertyName.value);
protobufSelector.setEventpropertykeyselector(propertyKeySelector);
}
else if (selector instanceof EventSourceIdKeySelector_1.EventSourceIdKeySelector) {
protobufSelector.setEventsourcekeyselector(new Projections_pb_1.EventSourceIdKeySelector());
}
else if (selector instanceof PartitionIdKeySelector_1.PartitionIdKeySelector) {
protobufSelector.setPartitionkeyselector(new Projections_pb_1.PartitionIdKeySelector());
}
else if (selector instanceof StaticKeySelector_1.StaticKeySelector) {
const staticKeySelector = new Projections_pb_1.StaticKeySelector();
staticKeySelector.setStatickey(selector.staticKey.value);
protobufSelector.setStatickeyselector(staticKeySelector);
}
else if (selector instanceof EventOccurredKeySelector_1.EventOccurredKeySelector) {
const eventOccurredKeySelector = new Projections_pb_1.EventOccurredKeySelector();
eventOccurredKeySelector.setFormat(selector.occurredFormat.value);
protobufSelector.setEventoccurredkeyselector(eventOccurredKeySelector);
}
else {
throw new UnknownKeySelectorType_1.UnknownKeySelectorType(selector);
}
}
createCopiesSpecification() {
const copies = new Projections_pb_1.ProjectionCopies();
if (this._projection.copies.mongoDB.shouldCopyToMongoDB) {
const mongoDB = new Projections_pb_1.ProjectionCopyToMongoDB();
mongoDB.setCollection(this._projection.copies.mongoDB.collectionName.value);
mongoDB.setConversionsList(this.createMongoDBPropertyConversions(this._projection.copies.mongoDB.conversions));
copies.setMongodb(mongoDB);
}
return copies;
}
createMongoDBPropertyConversions(conversions) {
return conversions.map(conversion => {
const pbConversion = new Projections_pb_1.ProjectionCopyToMongoDB.PropertyConversion();
pbConversion.setPropertyname(conversion.property.value);
const pbConversionType = conversion.convertTo === Conversion_1.Conversion.None ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.NONE :
conversion.convertTo === Conversion_1.Conversion.Date ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.DATEASDATE :
conversion.convertTo === Conversion_1.Conversion.DateAsArray ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.DATEASARRAY :
conversion.convertTo === Conversion_1.Conversion.DateAsDocument ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.DATEASDOCUMENT :
conversion.convertTo === Conversion_1.Conversion.DateAsString ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.DATEASSTRING :
conversion.convertTo === Conversion_1.Conversion.DateAsInt64 ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.DATEASINT64 :
conversion.convertTo === Conversion_1.Conversion.Guid ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.GUIDASSTANDARDBINARY :
conversion.convertTo === Conversion_1.Conversion.GuidAsCSharpLegacy ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.GUIDASCSHARPLEGACYBINARY :
conversion.convertTo === Conversion_1.Conversion.GuidAsString ? Projections_pb_1.ProjectionCopyToMongoDB.BSONType.GUIDASSTRING :
undefined;
if (pbConversionType === undefined) {
throw new UnknownMongoDBConversion_1.UnknownMongoDBConversion(conversion.convertTo);
}
pbConversion.setConvertto(pbConversionType);
if (conversion.shouldRename) {
const renameTo = new wrappers_pb_1.StringValue();
renameTo.setValue(conversion.renameTo.value);
pbConversion.setRenameto(renameTo);
}
pbConversion.setChildrenList(this.createMongoDBPropertyConversions(conversion.children));
return pbConversion;
});
}
/** @inheritdoc */
createClient(client, registerArguments, callback, executionContext, pingInterval, logger, cancellation) {
return new sdk_services_1.ReverseCallClient((requests, cancellation) => (0, sdk_services_1.reactiveDuplex)(client, client.connect, requests, cancellation), Projections_pb_1.ProjectionClientToRuntimeMessage, (message, connectArguments) => message.setRegistrationrequest(connectArguments), (message) => message.getRegistrationresponse(), (message) => message.getHandlerequest(), (message, response) => message.setHandleresult(response), (connectArguments, context) => connectArguments.setCallcontext(context), (request) => request.getCallcontext(), (response, context) => response.setCallcontext(context), (message) => message.getPing(), (message, pong) => message.setPong(pong), executionContext, registerArguments, pingInterval, callback, cancellation, logger);
}
/** @inheritdoc */
getFailureFromRegisterResponse(response) {
return response.getFailure();
}
/** @inheritdoc */
getRetryProcessingStateFromRequest(request) {
return request.getRetryprocessingstate();
}
/** @inheritdoc */
createResponseFromFailure(failure) {
const response = new Projections_pb_1.ProjectionResponse();
response.setFailure(failure);
return response;
}
/** @inheritdoc */
async handle(request, executionContext, services, logger) {
var _a, _b;
if (!request.getEvent() || !((_a = request.getEvent()) === null || _a === void 0 ? void 0 : _a.getEvent())) {
throw new sdk_events_processing_1.MissingEventInformation('No event in ProjectionRequest');
}
const pbEvent = request.getEvent().getEvent();
const pbSequenceNumber = pbEvent.getEventlogsequencenumber();
if (pbSequenceNumber === undefined)
throw new sdk_events_processing_1.MissingEventInformation('Sequence Number');
const pbEventSourceId = pbEvent.getEventsourceid();
if (!pbEventSourceId)
throw new sdk_events_processing_1.MissingEventInformation('EventSourceId');
const pbExecutionContext = pbEvent.getExecutioncontext();
if (!pbExecutionContext)
throw new sdk_events_processing_1.MissingEventInformation('Execution context');
const pbOccurred = pbEvent.getOccurred();
if (!pbOccurred)
throw new sdk_events_processing_1.MissingEventInformation('Occurred');
const pbEventType = pbEvent.getEventtype();
if (!pbEventType)
throw new sdk_events_processing_1.MissingEventInformation('Event Type');
const eventContext = new sdk_events_1.EventContext(pbSequenceNumber, sdk_events_1.EventSourceId.from(pbEventSourceId), luxon_1.DateTime.fromJSDate(pbOccurred.toDate()), sdk_protobuf_1.ExecutionContexts.toSDK(pbExecutionContext), executionContext);
if (!request.getCurrentstate() || !((_b = request.getCurrentstate()) === null || _b === void 0 ? void 0 : _b.getState())) {
throw new sdk_events_processing_1.MissingEventInformation('No state in ProjectionRequest');
}
const pbCurrentState = request.getCurrentstate();
const pbStateType = pbCurrentState.getType();
const pbKey = pbCurrentState.getKey();
const projectionContext = new ProjectionContext_1.ProjectionContext(pbStateType === State_pb_1.ProjectionCurrentStateType.CREATED_FROM_INITIAL_STATE, Key_1.Key.from(pbKey), eventContext);
let event = JSON.parse(pbEvent.getContent());
const eventType = sdk_protobuf_1.Artifacts.toSDK(pbEventType, sdk_events_1.EventType.from);
if (this._eventTypes.hasTypeFor(eventType)) {
const typeOfEvent = this._eventTypes.getTypeFor(eventType);
event = Object.assign(new typeOfEvent(), event);
}
let state = JSON.parse(request.getCurrentstate().getState());
if (this._projection.readModelType !== undefined) {
state = Object.assign(new this._projection.readModelType(), state);
}
const nextStateOrDelete = await this._projection.on(state, event, eventType, projectionContext);
const response = new Projections_pb_1.ProjectionResponse();
if (nextStateOrDelete instanceof DeleteReadModelInstance_1.DeleteReadModelInstance) {
response.setDelete(new Projections_pb_1.ProjectionDeleteResponse());
}
else {
const replace = new Projections_pb_1.ProjectionReplaceResponse();
replace.setState(JSON.stringify(nextStateOrDelete));
response.setReplace(replace);
}
return response;
}
}
exports.ProjectionProcessor = ProjectionProcessor;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJvamVjdGlvblByb2Nlc3Nvci5qcyIsInNvdXJjZVJvb3QiOiIuLi8iLCJzb3VyY2VzIjpbIkludGVybmFsL1Byb2plY3Rpb25Qcm9jZXNzb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxxR0FBcUc7OztBQUVyRyxpQ0FBaUM7QUFFakMsNkVBQTBFO0FBRzFFLHFEQUEyRjtBQUUzRiwyRUFBb0Y7QUFDcEYseURBQTZFO0FBRTdFLHlEQUErRjtBQUsvRixpR0FLc0U7QUFDdEUsK0VBQThGO0FBRTlGLHdFQUFxRTtBQUNyRSwwRUFBdUU7QUFDdkUsMEVBQXVFO0FBRXZFLGdDQUE2QjtBQUU3QixzRUFBbUU7QUFDbkUsNERBQXlEO0FBRXpELHNFQUFtRTtBQUNuRSw2REFBMEQ7QUFDMUQseUZBQXNGO0FBRXRGLDREQUF5RDtBQUN6RCwwRUFBdUU7QUFFdkU7OztHQUdHO0FBQ0gsTUFBYSxtQkFBdUIsU0FBUSxnQ0FBUSxDQUFDLGNBQXFKO0lBQ3RNOzs7O09BSUc7SUFDSCxZQUNZLFdBQTJCLEVBQzNCLFdBQXdCO1FBRWhDLEtBQUssQ0FBQyxZQUFZLEVBQUUsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBSHRDLGdCQUFXLEdBQVgsV0FBVyxDQUFnQjtRQUMzQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtJQUdwQyxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLElBQWMsaUJBQWlCO1FBQzNCLE1BQU0saUJBQWlCLEdBQUcsSUFBSSw4Q0FBNkIsRUFBRSxDQUFDO1FBQzlELGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxvQkFBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3pGLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxvQkFBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQy9FLGlC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