Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #3448 from cloudfoundry-incubator/user-services-co…
Browse files Browse the repository at this point in the history
…unts

Ensure Service Instance counts are correct
  • Loading branch information
richard-cox committed Apr 4, 2019
2 parents 2eeac37 + 46692e9 commit ce21f0a
Show file tree
Hide file tree
Showing 22 changed files with 168 additions and 165 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@

import { of as observableOf, BehaviorSubject, Observable, combineLatest } from 'rxjs';
import { Component, OnInit, Optional } from '@angular/core';
import { Store } from '@ngrx/store';
import { BehaviorSubject, combineLatest, Observable, of as observableOf } from 'rxjs';
import { first, map } from 'rxjs/operators';

import { RouterNav } from '../../../../../store/src/actions/router.actions';
import { AppState } from '../../../../../store/src/app-state';
import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types';
import { EndpointModel } from '../../../../../store/src/types/endpoint.types';
import { getPreviousRoutingState } from '../../../../../store/src/types/routing.type';
import { IOrganization, ISpace } from '../../../core/cf-api.types';
import { CurrentUserPermissionsChecker } from '../../../core/current-user-permissions.checker';
import { CurrentUserPermissions } from '../../../core/current-user-permissions.config';
Expand All @@ -15,11 +19,7 @@ import { getActiveRouteCfOrgSpaceProvider } from '../cf.helpers';
import { CloudFoundryEndpointService } from '../services/cloud-foundry-endpoint.service';
import { CloudFoundryOrganizationService } from '../services/cloud-foundry-organization.service';
import { CloudFoundrySpaceService } from '../services/cloud-foundry-space.service';
import { EntityInfo, APIResource } from '../../../../../store/src/types/api.types';
import { EndpointModel } from '../../../../../store/src/types/endpoint.types';
import { AppState } from '../../../../../store/src/app-state';
import { getPreviousRoutingState } from '../../../../../store/src/types/routing.type';
import { RouterNav } from '../../../../../store/src/actions/router.actions';


@Component({
selector: 'app-cli-info-cloud-foundry',
Expand Down Expand Up @@ -71,7 +71,6 @@ export class CliInfoCloudFoundryComponent implements OnInit {
}

ngOnInit() {
const { cfGuid, orgGuid, spaceGuid } = this.activeRouteCfOrgSpace;
this.setupRouteObservable(this.getDefaultBackLink());
// Will auto unsubscribe as we are using 'first'
this.route$.pipe(first()).subscribe(route => {
Expand Down Expand Up @@ -107,7 +106,7 @@ export class CliInfoCloudFoundryComponent implements OnInit {
}

private setupObservables() {
const { cfGuid, orgGuid, spaceGuid } = this.activeRouteCfOrgSpace;
const { orgGuid, spaceGuid } = this.activeRouteCfOrgSpace;
const org$ = orgGuid ? this.cfOrgService.org$ : observableOf(null);
const space$ = spaceGuid ? this.cfSpaceService.space$ : observableOf(null);
this.endpointOrgSpace$ = combineLatest(
Expand All @@ -130,7 +129,6 @@ export class CliInfoCloudFoundryComponent implements OnInit {
}

private setupBreadcrumbs() {
const { cfGuid, orgGuid, spaceGuid } = this.activeRouteCfOrgSpace;
this.breadcrumbs$ = this.endpointOrgSpace$.pipe(
map(([cf, org, space]) => {
const breadcrumbs = [{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
privateDomainsSchemaKey,
quotaDefinitionSchemaKey,
routeSchemaKey,
serviceInstancesSchemaKey,
spaceSchemaKey,
} from '../../../../../store/src/helpers/entity-factory';
import {
Expand Down Expand Up @@ -86,9 +85,8 @@ export class CloudFoundryEndpointService {
createEntityRelationKey(organizationSchemaKey, domainSchemaKey),
createEntityRelationKey(organizationSchemaKey, quotaDefinitionSchemaKey),
createEntityRelationKey(organizationSchemaKey, privateDomainsSchemaKey),
createEntityRelationKey(spaceSchemaKey, serviceInstancesSchemaKey),
createEntityRelationKey(spaceSchemaKey, routeSchemaKey), // Not really needed at top level, but if we drop down into an org with
// lots of spaces it saves n x routes requests
// lots of spaces it saves spaces x routes requests
]);
}
static createGetAllOrganizationsLimitedSchema(cfGuid: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@ import {
privateDomainsSchemaKey,
quotaDefinitionSchemaKey,
routeSchemaKey,
serviceInstancesSchemaKey,
spaceSchemaKey,
} from '../../../../../store/src/helpers/entity-factory';
import { createEntityRelationKey } from '../../../../../store/src/helpers/entity-relations/entity-relations.types';
import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types';
import { OrgUserRoleNames } from '../../../../../store/src/types/user.types';
import { IServiceInstance } from '../../../core/cf-api-svc.types';
import { IApp, IOrganization, IPrivateDomain, IQuotaDefinition, ISpace } from '../../../core/cf-api.types';
import { getEntityFlattenedList, getStartedAppInstanceCount } from '../../../core/cf.helpers';
import { EntityServiceFactory } from '../../../core/entity-service-factory.service';
import { CfUserService } from '../../../shared/data-services/cf-user.service';
import { PaginationMonitorFactory } from '../../../shared/monitors/pagination-monitor.factory';
import {
CloudFoundryUserProvidedServicesService,
} from '../../../shared/services/cloud-foundry-user-provided-services.service';
import { fetchServiceInstancesCount } from '../../service-catalog/services-helper';
import { ActiveRouteCfOrgSpace } from '../cf-page.types';
import { getOrgRolesString } from '../cf.helpers';
import { CloudFoundryEndpointService } from './cloud-foundry-endpoint.service';
Expand All @@ -52,7 +54,8 @@ export class CloudFoundryOrganizationService {
totalMem$: Observable<number>;
privateDomains$: Observable<APIResource<IPrivateDomain>[]>;
routes$: Observable<APIResource<Route>[]>;
serviceInstances$: Observable<APIResource<IServiceInstance>[]>;
serviceInstancesCount$: Observable<number>;
userProvidedServiceInstancesCount$: Observable<number>;
spaces$: Observable<APIResource<ISpace>[]>;
appInstances$: Observable<number>;
apps$: Observable<APIResource<IApp>[]>;
Expand All @@ -68,6 +71,7 @@ export class CloudFoundryOrganizationService {
private cfUserService: CfUserService,
private paginationMonitorFactory: PaginationMonitorFactory,
private cfEndpointService: CloudFoundryEndpointService,
private cfUserProvidedServicesService: CloudFoundryUserProvidedServicesService
) {
this.orgGuid = activeRouteCfOrgSpace.orgGuid;
this.cfGuid = activeRouteCfOrgSpace.cfGuid;
Expand All @@ -91,7 +95,6 @@ export class CloudFoundryOrganizationService {
createEntityRelationKey(organizationSchemaKey, domainSchemaKey),
createEntityRelationKey(organizationSchemaKey, quotaDefinitionSchemaKey),
createEntityRelationKey(organizationSchemaKey, privateDomainsSchemaKey),
createEntityRelationKey(spaceSchemaKey, serviceInstancesSchemaKey),
createEntityRelationKey(spaceSchemaKey, routeSchemaKey),
];
if (!isAdmin) {
Expand Down Expand Up @@ -129,10 +132,13 @@ export class CloudFoundryOrganizationService {
map(u => getOrgRolesString(u))
);

this.serviceInstancesCount$ = fetchServiceInstancesCount(this.cfGuid, this.orgGuid, null, this.store, this.paginationMonitorFactory);
this.userProvidedServiceInstancesCount$ =
this.cfUserProvidedServicesService.fetchUserProvidedServiceInstancesCount(this.cfGuid, this.orgGuid);

}

private initialiseSpaceObservables() {
this.serviceInstances$ = this.spaces$.pipe(this.getFlattenedList('service_instances'));
this.routes$ = this.spaces$.pipe(this.getFlattenedList('routes'));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ import {
import { createEntityRelationKey } from '../../../../../store/src/helpers/entity-relations/entity-relations.types';
import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types';
import { SpaceUserRoleNames } from '../../../../../store/src/types/user.types';
import { IServiceInstance } from '../../../core/cf-api-svc.types';
import { IApp, IQuotaDefinition, IRoute, ISpace } from '../../../core/cf-api.types';
import { getStartedAppInstanceCount } from '../../../core/cf.helpers';
import { EntityServiceFactory } from '../../../core/entity-service-factory.service';
import { CfUserService } from '../../../shared/data-services/cf-user.service';
import { PaginationMonitorFactory } from '../../../shared/monitors/pagination-monitor.factory';
import {
CloudFoundryUserProvidedServicesService,
} from '../../../shared/services/cloud-foundry-user-provided-services.service';
import { fetchServiceInstancesCount } from '../../service-catalog/services-helper';
import { ActiveRouteCfOrgSpace } from '../cf-page.types';
import { getSpaceRolesString } from '../cf.helpers';
import { CloudFoundryEndpointService } from './cloud-foundry-endpoint.service';
Expand All @@ -40,7 +43,8 @@ export class CloudFoundrySpaceService {
allowSsh$: Observable<string>;
totalMem$: Observable<number>;
routes$: Observable<APIResource<IRoute>[]>;
serviceInstances$: Observable<APIResource<IServiceInstance>[]>;
serviceInstancesCount$: Observable<number>;
userProvidedServiceInstancesCount$: Observable<number>;
appInstances$: Observable<number>;
apps$: Observable<APIResource<IApp>[]>;
appCount$: Observable<number>;
Expand All @@ -55,6 +59,7 @@ export class CloudFoundrySpaceService {
private cfUserService: CfUserService,
private paginationMonitorFactory: PaginationMonitorFactory,
private cfEndpointService: CloudFoundryEndpointService,
private cfUserProvidedServicesService: CloudFoundryUserProvidedServicesService
) {

this.spaceGuid = activeRouteCfOrgSpace.spaceGuid;
Expand Down Expand Up @@ -90,7 +95,6 @@ export class CloudFoundrySpaceService {
this.space$ = this.cfUserService.isConnectedUserAdmin(this.cfGuid).pipe(
switchMap(isAdmin => {
const relations = [
createEntityRelationKey(spaceSchemaKey, serviceInstancesSchemaKey),
createEntityRelationKey(spaceSchemaKey, spaceQuotaSchemaKey),
createEntityRelationKey(serviceInstancesSchemaKey, serviceBindingSchemaKey),
createEntityRelationKey(serviceBindingSchemaKey, applicationSchemaKey),
Expand Down Expand Up @@ -119,7 +123,14 @@ export class CloudFoundrySpaceService {
refCount()
);

this.serviceInstances$ = this.space$.pipe(map(o => o.entity.entity.service_instances));
this.serviceInstancesCount$ = fetchServiceInstancesCount(
this.cfGuid,
this.orgGuid,
this.spaceGuid,
this.store,
this.paginationMonitorFactory);
this.userProvidedServiceInstancesCount$ =
this.cfUserProvidedServicesService.fetchUserProvidedServiceInstancesCount(this.cfGuid, this.orgGuid, this.spaceGuid);
this.routes$ = this.space$.pipe(map(o => o.entity.entity.routes));
this.allowSsh$ = this.space$.pipe(map(o => o.entity.entity.allow_ssh ? 'true' : 'false'));
this.quotaDefinition$ = this.space$.pipe(map(q => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,54 @@
<app-loading-page [isLoading]="detailsLoading$" text="Retrieving details">
<app-tile-group>
<app-tile>
<app-card-number-metric link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/apps" icon="apps" label="Applications" labelSingular="Application" value="{{ cfSpaceService.appCount$ | async }}"></app-card-number-metric>
<app-card-number-metric
link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/apps"
icon="apps" label="Applications" labelSingular="Application" value="{{ cfSpaceService.appCount$ | async }}">
</app-card-number-metric>
</app-tile>
<app-tile *ngIf="cfEndpointService.appsPagObs.hasEntities$ | async">
<app-card-number-metric icon="content_copy" label="App Instances" value="{{ (cfSpaceService.appInstances$ | async) }}" limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.app_instance_limit}}"></app-card-number-metric>
<app-card-number-metric icon="content_copy" label="App Instances"
value="{{ (cfSpaceService.appInstances$ | async) }}"
limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.app_instance_limit}}"></app-card-number-metric>
</app-tile>
<app-tile>
<app-card-number-metric link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/routes" iconFont="stratos-icons" icon="network_route" label="Routes" value="{{ (cfSpaceService.routes$ | async)?.length }}" limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.total_routes}}"></app-card-number-metric>
<app-card-number-metric
link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/routes"
iconFont="stratos-icons" icon="network_route" label="Routes"
value="{{ (cfSpaceService.routes$ | async)?.length }}"
limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.total_routes}}"></app-card-number-metric>
</app-tile>
</app-tile-group>

<app-tile-group>
<app-tile>
<app-card-number-metric link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/users" icon="person" label="Users" labelSingular="User" value="{{(cfSpaceService.usersCount$ | async)}}"></app-card-number-metric>
<app-card-number-metric
link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/users"
icon="person" label="Users" labelSingular="User" value="{{(cfSpaceService.usersCount$ | async)}}">
</app-card-number-metric>
</app-tile>
<app-tile>
<app-card-number-metric link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/service-instances" iconFont="stratos-icons" icon="service" label="Service Instances" value="{{ (cfSpaceService.serviceInstances$ | async)?.length }}" limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.total_services }}"></app-card-number-metric>
<app-card-number-metric
link="/cloud-foundry/{{cfSpaceService.cfGuid}}/organizations/{{cfSpaceService.orgGuid}}/spaces/{{cfSpaceService.spaceGuid}}/service-instances"
iconFont="stratos-icons" icon="service" label="Service Instances"
value="{{ (cfSpaceService.serviceInstancesCount$ | async)}}"
limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.total_services }}"></app-card-number-metric>
</app-tile>
<app-tile *ngIf="(cfSpaceService.userProvidedServiceInstancesCount$ | async) > 0">
<app-card-number-metric iconFont="stratos-icons" icon="service" label="User Service Instances"
value="{{ (cfSpaceService.userProvidedServiceInstancesCount$ | async)}}"></app-card-number-metric>
</app-tile>
<app-tile *ngIf="cfEndpointService.appsPagObs.hasEntities$ | async">
<app-card-number-metric icon="memory" label="Memory Usage" units="mb" value="{{ (cfSpaceService.totalMem$ | async) }}" limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.memory_limit }}"></app-card-number-metric>
<app-card-number-metric icon="memory" label="Memory Usage" units="mb"
value="{{ (cfSpaceService.totalMem$ | async) }}"
limit="{{ (cfSpaceService.quotaDefinition$ | async)?.entity.memory_limit }}"></app-card-number-metric>
</app-tile>
</app-tile-group>

<app-tile-group>
<app-tile>
<app-card-cf-recent-apps *ngIf="!(detailsLoading$ | async)" [allApps$]="cfSpaceService.apps$" [loading$]="cfSpaceService.loadingApps$" (refresh)="cfSpaceService.fetchApps()"></app-card-cf-recent-apps>
<app-card-cf-recent-apps *ngIf="!(detailsLoading$ | async)" [allApps$]="cfSpaceService.apps$"
[loading$]="cfSpaceService.loadingApps$" (refresh)="cfSpaceService.fetchApps()"></app-card-cf-recent-apps>
</app-tile>
</app-tile-group>
</app-loading-page>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class CloudFoundrySpaceSummaryComponent {
cfEndpointService.appsPagObs.fetchingEntities$.pipe(
filter(loading => !loading)
),
cfSpaceService.userProvidedServiceInstancesCount$
]).pipe(
map(() => false),
startWith(true)
Expand Down
Loading

0 comments on commit ce21f0a

Please sign in to comment.