import { Injectable } from '@angular/core' ; import { SystemApplication , Application } from '../Models/DataModels/Application' ; import { ApplicationTypeGroupCollection , ApplicationCollection , BackupPolicyCollection , ServiceTypeCollection , DeployedReplicaCollection , DeployedCodePackageCollection , DeployedServicePackageCollection , ReplicaOnPartitionCollection , PartitionCollection , ClusterEventList , NodeEventList , ApplicationEventList , ServiceEventList , PartitionEventList , ReplicaEventList , CorrelatedEventList , EventListBase } from '../Models/DataModels/collections/Collections' ; import { RoutesService } from './routes.service' ; import { MessageService } from './message.service' ; import { TelemetryService } from './telemetry.service' ; import { StatusWarningService } from './status-warning.service' ; import { StorageService } from './storage.service' ; import { HealthStateFilterFlags , IClusterHealthChunkQueryDescription , IClusterHealthChunk , IDeployedApplicationHealthStateChunk } from '../Models/HealthChunkRawDataTypes' ; import { ClusterUpgradeProgress , ClusterLoadInformation , ClusterManifest , ClusterHealth } from '../Models/DataModels/Cluster' ; import { ImageStore } from '../Models/DataModels/ImageStore' ; import { Constants } from '../Common/Constants' ; import { IResponseMessageHandler , ResponseMessageHandlers } from '../Common/ResponseMessageHandlers' ; import { Observable , throwError , of } from 'rxjs' ; import { RestClientService } from './rest-client.service' ; import { map , mergeMap , finalize } from 'rxjs/operators' ; import { IDataModel } from '../Models/DataModels/Base' ; import { IdGenerator } from '../Utils/IdGenerator' ; import { Node } from '../Models/DataModels/Node' ; import { ApplicationTypeGroup , ApplicationType } from '../Models/DataModels/ApplicationType' ; import { ServiceType , Service } from '../Models/DataModels/Service' ; import { DeployedReplica } from '../Models/DataModels/DeployedReplica' ; import { DeployedCodePackage } from '../Models/DataModels/DeployedCodePackage' ; import { DeployedServicePackage } from '../Models/DataModels/DeployedServicePackage' ; import { DeployedApplication } from '../Models/DataModels/DeployedApplication' ; import { ReplicaOnPartition } from '../Models/DataModels/Replica' ; import { Partition } from '../Models/DataModels/Partition' ; import { NodeCollection } from '../Models/DataModels/collections/NodeCollection' ; import { ServiceCollection } from '../Models/DataModels/collections/ServiceCollection' ; import { IDataModelCollection } from '../Models/DataModels/collections/CollectionBase' ; import { DeployedApplicationCollection } from '../Models/DataModels/collections/DeployedApplicationCollection' ; import { MatDialog } from '@angular/material/dialog' ; import { RepairTaskCollection } from '../Models/DataModels/collections/RepairTaskCollection' ; import { ApplicationEvent , ClusterEvent , FabricEventBase , NodeEvent , PartitionEvent , ReplicaEvent , ServiceEvent } from '../Models/eventstore/Events' ; import { IEventStoreData } from '../modules/event-store/event-store/event-store.component' ; import { SettingsService } from './settings.service' ; import { RepairTask } from '../Models/DataModels/repairTask' ; import { ApplicationTimelineGenerator , ClusterTimelineGenerator , NodeTimelineGenerator , PartitionTimelineGenerator , RepairTaskTimelineGenerator } from '../Models/eventstore/timelineGenerators' ; import groupBy from 'lodash/groupBy' ; @ Injectable ( { providedIn : 'root' } ) export class DataService { public systemApp : SystemApplication ; public clusterManifest : ClusterManifest ; public clusterUpgradeProgress : ClusterUpgradeProgress ; public clusterLoadInformation : ClusterLoadInformation ; public appTypeGroups : ApplicationTypeGroupCollection ; public apps : ApplicationCollection ; public nodes : NodeCollection ; public imageStore : ImageStore ; public backupPolicies : BackupPolicyCollection ; public repairCollection : RepairTaskCollection ; public readOnlyHeader : boolean = null ; public clusterNameMetadata : string = null ; constructor ( public routes , public message , public telemetry , public warnings , public storage , public restClient , public dialog ) { this . clusterUpgradeProgress = new ClusterUpgradeProgress ( this ) ; this . clusterManifest = new ClusterManifest ( this ) ; this . clusterLoadInformation = new ClusterLoadInformation ( this ) ; this . apps = new ApplicationCollection ( this ) ; this . appTypeGroups = new ApplicationTypeGroupCollection ( this ) ; this . nodes = new NodeCollection ( this ) ; this . systemApp = new SystemApplication ( this ) ; this . backupPolicies = new BackupPolicyCollection ( this ) ; this . repairCollection = new RepairTaskCollection ( this ) ; } public actionsEnabled ( ) { return this . readOnlyHeader !== true ; } public actionsAdvancedEnabled ( ) { return this . actionsEnabled ( ) && this . storage . getValueBoolean ( Constants . AdvancedModeKey , false ) ; } public isAdvancedModeEnabled ( ) { return this . storage . getValueBoolean ( Constants . AdvancedModeKey , false ) ; } public getClusterHealth ( eventsHealthStateFilter = HealthStateFilterFlags . Default , nodesHealthStateFilter = HealthStateFilterFlags . Default , applicationsHealthStateFilter = HealthStateFilterFlags . Default ) { return new ClusterHealth ( this , eventsHealthStateFilter , nodesHealthStateFilter , applicationsHealthStateFilter ) ; } public getClusterManifest ( forceRefresh = false , messageHandler ? ) { return this . clusterManifest . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => this . clusterManifest ) ) ; } public getClusterUpgradeProgress ( forceRefresh = false , messageHandler ? ) { return this . clusterUpgradeProgress . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => this . clusterUpgradeProgress ) ) ; } public getClusterLoadInformation ( forceRefresh = false , messageHandler ? ) { return this . clusterLoadInformation . ensureInitialized ( forceRefresh , messageHandler ) ; } public getClusterHealthChunk ( healthDescriptor ) { return this . restClient . getClusterHealthChunk ( healthDescriptor , ResponseMessageHandlers . silentResponseMessageHandler ) . pipe ( map ( ( raw ) => { return this . preprocessHealthChunkData ( raw ) ; } ) ) ; } public getInitialClusterHealthChunkQueryDescription ( ) { return { ApplicationFilters : [ { HealthStateFilter : HealthStateFilterFlags . All } ] , NodeFilters : [ { HealthStateFilter : HealthStateFilterFlags . All } ] } ; } public getSystemApp ( forceRefresh ? , messageHandler ? ) { return this . systemApp . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => this . systemApp ) ) ; } public getSystemServices ( forceRefresh ? , messageHandler ? ) { return this . getSystemApp ( false , messageHandler ) . pipe ( mergeMap ( app => app . services . ensureInitialized ( forceRefresh , messageHandler ) ) , map ( ( ) => this . systemApp . services ) ) ; } public getApps ( forceRefresh ? , messageHandler ? ) { return this . apps . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => this . apps ) ) ; } public getApp ( id , forceRefresh ? , messageHandler ? ) { return this . getApps ( false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , id , forceRefresh , messageHandler ) ; } ) ) ; } public getNodes ( forceRefresh ? , messageHandler ? ) { return this . nodes . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => this . nodes ) ) ; } public getNode ( name , forceRefresh ? , messageHandler ? ) { return this . getNodes ( false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , name , forceRefresh , messageHandler ) ; } ) ) ; } public getAppTypeGroups ( forceRefresh ? , messageHandler ? ) { return this . appTypeGroups . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => this . appTypeGroups ) ) ; } public getAppTypeGroup ( name , forceRefresh ? , messageHandler ? ) { return this . getAppTypeGroups ( false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , name , forceRefresh , messageHandler ) ; } ) ) ; } public getAppType ( name , version , forceRefresh ? , messageHandler ? ) { return this . getAppTypeGroup ( name , false , messageHandler ) . pipe ( map ( appTypeGroup => { const filteredAppTypes = appTypeGroup . appTypes . filter ( appType => appType . raw . Version === version ) ; return filteredAppTypes [ 0 ] ; } ) ) ; } public getServiceTypes ( appTypeName , appTypeVersion , forceRefresh ? , messageHandler ? ) { return this . getAppType ( appTypeName , appTypeVersion , false , messageHandler ) . pipe ( mergeMap ( appType => { return appType . serviceTypes . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => appType . serviceTypes ) ) ; } ) ) ; } public getServiceType ( appTypeName , appTypeVersion , serviceTypeName , forceRefresh ? , messageHandler ? ) { return this . getServiceTypes ( appTypeName , appTypeVersion , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , serviceTypeName , forceRefresh , messageHandler ) ; } ) ) ; } public getServices ( appId , forceRefresh ? , messageHandler ? ) { const getAppPromise = appId === Constants . SystemAppId ? this . getSystemApp ( false , messageHandler ) : this . getApp ( appId , false , messageHandler ) ; return getAppPromise . pipe ( mergeMap ( app => { return app . services . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => app . services ) ) ; } ) ) ; } public getService ( appId , serviceId , forceRefresh ? , messageHandler ? ) { return this . getServices ( appId , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , IdGenerator . service ( serviceId ) , forceRefresh , messageHandler ) ; } ) ) ; } public getPartitions ( appId , serviceId , forceRefresh ? , messageHandler ? ) { return this . getService ( appId , serviceId , false , messageHandler ) . pipe ( mergeMap ( service => { return service . partitions . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => service . partitions ) ) ; } ) ) ; } public getPartition ( appId , serviceId , partitionId , forceRefresh ? , messageHandler ? ) { return this . getPartitions ( appId , serviceId , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , IdGenerator . partition ( partitionId ) , forceRefresh , messageHandler ) ; } ) ) ; } public getReplicasOnPartition ( appId , serviceId , partitionId , forceRefresh ? , messageHandler ? ) { return this . getPartition ( appId , serviceId , partitionId , false , messageHandler ) . pipe ( mergeMap ( partition => { return partition . replicas . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => partition . replicas ) ) ; } ) ) ; } public getReplicaOnPartition ( appId , serviceId , partitionId , replicaId , forceRefresh ? , messageHandler ? ) { return this . getReplicasOnPartition ( appId , serviceId , partitionId , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , IdGenerator . replica ( replicaId ) , forceRefresh , messageHandler ) ; } ) ) ; } public getDeployedApplications ( nodeName , forceRefresh ? , messageHandler ? ) { return this . getNode ( nodeName , false , messageHandler ) . pipe ( mergeMap ( node => { return node . deployedApps . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => node . deployedApps ) ) ; } ) ) ; } public getDeployedApplication ( nodeName , appId , forceRefresh ? , messageHandler ? ) { return this . getDeployedApplications ( nodeName , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , IdGenerator . app ( appId ) , forceRefresh , messageHandler ) ; } ) ) ; } public getDeployedServicePackages ( nodeName , appId , forceRefresh ? , messageHandler ? ) { return this . getDeployedApplication ( nodeName , appId , false , messageHandler ) . pipe ( mergeMap ( deployedApp => { return deployedApp . deployedServicePackages . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => deployedApp . deployedServicePackages ) ) ; } ) ) ; } public getDeployedServicePackage ( nodeName , appId , servicePackageName , servicePackageActivationId , forceRefresh ? , messageHandler ? ) { return this . getDeployedServicePackages ( nodeName , appId , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , IdGenerator . deployedServicePackage ( servicePackageName , servicePackageActivationId ) , forceRefresh , messageHandler ) ; } ) ) ; } public getDeployedCodePackages ( nodeName , appId , servicePackageName , servicePackageActivationId , forceRefresh ? , messageHandler ? ) { return this . getDeployedServicePackage ( nodeName , appId , servicePackageName , servicePackageActivationId , false , messageHandler ) . pipe ( mergeMap ( deployedServicePackage => { return deployedServicePackage . deployedCodePackages . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => deployedServicePackage . deployedCodePackages ) ) ; } ) ) ; } public getDeployedCodePackage ( nodeName , appId , servicePackageName , servicePackageActivationId , codePackageName , forceRefresh ? , messageHandler ? ) { return this . getDeployedCodePackages ( nodeName , appId , servicePackageName , servicePackageActivationId , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , IdGenerator . deployedCodePackage ( codePackageName ) , forceRefresh , messageHandler ) ; } ) ) ; } public getDeployedReplicas ( nodeName , appId , servicePackageName , servicePackageActivationId , forceRefresh ? , messageHandler ? ) { return this . getDeployedServicePackage ( nodeName , appId , servicePackageName , servicePackageActivationId , false , messageHandler ) . pipe ( mergeMap ( deployedServicePackage => { return deployedServicePackage . deployedReplicas . ensureInitialized ( forceRefresh , messageHandler ) . pipe ( map ( ( ) => deployedServicePackage . deployedReplicas ) ) ; } ) ) ; } public getDeployedReplica ( nodeName , appId , servicePackageName , servicePackageActivationId , partitionId , forceRefresh ? , messageHandler ? ) { return this . getDeployedReplicas ( nodeName , appId , servicePackageName , servicePackageActivationId , false , messageHandler ) . pipe ( mergeMap ( collection => { return this . tryGetValidItem ( collection , IdGenerator . deployedReplica ( partitionId ) , forceRefresh , messageHandler ) ; } ) ) ; } public refreshBackupPolicies ( messageHandler ) { return this . clusterManifest . ensureInitialized ( ) . pipe ( mergeMap ( ( ) => { if ( this . clusterManifest . isBackupRestoreEnabled ) { return this . backupPolicies . refresh ( messageHandler ) ; } else { return of ( null ) ; } } ) ) ; } private addFabricEventData < T extends EventListBase < any > , S extends FabricEventBase > ( data ) { data . listSettings = data . eventsList . settings ; data . getEvents = ( ) => data . eventsList . collection . map ( event => event . raw ) ; data . setDateWindow = ( startDate , endDate ) => data . eventsList . setDateWindow ( startDate , endDate ) ; } public getRepairTasksData ( settings ) { return { eventsList : this . repairCollection , timelineGenerator : new RepairTaskTimelineGenerator ( ) , displayName : 'Repair Tasks' , listSettings : settings . getNewOrExistingCompletedRepairTaskListSettings ( ) , getEvents : ( ) => this . repairCollection . collection } ; } public getClusterEventData ( ) { const list = new ClusterEventList ( this ) ; const d = { eventsList : list , timelineGenerator : new ClusterTimelineGenerator ( ) , displayName : 'Cluster' , } ; this . addFabricEventData < ClusterEventList , ClusterEvent > ( d ) ; return d ; } public getNodeEventData ( nodeName ? ) { const list = new NodeEventList ( this , nodeName ) ; const d = { eventsList : list , timelineGenerator : new NodeTimelineGenerator ( ) , displayName : nodeName ? nodeName : 'Nodes' , } ; this . addFabricEventData < NodeEventList , NodeEvent > ( d ) ; return d ; } public getApplicationEventData ( applicationId ? ) { const list = new ApplicationEventList ( this , applicationId ) ; const d = { eventsList : list , timelineGenerator : applicationId ? new ApplicationTimelineGenerator ( ) : null , displayName : applicationId ? applicationId : 'Apps' , } ; this . addFabricEventData < ApplicationEventList , ApplicationEvent > ( d ) ; return d ; } public getServiceEventData ( serviceId ? ) { const list = new ServiceEventList ( this , serviceId ) ; const d = { eventsList : list , displayName : serviceId } ; this . addFabricEventData < ServiceEventList , ServiceEvent > ( d ) ; return d ; } public getPartitionEventData ( partitionId ? ) { const list = new PartitionEventList ( this , partitionId ) ; const d = { eventsList : list , timelineGenerator : new PartitionTimelineGenerator ( ) , displayName : partitionId } ; this . addFabricEventData < PartitionEventList , PartitionEvent > ( d ) ; return d ; } public getReplicaEventData ( partitionId , replicaId ? ) { const list = new ReplicaEventList ( this , partitionId , replicaId ) ; const d = { eventsList : list , displayName : replicaId } ; this . addFabricEventData < ReplicaEventList , ReplicaEvent > ( d ) ; return d ; } public createCorrelatedEventList ( eventInstanceId ) { return new CorrelatedEventList ( this , eventInstanceId ) ; } private tryGetValidItem < T extends IDataModel < any > > ( collection , uniqueId , forceRefresh ? , messageHandler ? ) { const item = collection . find ( uniqueId ) ; if ( item ) { return item . ensureInitialized ( forceRefresh , messageHandler ) ; } else { return throwError ( 'This item could not be found' ) ; } } private preprocessHealthChunkData ( clusterHealthChunk ) { clusterHealthChunk . SystemApplicationHealthStateChunk = clusterHealthChunk . ApplicationHealthStateChunks . Items . filter ( appHealthStateChunk => appHealthStateChunk . ApplicationName === Constants . SystemAppName ) [ 0 ] ; const deployedApps = [ ] ; clusterHealthChunk . ApplicationHealthStateChunks . Items . forEach ( appHealthStateChunk => appHealthStateChunk . DeployedApplicationHealthStateChunks . Items . forEach ( deployedApp => { deployedApp . ApplicationName = appHealthStateChunk . ApplicationName ; deployedApps . push ( deployedApp ) ; } ) ) ; const nodeDeployedAppsGroups = groupBy ( deployedApps , deployedApp => deployedApp . NodeName ) ; Object . keys ( nodeDeployedAppsGroups ) . forEach ( key => { const group = nodeDeployedAppsGroups [ key ] ; const nodeHealthChunk = clusterHealthChunk . NodeHealthStateChunks . Items . find ( chunk => chunk . NodeName === key ) ; if ( nodeHealthChunk ) { nodeHealthChunk . DeployedApplicationHealthStateChunks = { Items : group , TotalCount : group . length } ; } } ) ; clusterHealthChunk . NodeHealthStateChunks . Items . forEach ( nodeHealthChunk => { if ( ! nodeHealthChunk . DeployedApplicationHealthStateChunks ) { nodeHealthChunk . DeployedApplicationHealthStateChunks = { Items : [ ] , TotalCount : 0 } ; } } ) ; return clusterHealthChunk ; } }