module Sfx { export class Node extends DataModelBase < IRawNode > { public decorators : IDecorators = { decorators : { "NodeUpTimeInSeconds" : { displayName : ( name ) => "Node Up Time" , displayValueInHtml : ( value ) => this . nodeUpTime } } } ; public deployedApps : DeployedApplicationCollection ; public loadInformation : NodeLoadInformation ; public health : NodeHealth ; private expectedNodeStatus : NodeStatus = NodeStatus . Invalid ; public constructor ( data , raw ? ) { super ( data , raw ) ; this . deployedApps = new DeployedApplicationCollection ( this . data , this ) ; this . loadInformation = new NodeLoadInformation ( this . data , this ) ; this . health = new NodeHealth ( this . data , this , HealthStateFilterFlags . Default ) ; if ( this . data . actionsEnabled ( ) ) { this . setUpActions ( ) ; } if ( this . data . actionsAdvancedEnabled ( ) ) { this . setAdvancedActions ( ) ; } } public get nodeStatus ( ) : string { return this . raw . IsStopped ? "Down (Stopped)" : this . raw . NodeStatus ; } public get nodeUpTime ( ) : string { return TimeUtils . getDurationFromSeconds ( this . raw . NodeUpTimeInSeconds ) ; } public get id ( ) : string { return this . raw . Id . Id ; } public get viewPath ( ) : string { return this . data . routes . getNodeViewPath ( this . name ) ; } public get tooltip ( ) : string { return `${ this . name }\nType: ${ this . raw . Type }\nStatus: ${ this . raw . NodeStatus }\nHealth State: ${ this . healthState . text }` ; } public get upgradeDomain ( ) : string { return this . raw . UpgradeDomain ; } public get faultDomain ( ) : string { return this . raw . FaultDomain ; } public addHealthStateFiltersForChildren ( clusterHealthChunkQueryDescription ) { _ . forEach ( clusterHealthChunkQueryDescription . ApplicationFilters , filter => { if ( _ . isEmpty ( filter . DeployedApplicationFilters ) ) { filter . DeployedApplicationFilters = [ ] ; } filter . DeployedApplicationFilters . push ( { NodeNameFilter : this . name } ) ; } ) ; return null ; } public removeAdvancedActions ( ) { this . actions . collection = this . actions . collection . filter ( action => [ "activateNode" , "removeNodeState" , "deactivePauseNode" , "deactiveRestartNode" , "deactiveRemoveNodeData" ] . indexOf ( action . name ) === - 1 ) ; } public setAdvancedActions ( ) { this . actions . add ( new Action ( "activateNode" , "Activate" , "Activating" , ( ) => this . activate ( ) , ( ) => ( this . expectedNodeStatus !== NodeStatus . Invalid ) ? this . expectedNodeStatus === NodeStatus . Disabled : this . raw . NodeStatus === NodeStatusConstants . Down || this . raw . NodeStatus === NodeStatusConstants . Disabling || this . raw . NodeStatus === NodeStatusConstants . Disabled ) ) ; this . actions . add ( new ActionWithConfirmationDialog ( this . data . $uibModal , this . data . $q , "removeNodeState" , "Remove node state" , "Removing" , ( ) => this . removeNodeState ( ) , ( ) => this . raw . NodeStatus === NodeStatusConstants . Down , "Confirm Node Removal" , `Data about node ${ this . name } will be completely erased from the cluster ${ this . data . $location . host ( ) }. All data stored on the node will be lost permanently. Are you sure to continue?` , this . name ) ) ; this . actions . add ( new ActionWithConfirmationDialog ( this . data . $uibModal , this . data . $q , "deactivePauseNode" , "Deactivate (pause)" , "Deactivating" , ( ) => this . deactivate ( 1 ) , ( ) => this . raw . NodeStatus !== NodeStatusConstants . Down , "Confirm Node Deactivation" , `Deactivate node '${ this . name }' from cluster '${ this . data . $location . host ( ) }'? This node will not become operational again until it is manually reactivated. WARNING: Deactivating nodes can cause data loss if not used with caution. For more information see: https://go.microsoft.com/fwlink/?linkid=825861` , this . name ) ) ; this . actions . add ( new ActionWithConfirmationDialog ( this . data . $uibModal , this . data . $q , "deactiveRestartNode" , "Deactivate (restart)" , "Deactivating" , ( ) => this . deactivate ( 2 ) , ( ) => this . raw . NodeStatus !== NodeStatusConstants . Down , "Confirm Node Deactivation" , `Deactivate node '${ this . name }' from cluster '${ this . data . $location . host ( ) }'? This node will not become operational again until it is manually reactivated. WARNING: Deactivating nodes can cause data loss if not used with caution. For more information see: https://go.microsoft.com/fwlink/?linkid=825861` , this . name ) ) ; this . actions . add ( new ActionWithConfirmationDialog ( this . data . $uibModal , this . data . $q , "deactiveRemoveNodeData" , "Deactivate (remove data)" , "Deactivating" , ( ) => this . deactivate ( 3 ) , ( ) => this . raw . NodeStatus !== NodeStatusConstants . Down , "Confirm Node Deactivation" , `Deactivate node '${ this . name }' from cluster '${ this . data . $location . host ( ) }'? This node will not become operational again until it is manually reactivated. WARNING: Deactivating nodes can cause data loss if not used with caution. For more information see: https://go.microsoft.com/fwlink/?linkid=825861` , this . name ) ) ; } protected retrieveNewData ( messageHandler ? ) { return this . data . restClient . getNode ( this . name , messageHandler ) . then ( response => { this . expectedNodeStatus = NodeStatus . Invalid ; return response . data ; } ) ; } private setUpActions ( ) { this . actions . add ( new ActionWithConfirmationDialog ( this . data . $uibModal , this . data . $q , "restartNode" , "Restart" , "Restarting" , ( ) => this . restart ( ) , ( ) => true , "Confirm Node Restart" , `Restart node ${ this . name } from the cluster ${ this . data . $location . host ( ) }?` , this . name ) ) ; } private activate ( ) { return this . data . restClient . activateNode ( this . name ) . then ( ( ) => { this . expectedNodeStatus = NodeStatus . Up ; } ) ; } private deactivate ( intent ) { return this . data . restClient . deactivateNode ( this . name , intent ) . then ( ( ) => { this . expectedNodeStatus = NodeStatus . Disabled ; } ) ; } private removeNodeState ( ) { return this . data . restClient . removeNodeState ( this . name ) ; } private restart ( ) { return this . data . restClient . restartNode ( this . name , this . raw . InstanceId ) ; } } export class NodeLoadInformation extends DataModelBase < IRawNodeLoadInformation > { public decorators : IDecorators = { hideList : [ "NodeName" ] } ; public nodeLoadMetricInformation : NodeLoadMetricInformation [ ] = [ ] ; public get name ( ) : string { return this . raw . NodeName ; } public constructor ( data , public parent ) { super ( data , null , parent ) ; } protected retrieveNewData ( messageHandler ? ) { return Utils . getHttpResponseData ( this . data . restClient . getNodeLoadInformation ( this . parent . name , messageHandler ) ) ; } protected updateInternal ( ) { CollectionUtils . updateDataModelCollection ( this . nodeLoadMetricInformation , _ . map ( this . raw . NodeLoadMetricInformation , lmi => new NodeLoadMetricInformation ( this . data , lmi , this ) ) ) ; } } export class NodeLoadMetricInformation extends DataModelBase < IRawNodeLoadMetricInformation > { public get hasCapacity ( ) : boolean { return this . raw . NodeCapacity && + this . raw . NodeCapacity > 0 ; } public get isSystemMetric ( ) : boolean { return _ . startsWith ( this . raw . Name , "__" ) && _ . endsWith ( this . raw . Name , "__" ) ; } public get loadCapacityRatio ( ) : number { return this . hasCapacity ? this . raw . NodeLoad / this . raw . NodeCapacity : 0 ; } public get loadCapacityRatioString ( ) : string { return ( this . loadCapacityRatio * 100 ) . toFixed ( 1 ) + "%" ; } public constructor ( data , raw , public parent ) { super ( data , raw , parent ) ; } } export class NodeHealth extends HealthBase < IRawNodeHealth > { public constructor ( data , public parent , protected eventsHealthStateFilter ) { super ( data , parent ) ; } protected retrieveNewData ( messageHandler ? ) { return Utils . getHttpResponseData ( this . data . restClient . getNodeHealth ( this . parent . name , this . eventsHealthStateFilter , messageHandler ) ) ; } } }