packageDocumentation module import { AccessToken , GuidString , Logger } from "@itwin/core-bentley" ; import { request , RequestOptions , Response } from "../itwin-client/Request" ; import { ECJsonTypeMap , WsgInstance } from "../wsg/ECJsonTypeMap" ; import { IModelHubClientLoggerCategory } from "../IModelHubClientLoggerCategories" ; import { IModelBaseHandler } from "./BaseHandler" ; import { ArgumentCheck } from "./Errors" ; import { BaseEventSAS , EventBaseHandler , EventListener , GetEventOperationToRequestType , IModelHubBaseEvent , ListenerSubscription , } from "./EventsBase" ; const loggerCategory = IModelHubClientLoggerCategory . IModelHub ; internal export type GlobalEventType = "SoftiModelDeleteEvent" | "HardiModelDeleteEvent" | "iModelCreatedEvent" | "ChangeSetCreatedEvent" | "NamedVersionCreatedEvent" | "CheckpointCreatedEvent" | "CheckpointV2CreatedEvent" ; internal export abstract class IModelHubGlobalEvent extends IModelHubBaseEvent { /** Id of the iModel that caused this event. */ public iModelId ? : GuidString ; /** Id of the [[Project]] that this iModel belongs to. */ public projectId ? : string ; /** Id of the iTwin that this iModel belongs to. */ public iTwinId ? : string ; param obj internal public override fromJson ( obj ) { super . fromJson ( obj ) ; this . iModelId = obj . iModelId ; this . projectId = obj . ProjectId ; this . iTwinId = obj . iTwinId ; } } internal export class SoftiModelDeleteEvent extends IModelHubGlobalEvent { } internal export class HardiModelDeleteEvent extends IModelHubGlobalEvent { } internal export class IModelCreatedEvent extends IModelHubGlobalEvent { } internal export class ChangeSetCreatedEvent extends IModelHubGlobalEvent { public changeSetId ? : string ; public changeSetIndex ? : string ; public briefcaseId ? : number ; param obj public override fromJson ( obj ) { super . fromJson ( obj ) ; this . changeSetId = obj . ChangeSetId ; this . changeSetIndex = obj . ChangeSetIndex ; this . briefcaseId = obj . BriefcaseId ; } } internal export class NamedVersionCreatedEvent extends IModelHubGlobalEvent { public versionId ? : GuidString ; public versionName ? : string ; public changeSetId ? : string ; param obj public override fromJson ( obj ) { super . fromJson ( obj ) ; this . versionId = obj . VersionId ; this . versionName = obj . VersionName ; this . changeSetId = obj . ChangeSetId ; } } internal export class GlobalCheckpointCreatedEvent extends IModelHubGlobalEvent { public changeSetIndex ? : string ; public changeSetId ? : string ; public versionId ? : GuidString ; param obj public override fromJson ( obj ) { super . fromJson ( obj ) ; this . changeSetIndex = obj . ChangeSetIndex ; this . changeSetId = obj . ChangeSetId ; this . versionId = obj . VersionId ; } } internal export class GlobalCheckpointV2CreatedEvent extends IModelHubGlobalEvent { public changeSetIndex ? : string ; public changeSetId ? : string ; public versionId ? : GuidString ; param obj public override fromJson ( obj ) { super . fromJson ( obj ) ; this . changeSetIndex = obj . ChangeSetIndex ; this . changeSetId = obj . ChangeSetId ; this . versionId = obj . VersionId ; } } type GlobalEventConstructor = ( new ( handler ? , sasToken ? ) => IModelHubGlobalEvent ) ; /** Get constructor from GlobalEventType name. */ function constructorFromEventType ( type ) { switch ( type ) { case "SoftiModelDeleteEvent" : return SoftiModelDeleteEvent ; case "HardiModelDeleteEvent" : return HardiModelDeleteEvent ; case "iModelCreatedEvent" : return IModelCreatedEvent ; case "ChangeSetCreatedEvent" : return ChangeSetCreatedEvent ; case "NamedVersionCreatedEvent" : return NamedVersionCreatedEvent ; case "CheckpointCreatedEvent" : return GlobalCheckpointCreatedEvent ; case "CheckpointV2CreatedEvent" : return GlobalCheckpointV2CreatedEvent ; } } param response returns internal export function ParseGlobalEvent ( response , handler ? , sasToken ? ) { const constructor = constructorFromEventType ( response . header [ "content-type" ] ) ; const globalEvent = new constructor ( handler , sasToken ) ; globalEvent . fromJson ( { ... response . header , ... response . body } ) ; return globalEvent ; } internal @ ECJsonTypeMap . classToJson ( "wsg" , "GlobalScope.GlobalEventSubscription" , { schemaPropertyName : "schemaName" , classPropertyName : "className" } ) export class GlobalEventSubscription extends WsgInstance { @ ECJsonTypeMap . propertyToJson ( "wsg" , "properties.EventTypes" ) public eventTypes ? : GlobalEventType [ ] ; @ ECJsonTypeMap . propertyToJson ( "wsg" , "properties.SubscriptionId" ) public subscriptionId ? : string ; } internal @ ECJsonTypeMap . classToJson ( "wsg" , "GlobalScope.GlobalEventSAS" , { schemaPropertyName : "schemaName" , classPropertyName : "className" } ) export class GlobalEventSAS extends BaseEventSAS { } internal export class GlobalEventSubscriptionHandler { private _handler : IModelBaseHandler ; param handler internal constructor ( handler ) { this . _handler = handler ; } param instanceId private getRelativeUrl ( instanceId ? ) { return `/Repositories/Global--Global/GlobalScope/GlobalEventSubscription/${ instanceId || "" }` ; } param subscriptionId param globalEvents return throws throws public async create ( accessToken , subscriptionId , globalEvents ) { Logger . logInfo ( loggerCategory , "Creating global event subscription" , ( ) => ( { subscriptionId } ) ) ; ArgumentCheck . validGuid ( "subscriptionId" , subscriptionId ) ; let subscription = new GlobalEventSubscription ( ) ; subscription . eventTypes = globalEvents ; subscription . subscriptionId = subscriptionId ; subscription = await this . _handler . postInstance < GlobalEventSubscription > ( accessToken , GlobalEventSubscription , this . getRelativeUrl ( ) , subscription ) ; Logger . logTrace ( loggerCategory , "Created global event subscription" , ( ) => ( { subscriptionId } ) ) ; return subscription ; } param subscription return throws throws public async update ( accessToken , subscription ) { Logger . logInfo ( loggerCategory , `Updating global event subscription with instance id: ${ subscription . wsgId }` , ( ) => ( { subscriptionId : subscription . subscriptionId } ) ) ; ArgumentCheck . defined ( "subscription" , subscription ) ; ArgumentCheck . validGuid ( "subscription.wsgId" , subscription . wsgId ) ; const updatedSubscription = await this . _handler . postInstance < GlobalEventSubscription > ( accessToken , GlobalEventSubscription , this . getRelativeUrl ( subscription . wsgId ) , subscription ) ; Logger . logTrace ( loggerCategory , `Updated global event subscription with instance id: ${ subscription . wsgId }` , ( ) => ( { subscriptionId : subscription . subscriptionId } ) ) ; return updatedSubscription ; } param subscriptionId returns throws throws public async delete ( accessToken , subscriptionId ) { Logger . logInfo ( loggerCategory , "Deleting global event subscription" , ( ) => ( { subscriptionId } ) ) ; ArgumentCheck . validGuid ( "subscriptionInstanceId" , subscriptionId ) ; await this . _handler . delete ( accessToken , this . getRelativeUrl ( subscriptionId ) ) ; Logger . logTrace ( loggerCategory , "Deleted global event subscription" , ( ) => ( { subscriptionId } ) ) ; } } internal export enum GetEventOperationType { /** Event will be immediately removed from queue. */ Destructive = 0 , /** Event will be locked instead of removed. It has to be later removed via [[IModelHubBaseEvent.delete]]. */ Peek } internal export class GlobalEventHandler extends EventBaseHandler { private _subscriptionHandler : GlobalEventSubscriptionHandler | undefined ; param handler internal constructor ( handler ) { super ( ) ; this . _handler = handler ; } /** Get a handler for managing [[GlobalEventSubscription]]s. */ public get subscriptions ( ) : GlobalEventSubscriptionHandler { if ( ! this . _subscriptionHandler ) { this . _subscriptionHandler = new GlobalEventSubscriptionHandler ( this . _handler ) ; } return this . _subscriptionHandler ; } /** Get relative url for GlobalEventSAS requests. */ private getGlobalEventSASRelativeUrl ( ) { return `/Repositories/Global--Global/GlobalScope/GlobalEventSAS/` ; } throws public async getSASToken ( accessToken ) { Logger . logInfo ( loggerCategory , "Getting global event SAS token" ) ; const globalEventSAS = await this . _handler . postInstance < GlobalEventSAS > ( accessToken , GlobalEventSAS , this . getGlobalEventSASRelativeUrl ( ) , new GlobalEventSAS ( ) ) ; Logger . logTrace ( loggerCategory , "Got global event SAS token" ) ; return globalEventSAS ; } param baseAddress param subscriptionId param timeout private getGlobalEventUrl ( baseAddress , subscriptionId , timeout ? ) { let url = `${ baseAddress }/Subscriptions/${ subscriptionId }/messages/head` ; if ( timeout ) { url = `${ url }?timeout=${ timeout }` ; } return url ; } param sasToken param baseAddress param subscriptionId param timeout return throws throws public async getEvent ( sasToken , baseAddress , subscriptionId , timeout ? , getOperation = GetEventOperationType . Destructive ) { Logger . logInfo ( loggerCategory , "Getting global event from subscription" , ( ) => ( { subscriptionId } ) ) ; ArgumentCheck . defined ( "sasToken" , sasToken ) ; ArgumentCheck . defined ( "baseAddress" , baseAddress ) ; ArgumentCheck . defined ( "subscriptionInstanceId" , subscriptionId ) ; let options ; if ( getOperation === GetEventOperationType . Destructive ) options = await this . getEventRequestOptions ( GetEventOperationToRequestType . GetDestructive , sasToken , timeout ) ; else if ( getOperation === GetEventOperationType . Peek ) options = await this . getEventRequestOptions ( GetEventOperationToRequestType . GetPeek , sasToken , timeout ) ; else return undefined ; const result = await request ( this . getGlobalEventUrl ( baseAddress , subscriptionId , timeout ) , options ) ; if ( result . status === 204 ) { Logger . logTrace ( loggerCategory , "No events found on subscription" , ( ) => ( { subscriptionId } ) ) ; return undefined ; } const event = ParseGlobalEvent ( result , this . _handler , sasToken ) ; Logger . logTrace ( loggerCategory , "Got Global Event from subscription" , ( ) => ( { subscriptionId } ) ) ; return event ; } param authenticationCallback param subscriptionInstanceId param listener returns throws public createListener ( authenticationCallback , subscriptionInstanceId , listener ) { ArgumentCheck . defined ( "subscriptionInstanceId" , subscriptionInstanceId ) ; const subscription = new ListenerSubscription ( ) ; subscription . authenticationCallback = authenticationCallback ; subscription . getEvent = async ( sasToken , baseAddress , id , timeout ? ) => this . getEvent ( sasToken , baseAddress , id , timeout ) ; subscription . getSASToken = async ( token ) => this . getSASToken ( token ) ; subscription . id = subscriptionInstanceId ; return EventListener . create ( subscription , listener ) ; } }