UNPKG

@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
"use strict"; // 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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