module Sfx { export interface IDataModelCollection < T extends IDataModel < any > > { collection : T [ ] ; length : number ; isInitialized : boolean ; isRefreshing : boolean ; viewPath : string ; find ( uniqueId ) : T ; refresh ( messageHandler ? ) : angular . IPromise < any > ; ensureInitialized ( forceRefresh ? , messageHandler ? ) : angular . IPromise < any > ; mergeClusterHealthStateChunk ( clusterHealthChunk ) : angular . IPromise < any > ; } export class CancelablePromise < T > { private defer : angular . IDeferred < T > = null ; public constructor ( private $q ) { } public load ( loadHandler ) { if ( this . hasPromise ( ) ) { this . cancel ( ) ; } this . defer = this . $q . defer < T > ( ) ; this . executeInternal ( loadHandler ) ; return this . getPromise ( ) ; } public hasPromise ( ) { return this . defer !== null ; } public getPromise ( ) { if ( ! this . hasPromise ( ) ) { return null ; } return this . defer . promise ; } public cancel ( ) { if ( this . hasPromise ( ) ) { this . defer . reject ( { isCanceled : true } ) ; this . defer = null ; } } private executeInternal ( loadHandler ) { let capturedDefer = this . defer ; loadHandler ( ) . then ( result => { if ( this . defer === capturedDefer ) { this . defer . resolve ( result ) ; } } ) . catch ( ( rejected ) => { if ( this . defer === capturedDefer ) { this . defer . reject ( rejected ) ; } } ) . finally ( ( ) => { if ( this . defer === capturedDefer ) { this . defer = null ; } } ) ; } } export class DataModelCollectionBase < T extends IDataModel < any > > implements IDataModelCollection < T > { public isInitialized : boolean = false ; public parent : any ; public collection : T [ ] = [ ] ; protected valueResolver : ValueResolver = new ValueResolver ( ) ; private appendOnly : boolean ; private hash : _ . Dictionary < T > ; private refreshingLoadPromise : CancelablePromise < T [ ] > ; private refreshingPromise : angular . IPromise < any > ; public get viewPath ( ) : string { return "" ; } public get length ( ) : number { return this . collection . length ; } public get isRefreshing ( ) : boolean { return ! ! this . refreshingPromise ; } protected get indexPropery ( ) : string { return "uniqueId" ; } public constructor ( public data , parent ? , appendOnly = false ) { this . parent = parent ; this . appendOnly = appendOnly ; this . refreshingLoadPromise = new CancelablePromise ( this . data . $q ) ; } public refresh ( messageHandler ? ) { if ( ! this . refreshingPromise ) { this . refreshingPromise = this . refreshingLoadPromise . load ( ( ) => { return this . retrieveNewCollection ( messageHandler ) ; } ) . catch ( ( error ) => { if ( error && error . isCanceled !== true ) { throw error ; } return this . data . $q . when ( null ) ; } ) . then ( collection => { if ( collection ) { return this . update ( collection ) ; } } ) . then ( ( ) => { return this ; } ) . finally ( ( ) => { this . refreshingPromise = null ; } ) ; } return this . refreshingPromise ; } public clear ( ) { this . cancelLoad ( ) ; return this . data . $q . when ( this . refreshingPromise ? this . refreshingPromise : true ) . then ( ( ) => { this . collection = [ ] ; this . isInitialized = false ; } ) ; } protected cancelLoad ( ) { if ( this . refreshingLoadPromise . hasPromise ( ) ) { this . refreshingLoadPromise . cancel ( ) ; } } protected update ( collection ) { this . isInitialized = true ; CollectionUtils . updateDataModelCollection ( this . collection , collection , this . appendOnly ) ; this . hash = _ . keyBy ( this . collection , this . indexPropery ) ; return this . data . $q . when ( this . updateInternal ( ) ) ; } public ensureInitialized ( forceRefresh ? , messageHandler ? ) { if ( ! this . isInitialized || forceRefresh ) { return this . refresh ( messageHandler ) ; } return this . data . $q . when ( this ) ; } public find ( uniqueId ) { if ( this . hash ) { return this . hash [ uniqueId ] ; } return null ; } public mergeClusterHealthStateChunk ( clusterHealthChunk ) { return this . data . $q . when ( true ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . $q . reject ( ) ; } protected updateInternal ( ) { return this . data . $q . when ( true ) ; } protected updateCollectionFromHealthChunkList < P extends IHealthStateChunk > ( healthChunkList , newIdSelector ) { if ( ! CollectionUtils . compareCollectionsByKeys ( this . collection , healthChunkList . Items , item => item [ this . indexPropery ] , newIdSelector ) ) { if ( ! this . isRefreshing ) { return this . refresh ( ) ; } else { return this . data . $q . when ( true ) ; } } let updatePromises = [ ] ; CollectionUtils . updateCollection < T , P > ( this . collection , healthChunkList . Items , item => item [ this . indexPropery ] , newIdSelector , null , ( item , newItem ) => { updatePromises . push ( item . mergeHealthStateChunk ( newItem ) ) ; } ) ; return this . data . $q . all ( updatePromises ) ; } protected getDetailsList ( item ) { return null ; } } export class NodeCollection extends DataModelCollectionBase < Node > { private static checkedOneNodeScenario = false ; public healthState : ITextAndBadge ; public upgradeDomains : string [ ] ; public faultDomains : string [ ] ; public healthySeedNodes : string ; public disabledNodes : string ; public seedNodeCount : number ; public constructor ( data ) { super ( data ) ; } public get viewPath ( ) : string { return this . data . routes . getNodesViewPath ( ) ; } public mergeClusterHealthStateChunk ( clusterHealthChunk ) { return this . updateCollectionFromHealthChunkList ( clusterHealthChunk . NodeHealthStateChunks , item => IdGenerator . node ( item . NodeName ) ) . then ( ( ) => { this . updateNodesHealthState ( ) ; } ) ; } public getNodeStateCounts ( ) { let counts = { } ; let allNodes = new NodeStatusDetails ( "All nodes" ) ; let seedNodes = new NodeStatusDetails ( "Seed Nodes" ) ; this . collection . forEach ( node => { if ( node . raw . IsSeedNode ) { seedNodes . add ( node ) ; } if ( ! ( node . raw . Type in counts ) ) { counts [ node . raw . Type ] = new NodeStatusDetails ( node . raw . Type ) ; } counts [ node . raw . Type ] . add ( node ) ; allNodes . add ( node ) ; } ) ; return [ allNodes , seedNodes ] . concat ( Object . keys ( counts ) . map ( key => counts [ key ] ) ) ; } public setAdvancedMode ( state ) { this . collection . forEach ( node => { node . removeAdvancedActions ( ) ; if ( state ) { node . setAdvancedActions ( ) ; } } ) ; } protected get indexPropery ( ) : string { return "name" ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getNodes ( messageHandler ) . then ( items => { return _ . map ( items , raw => new Node ( this . data , raw ) ) ; } ) ; } protected updateInternal ( ) { this . updateNodesHealthState ( ) ; this . faultDomains = _ . map ( this . collection , node => node . raw . FaultDomain ) ; this . faultDomains = _ . uniq ( this . faultDomains ) . sort ( ) ; this . upgradeDomains = _ . map ( this . collection , node => node . raw . UpgradeDomain ) ; this . upgradeDomains = _ . uniq ( this . upgradeDomains ) . sort ( ) ; let seedNodes = _ . filter ( this . collection , node => node . raw . IsSeedNode ) ; let healthyNodes = _ . filter ( seedNodes , node => node . healthState . text === HealthStateConstants . OK ) ; let disabledNodes = 0 ; let disablingNodes = 0 ; this . collection . forEach ( node => { if ( node . raw . NodeStatus === NodeStatusConstants . Disabled ) { disabledNodes ++ ; } if ( node . raw . NodeStatus === NodeStatusConstants . Disabling ) { disablingNodes ++ ; } } ) ; this . disabledNodes = `${ disabledNodes }/${ disablingNodes }` ; this . seedNodeCount = seedNodes . length ; this . checkOneNodeScenario ( ) ; this . healthySeedNodes = seedNodes . length . toString ( ) + " (" + Math . round ( healthyNodes . length / seedNodes . length * 100 ) . toString ( ) + "%)" ; } public checkSeedNodeCount ( expected ) { if ( this . seedNodeCount < expected && this . seedNodeCount !== 1 ) { this . data . warnings . addOrUpdateNotification ( { message : `This cluster is currently running on the bronze reliability tier. For production workloads, only a reliability level of silver or greater is supported 
                    <br>See <a href="https://aka.ms/servicefabric/reliability" target="_black">( link )</a> for more details` , level : StatusWarningLevel . Warning , priority : 2 , id : BannerWarningID . ClusterDegradedState , confirmText : `This cluster is currently running on the bronze reliability tier which indicates a test/staging environment. For production workloads, only a reliability
                    level of silver or greater is supported. For more information on the reliability characteristics of a cluster, please see https://aka.ms/sfreliabilitytiers` } ) ; } else { this . data . warnings . removeNotificationById ( BannerWarningID . ClusterDegradedState ) ; } } private checkOneNodeScenario ( ) { if ( ! NodeCollection . checkedOneNodeScenario && this . collection . length === 1 ) { this . data . warnings . addOrUpdateNotification ( { message : "One node cluster is considered a test cluster and cannot perform cluster upgrades." , level : StatusWarningLevel . Info , priority : 1 , id : BannerWarningID . OneNodeCluster , link : "https://aka.ms/servicefabric/durability" } ) ; } NodeCollection . checkedOneNodeScenario = true ; } private updateNodesHealthState ( ) { this . healthState = this . valueResolver . resolveHealthStatus ( _ . max ( _ . map ( this . collection , node => HealthStateConstants . Values [ node . healthState . text ] ) ) ) ; } } export class BackupPolicyCollection extends DataModelCollectionBase < BackupPolicy > { protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getBackupPolicies ( messageHandler ) . then ( items => { return _ . map ( items , raw => new BackupPolicy ( this . data , raw ) ) ; } ) ; } } export class NetworkCollection extends DataModelCollectionBase < Network > { public constructor ( data ) { super ( data ) ; } public get viewPath ( ) : string { return this . data . routes . getNetworksViewPath ( ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getNetworks ( messageHandler ) . then ( items => { return _ . map ( items , raw => new Network ( this . data , raw ) ) ; } ) ; } } export class NetworkOnAppCollection extends DataModelCollectionBase < NetworkOnApp > { appId : string ; public constructor ( data , appId ) { super ( data ) ; this . appId = appId ; } protected retrieveNewCollection ( messageHandler ? ) { let collection = [ ] ; return this . data . restClient . getNetworksOnApp ( this . appId , messageHandler ) . then ( items => { let tasks = _ . map ( items , raw => { let network = new NetworkOnApp ( this . data , raw ) ; return network . refresh ( ) . then ( ( ) => collection . push ( network ) ) ; } ) ; return this . data . $q . all ( tasks ) . then ( ( ) => collection ) ; } ) ; } } export class NetworkOnNodeCollection extends DataModelCollectionBase < NetworkOnNode > { nodeName : string ; public constructor ( data , nodeName ) { super ( data ) ; this . nodeName = nodeName ; } protected retrieveNewCollection ( messageHandler ? ) { let collection = [ ] ; return this . data . restClient . getNetworksOnNode ( this . nodeName , messageHandler ) . then ( items => { let filtered = _ . filter ( items , item => { return item . NetworkName !== "servicefabric_network" ; } ) ; let tasks = _ . map ( filtered , raw => { let network = new NetworkOnNode ( this . data , raw ) ; return network . refresh ( ) . then ( ( ) => collection . push ( network ) ) ; } ) ; return this . data . $q . all ( tasks ) . then ( ( ) => collection ) ; } ) ; } } export class AppOnNetworkCollection extends DataModelCollectionBase < AppOnNetwork > { networkName : string ; public constructor ( data , networkName ) { super ( data ) ; this . networkName = networkName ; } protected retrieveNewCollection ( messageHandler ? ) { let collection = [ ] ; return this . data . restClient . getAppsOnNetwork ( this . networkName , messageHandler ) . then ( items => { let tasks = _ . map ( items , raw => { let application = new AppOnNetwork ( this . data , raw ) ; return application . refresh ( ) . then ( ( ) => collection . push ( application ) ) ; } ) ; return this . data . $q . all ( tasks ) . then ( ( ) => collection ) ; } ) ; } } export class NodeOnNetworkCollection extends DataModelCollectionBase < NodeOnNetwork > { networkName : string ; public constructor ( data , networkName ) { super ( data ) ; this . networkName = networkName ; } protected retrieveNewCollection ( messageHandler ? ) { let collection = [ ] ; return this . data . restClient . getNodesOnNetwork ( this . networkName , messageHandler ) . then ( items => { let tasks = _ . map ( items , raw => { let node = new NodeOnNetwork ( this . data , raw ) ; return node . refresh ( ) . then ( ( ) => { collection . push ( node ) ; } ) ; } ) ; return this . data . $q . all ( tasks ) . then ( ( ) => collection ) ; } ) ; } } export class DeployedContainerOnNetworkCollection extends DataModelCollectionBase < DeployedContainerOnNetwork > { networkName : string ; public constructor ( data , networkName ) { super ( data ) ; this . networkName = networkName ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getNodesOnNetwork ( this . networkName , messageHandler ) . then ( items => { let result = new Array ( ) ; let promises = [ ] ; _ . each ( items , raw => { promises . push ( this . data . restClient . getDeployedContainersOnNetwork ( this . networkName , raw . nodeName , messageHandler ) . then ( values => { _ . each ( values , value => { result . push ( new DeployedContainerOnNetwork ( this . data , raw . nodeName , value ) ) ; } ) ; } ) ) ; } ) ; return this . data . $q . all ( promises ) . then ( values => { return result ; } ) ; } ) ; } } export class ApplicationCollection extends DataModelCollectionBase < Application > { public upgradingAppCount : number = 0 ; public healthState : ITextAndBadge ; public constructor ( data ) { super ( data ) ; } public get viewPath ( ) : string { return this . data . routes . getAppsViewPath ( ) ; } public mergeClusterHealthStateChunk ( clusterHealthChunk ) { return this . updateCollectionFromHealthChunkList ( clusterHealthChunk . ApplicationHealthStateChunks , item => IdGenerator . app ( IdUtils . nameToId ( item . ApplicationName ) ) ) . then ( ( ) => { this . updateAppsHealthState ( ) ; return this . refreshAppTypeGroups ( ) ; } ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getApplications ( messageHandler ) . then ( items => { return _ . map ( items , raw => new Application ( this . data , raw ) ) ; } ) ; } protected updateInternal ( ) { this . upgradingAppCount = _ . filter ( this . collection , ( app ) => app . isUpgrading ) . length ; this . updateAppsHealthState ( ) ; return this . refreshAppTypeGroups ( ) ; } private updateAppsHealthState ( ) { this . healthState = this . length > 0 ? this . valueResolver . resolveHealthStatus ( _ . max ( _ . map ( this . collection , app => HealthStateConstants . Values [ app . healthState . text ] ) ) ) : ValueResolver . healthStatuses [ 1 ] ; } private refreshAppTypeGroups ( ) { return this . data . getAppTypeGroups ( false ) . then ( appTypeGroups => { _ . each ( appTypeGroups . collection , appTypeGroup => appTypeGroup . refreshAppTypeApps ( this ) ) ; } ) ; } } export class ApplicationTypeGroupCollection extends DataModelCollectionBase < ApplicationTypeGroup > { public constructor ( data ) { super ( data ) ; } public get viewPath ( ) : string { return this . data . routes . getAppTypesViewPath ( ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getApplicationTypes ( null , messageHandler ) . then ( response => { let appTypes = _ . map ( response . data , item => new ApplicationType ( this . data , item ) ) ; let groups = _ . groupBy ( appTypes , item => item . raw . Name ) ; return _ . map ( groups , g => new ApplicationTypeGroup ( this . data , g ) ) ; } ) ; } } export class ApplicationBackupConfigurationInfoCollection extends DataModelCollectionBase < ApplicationBackupConfigurationInfo > { public constructor ( data , public parent ) { super ( data , parent ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getApplicationBackupConfigurationInfoCollection ( this . parent . id , messageHandler ) . then ( items => { return _ . map ( items , raw => new ApplicationBackupConfigurationInfo ( this . data , raw , this . parent ) ) ; } ) ; } } export class ServiceBackupConfigurationInfoCollection extends DataModelCollectionBase < ServiceBackupConfigurationInfo > { public constructor ( data , public parent ) { super ( data , parent ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getServiceBackupConfigurationInfoCollection ( this . parent . id , messageHandler ) . then ( items => { return _ . map ( items , raw => new ServiceBackupConfigurationInfo ( this . data , raw , this . parent ) ) ; } ) ; } } export class PartitionBackupCollection extends DataModelCollectionBase < PartitionBackup > { public startDate : Date ; public endDate : Date ; public constructor ( data , public parent ) { super ( data , parent ) ; this . startDate = null ; this . endDate = null ; } public retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getPartitionBackupList ( this . parent . parent . id , messageHandler , this . startDate , this . endDate ) . then ( items => { return _ . map ( items , raw => new PartitionBackup ( this . data , raw , this . parent ) ) ; } ) ; } } export class SinglePartitionBackupCollection extends DataModelCollectionBase < PartitionBackup > { public constructor ( data , public parent ) { super ( data , parent ) ; } public retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getLatestPartitionBackup ( this . parent . parent . id , messageHandler ) . then ( items => { return _ . map ( items , raw => new PartitionBackup ( this . data , raw , this . parent ) ) ; } ) ; } } export class ServiceTypeCollection extends DataModelCollectionBase < ServiceType > { public constructor ( data , public parent ) { super ( data , parent ) ; } protected retrieveNewCollection ( messageHandler ? ) { let appTypeName = null ; let appTypeVersion = null ; if ( this . parent instanceof ApplicationType ) { appTypeName = ( < ApplicationType > ( this . parent ) ) . raw . Name ; appTypeVersion = ( < ApplicationType > ( this . parent ) ) . raw . Version ; } else { appTypeName = ( < Application > ( this . parent ) ) . raw . TypeName ; appTypeVersion = ( < Application > ( this . parent ) ) . raw . TypeVersion ; } return this . data . restClient . getServiceTypes ( appTypeName , appTypeVersion , messageHandler ) . then ( response => { return _ . map ( response . data , raw => new ServiceType ( this . data , raw , this . parent ) ) ; } ) ; } } export class ServiceCollection extends DataModelCollectionBase < Service > { public constructor ( data , public parent ) { super ( data , parent ) ; } public mergeClusterHealthStateChunk ( clusterHealthChunk ) { let serviceHealthStateChunks = null ; if ( this . parent . name === Constants . SystemAppName ) { serviceHealthStateChunks = clusterHealthChunk . SystemApplicationHealthStateChunk . ServiceHealthStateChunks ; } else { let appHealthChunk = _ . find ( clusterHealthChunk . ApplicationHealthStateChunks . Items , item => item . ApplicationName === this . parent . name ) ; if ( appHealthChunk ) { serviceHealthStateChunks = appHealthChunk . ServiceHealthStateChunks ; } } if ( serviceHealthStateChunks ) { return this . updateCollectionFromHealthChunkList < IServiceHealthStateChunk > ( serviceHealthStateChunks , item => IdGenerator . service ( IdUtils . nameToId ( item . ServiceName ) ) ) ; } return this . data . $q . when ( true ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getServices ( this . parent . id , messageHandler ) . then ( items => { return _ . map ( items , raw => new Service ( this . data , raw , this . parent ) ) ; } ) ; } } export class PartitionCollection extends DataModelCollectionBase < Partition > { public constructor ( data , public parent ) { super ( data , parent ) ; } public mergeClusterHealthStateChunk ( clusterHealthChunk ) { let appHealthChunk = _ . find ( clusterHealthChunk . ApplicationHealthStateChunks . Items , item => item . ApplicationName === this . parent . parent . name ) ; if ( appHealthChunk ) { let serviceHealthChunk = _ . find ( appHealthChunk . ServiceHealthStateChunks . Items , item => item . ServiceName === this . parent . name ) ; if ( serviceHealthChunk ) { return this . updateCollectionFromHealthChunkList ( serviceHealthChunk . PartitionHealthStateChunks , item => IdGenerator . partition ( item . PartitionId ) ) ; } } return this . data . $q . when ( true ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getPartitions ( this . parent . parent . id , this . parent . id , messageHandler ) . then ( items => { return _ . map ( items , raw => new Partition ( this . data , raw , this . parent ) ) ; } ) ; } } export class ReplicaOnPartitionCollection extends DataModelCollectionBase < ReplicaOnPartition > { public constructor ( data , public parent ) { super ( data , parent ) ; } public get isStatefulService ( ) : boolean { return this . parent . parent . isStatefulService ; } public get isStatelessService ( ) : boolean { return this . parent . isStatelessService ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getReplicasOnPartition ( this . parent . parent . parent . id , this . parent . parent . id , this . parent . id , messageHandler ) . then ( items => { return _ . map ( items , raw => new ReplicaOnPartition ( this . data , raw , this . parent ) ) ; } ) ; } } export class DeployedApplicationCollection extends DataModelCollectionBase < DeployedApplication > { public constructor ( data , public parent ) { super ( data , parent ) ; } public mergeClusterHealthStateChunk ( clusterHealthChunk ) { let nodeHealthChunk = _ . find ( clusterHealthChunk . NodeHealthStateChunks . Items , chunk => chunk . NodeName === this . parent . name ) ; if ( nodeHealthChunk ) { return this . updateCollectionFromHealthChunkList < IDeployedApplicationHealthStateChunk > ( nodeHealthChunk . DeployedApplicationHealthStateChunks , item => IdGenerator . deployedApp ( IdUtils . nameToId ( item . ApplicationName ) ) ) ; } } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getDeployedApplications ( this . parent . name , messageHandler ) . then ( ( raw ) => { let rawApps = raw . data ; return _ . map ( rawApps , rawApp => new DeployedApplication ( this . data , rawApp , this . parent ) ) ; } ) ; } protected updateInternal ( ) { if ( this . length > 0 ) { let healthChunkQueryDescription = this . data . getInitialClusterHealthChunkQueryDescription ( ) ; this . parent . addHealthStateFiltersForChildren ( healthChunkQueryDescription ) ; return this . data . getClusterHealthChunk ( healthChunkQueryDescription ) . then ( healthChunk => { return this . mergeClusterHealthStateChunk ( healthChunk ) ; } ) ; } } } export class DeployedServicePackageCollection extends DataModelCollectionBase < DeployedServicePackage > { public constructor ( data , public parent ) { super ( data , parent ) ; } public mergeClusterHealthStateChunk ( clusterHealthChunk ) { let appHealthChunk = _ . find ( clusterHealthChunk . ApplicationHealthStateChunks . Items , item => item . ApplicationName === this . parent . name ) ; if ( appHealthChunk ) { let deployedAppHealthChunk = _ . find ( appHealthChunk . DeployedApplicationHealthStateChunks . Items , deployedAppHealthChunk => deployedAppHealthChunk . NodeName === this . parent . parent . name ) ; if ( deployedAppHealthChunk ) { return this . updateCollectionFromHealthChunkList < IDeployedServicePackageHealthStateChunk > ( deployedAppHealthChunk . DeployedServicePackageHealthStateChunks , item => IdGenerator . deployedServicePackage ( item . ServiceManifestName , item . ServicePackageActivationId ) ) ; } } return this . data . $q . when ( true ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getDeployedServicePackages ( this . parent . parent . name , this . parent . id , messageHandler ) . then ( ( raw ) => { let rawServicePackages = raw . data ; return _ . map ( rawServicePackages , rawServicePackage => new DeployedServicePackage ( this . data , rawServicePackage , this . parent ) ) ; } ) ; } protected updateInternal ( ) { if ( this . length > 0 ) { let healthChunkQueryDescription = this . data . getInitialClusterHealthChunkQueryDescription ( ) ; this . parent . addHealthStateFiltersForChildren ( healthChunkQueryDescription ) ; return this . data . getClusterHealthChunk ( healthChunkQueryDescription ) . then ( healthChunk => { return this . mergeClusterHealthStateChunk ( healthChunk ) ; } ) ; } } } export class DeployedCodePackageCollection extends DataModelCollectionBase < DeployedCodePackage > { public constructor ( data , public parent ) { super ( data , parent ) ; } public get viewPath ( ) : string { return this . data . routes . getDeployedCodePackagesViewPath ( this . parent . parent . parent . name , this . parent . parent . id , this . parent . id , this . parent . servicePackageActivationId ) ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getDeployedCodePackages ( this . parent . parent . parent . name , this . parent . parent . id , this . parent . name , messageHandler ) . then ( response => { return _ . map ( _ . filter ( response . data , raw => raw . ServicePackageActivationId === this . parent . servicePackageActivationId ) , raw => new DeployedCodePackage ( this . data , raw , this . parent ) ) ; } ) ; } } export class DeployedReplicaCollection extends DataModelCollectionBase < DeployedReplica > { public constructor ( data , public parent ) { super ( data , parent ) ; } public get viewPath ( ) : string { return this . data . routes . getDeployedReplicasViewPath ( this . parent . parent . parent . name , this . parent . parent . id , this . parent . id , this . parent . servicePackageActivationId ) ; } public get isStatefulService ( ) : boolean { return this . length > 0 && _ . first ( this . collection ) . isStatefulService ; } public get isStatelessService ( ) : boolean { return this . length > 0 && _ . first ( this . collection ) . isStatelessService ; } protected retrieveNewCollection ( messageHandler ? ) { return this . data . restClient . getDeployedReplicas ( this . parent . parent . parent . name , this . parent . parent . id , this . parent . name , messageHandler ) . then ( response => { return _ . map ( _ . filter ( response . data , raw => raw . ServicePackageActivationId === this . parent . servicePackageActivationId ) , raw => new DeployedReplica ( this . data , raw , this . parent ) ) ; } ) ; } } export abstract class EventListBase < T extends FabricEventBase > extends DataModelCollectionBase < FabricEventInstanceModel < T > > { public readonly settings : ListSettings ; public readonly detailsSettings : ListSettings ; public readonly minimumRefreshTimeInSecs : number = 10 ; public readonly pageSize : number = 15 ; public readonly defaultDateWindowInDays : number = 7 ; public readonly latestRefreshPeriodInSecs : number = 60 * 60 ; protected readonly optionalColsStartIndex : number = 2 ; private lastRefreshTime ? : Date ; private _startDate : Date ; private _endDate : Date ; public get startDate ( ) { return new Date ( this . _startDate . valueOf ( ) ) ; } public get endDate ( ) { let endDate = new Date ( this . _endDate . valueOf ( ) ) ; let timeNow = new Date ( ) ; if ( endDate > timeNow ) { endDate = timeNow ; } return endDate ; } public get queryStartDate ( ) { if ( this . isInitialized ) { if ( ( this . endDate . getTime ( ) - this . startDate . getTime ( ) ) / 1000 > this . latestRefreshPeriodInSecs ) { return TimeUtils . AddSeconds ( this . endDate , ( - 1 * this . latestRefreshPeriodInSecs ) ) ; } } return this . startDate ; } public get queryEndDate ( ) { return this . endDate ; } public constructor ( data , startDate ? , endDate ? ) { super ( data , null , true ) ; this . settings = this . createListSettings ( ) ; this . detailsSettings = this . createListSettings ( ) ; let correlatedEventsCol = new ListColumnSetting ( "#CorrelatedEvents" , "" , [ ] , null , ( item ) => HtmlUtils . getEventDetailsViewLinkHtml ( item . raw ) ) ; correlatedEventsCol . fixedWidthPx = 40 ; this . settings . columnSettings . splice ( 1 , 0 , correlatedEventsCol ) ; this . setNewDateWindowInternal ( startDate , endDate ) ; } public setDateWindow ( startDate ? , endDate ? ) { return this . setNewDateWindowInternal ( startDate , endDate ) ; } public resetDateWindow ( ) { return this . setDateWindow ( null , null ) ; } public reload ( messageHandler ? ) { this . lastRefreshTime = null ; return this . clear ( ) . then ( ( ) => { return this . refresh ( messageHandler ) ; } ) ; } protected retrieveNewCollection ( messageHandler ? ) { if ( this . lastRefreshTime && ( new Date ( ) . getTime ( ) - this . lastRefreshTime . getTime ( ) ) < ( this . minimumRefreshTimeInSecs * 1000 ) ) { return this . data . $q . when ( this . collection ) ; } this . lastRefreshTime = new Date ( ) ; return this . retrieveEvents ( messageHandler ) ; } protected getDetailsList ( item ) { return this . data . createCorrelatedEventList ( item . raw . eventInstanceId ) ; } protected retrieveEvents ( messageHandler ? ) { return this . data . $q . when ( [ ] ) ; } private createListSettings ( ) { let listSettings = new ListSettings ( this . pageSize , [ "raw.timeStamp" ] , [ new ListColumnSetting ( "raw.kind" , "Type" , [ "raw.kind" ] , true , ( item ) => HtmlUtils . getEventNameHtml ( item . raw ) ) , new ListColumnSetting ( "raw.category" , "Event Category" , [ "raw.category" ] , true , ( item ) => ( ! item . raw . category ? "Operational" : item . raw . category ) ) , new ListColumnSetting ( "raw.timeStampString" , "Timestamp" ) , ] , [ new ListColumnSetting ( "raw.eventInstanceId" , "" , [ ] , null , ( item ) => HtmlUtils . getEventSecondRowHtml ( item . raw ) , - 1 ) , ] , true , ( item ) => ( Object . keys ( item . raw . eventProperties ) . length > 0 ) , true ) ; listSettings . columnSettings [ 0 ] . fixedWidthPx = 320 ; listSettings . columnSettings [ 1 ] . fixedWidthPx = 200 ; listSettings . sortReverse = true ; return listSettings ; } private setNewDateWindowInternal ( startDate ? , endDate ? ) { if ( ! startDate ) { startDate = TimeUtils . AddDays ( endDate ? endDate : new Date ( ) , ( - 1 * this . defaultDateWindowInDays ) ) ; } if ( ! endDate ) { endDate = TimeUtils . AddDays ( startDate , this . defaultDateWindowInDays ) ; } if ( ! this . _startDate || this . _startDate . getTime ( ) !== startDate . getTime ( ) || ! this . _endDate || this . _endDate . getTime ( ) !== endDate . getTime ( ) ) { this . _startDate = startDate ; this . _endDate = endDate ; return true ; } return false ; } } export class ClusterEventList extends EventListBase < ClusterEvent > { public constructor ( data , partitionId ? ) { super ( data ) ; } protected retrieveEvents ( messageHandler ? ) { return this . data . restClient . getClusterEvents ( this . queryStartDate , this . queryEndDate , messageHandler ) . then ( result => { return result . map ( event => new FabricEventInstanceModel < ClusterEvent > ( this . data , event ) ) ; } ) ; } } export class NodeEventList extends EventListBase < NodeEvent > { private nodeName ? : string ; public constructor ( data , nodeName ? ) { super ( data ) ; this . nodeName = nodeName ; if ( ! this . nodeName ) { this . settings . columnSettings . splice ( this . optionalColsStartIndex , 0 , new ListColumnSettingWithFilter ( "raw.nodeName" , "Node Name" ) ) ; } } protected retrieveEvents ( messageHandler ? ) { return this . data . restClient . getNodeEvents ( this . queryStartDate , this . queryEndDate , this . nodeName , messageHandler ) . then ( result => { return result . map ( event => new FabricEventInstanceModel < NodeEvent > ( this . data , event ) ) ; } ) ; } } export class ApplicationEventList extends EventListBase < ApplicationEvent > { private applicationId ? : string ; public constructor ( data , applicationId ? ) { super ( data ) ; if ( applicationId ) { this . applicationId = applicationId . replace ( new RegExp ( "/" , "g" ) , "~" ) ; } if ( ! this . applicationId ) { this . settings . columnSettings . splice ( this . optionalColsStartIndex , 0 , new ListColumnSettingWithFilter ( "raw.applicationId" , "Application Id" ) ) ; } } protected retrieveEvents ( messageHandler ? ) { return this . data . restClient . getApplicationEvents ( this . queryStartDate , this . queryEndDate , this . applicationId , messageHandler ) . then ( result => { return result . map ( event => new FabricEventInstanceModel < ApplicationEvent > ( this . data , event ) ) ; } ) ; } } export class ServiceEventList extends EventListBase < ServiceEvent > { private serviceId ? : string ; public constructor ( data , serviceId ? ) { super ( data ) ; if ( serviceId ) { this . serviceId = serviceId . replace ( new RegExp ( "/" , "g" ) , "~" ) ; } if ( ! this . serviceId ) { this . settings . columnSettings . splice ( this . optionalColsStartIndex , 0 , new ListColumnSettingWithFilter ( "raw.serviceId" , "Service Id" ) ) ; } } protected retrieveEvents ( messageHandler ? ) { return this . data . restClient . getServiceEvents ( this . queryStartDate , this . queryEndDate , this . serviceId , messageHandler ) . then ( result => { return result . map ( event => new FabricEventInstanceModel < ServiceEvent > ( this . data , event ) ) ; } ) ; } } export class PartitionEventList extends EventListBase < PartitionEvent > { private partitionId ? : string ; public constructor ( data , partitionId ? ) { super ( data ) ; this . partitionId = partitionId ; if ( ! this . partitionId ) { this . settings . columnSettings . splice ( this . optionalColsStartIndex , 0 , new ListColumnSettingWithFilter ( "raw.partitionId" , "Partition Id" ) ) ; } } protected retrieveEvents ( messageHandler ? ) { return this . data . restClient . getPartitionEvents ( this . queryStartDate , this . queryEndDate , this . partitionId , messageHandler ) . then ( result => { return result . map ( event => new FabricEventInstanceModel < PartitionEvent > ( this . data , event ) ) ; } ) ; } } export class ReplicaEventList extends EventListBase < ReplicaEvent > { private partitionId : string ; private replicaId ? : string ; public constructor ( data , partitionId , replicaId ? ) { super ( data ) ; this . partitionId = partitionId ; this . replicaId = replicaId ; if ( ! this . replicaId ) { this . settings . columnSettings . splice ( this . optionalColsStartIndex , 0 , new ListColumnSettingWithFilter ( "raw.replicaId" , "Replica Id" ) ) ; } } protected retrieveEvents ( messageHandler ? ) { return this . data . restClient . getReplicaEvents ( this . queryStartDate , this . queryEndDate , this . partitionId , this . replicaId , messageHandler ) . then ( result => { return result . map ( event => new FabricEventInstanceModel < ReplicaEvent > ( this . data , event ) ) ; } ) ; } } export class CorrelatedEventList extends EventListBase < FabricEvent > { private eventInstanceId : string ; public constructor ( data , eventInstanceId ) { super ( data ) ; this . eventInstanceId = eventInstanceId ; } protected retrieveEvents ( messageHandler ? ) { return this . data . restClient . getCorrelatedEvents ( this . eventInstanceId , messageHandler ) . then ( result => { return result . map ( event => new FabricEventInstanceModel < FabricEvent > ( this . data , event ) ) ; } ) ; } } }