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

Typed access to actions and entities via catalog entity #4247

Merged
merged 21 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { createEntityRelationPaginationKey } from '../entity-relations/entity-re
import { CFStartAction } from './cf-action.types';

export class GetAllFeatureFlags extends CFStartAction implements PaginatedAction {
constructor(public endpointGuid: string, public paginationKey: string = '') {
constructor(public endpointGuid: string, public paginationKey: string = null) {
super();
this.paginationKey = this.paginationKey || createEntityRelationPaginationKey(endpointSchemaKey, this.endpointGuid);
this.options = new HttpRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class GetSpace extends CFStartAction implements ICFAction, EntityInlinePa
GET_SPACE_FAILED
];
entity = [cfEntityFactory(spaceEntityType)];
schemaKey = '';
schemaKey = ''; // Required by builder
entityType = spaceEntityType;
options: HttpRequest<any>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { combineLatest, filter, first, map, publishReplay, refCount, startWith, switchMap } from 'rxjs/operators';
import { combineLatest, filter, first, map, pairwise, publishReplay, refCount, startWith, switchMap } from 'rxjs/operators';

import { AppMetadataTypes } from '../../../../cloud-foundry/src/actions/app-metadata.actions';
import {
Expand All @@ -25,19 +25,16 @@ import {
ApplicationStateService,
} from '../../../../core/src/shared/components/application-state/application-state.service';
import { APP_GUID, CF_GUID } from '../../../../core/src/shared/entity.tokens';
import { entityCatalog } from '../../../../store/src/entity-catalog/entity-catalog';
import { EntityService } from '../../../../store/src/entity-service';
import { ActionState, rootUpdatingKey } from '../../../../store/src/reducers/api-request-reducer/types';
import {
getCurrentPageRequestInfo,
PaginationObservables,
} from '../../../../store/src/reducers/pagination-reducer/pagination-reducer.types';
import { selectUpdateInfo } from '../../../../store/src/selectors/api.selectors';
import { endpointEntitiesSelector } from '../../../../store/src/selectors/endpoint.selectors';
import { APIResource, EntityInfo } from '../../../../store/src/types/api.types';
import { PaginationEntityState } from '../../../../store/src/types/pagination.types';
import { cfEntityCatalog } from '../../cf-entity-catalog';
import { CF_ENDPOINT_TYPE } from '../../cf-types';
import { createEntityRelationKey } from '../../entity-relations/entity-relations.types';
import { AppStat } from '../../store/types/app-metadata.types';
import {
Expand All @@ -50,13 +47,13 @@ export function createGetApplicationAction(guid: string, endpointGuid: string) {
return new GetApplication(
guid,
endpointGuid, [
createEntityRelationKey(applicationEntityType, routeEntityType),
createEntityRelationKey(applicationEntityType, spaceEntityType),
createEntityRelationKey(applicationEntityType, stackEntityType),
createEntityRelationKey(applicationEntityType, serviceBindingEntityType),
createEntityRelationKey(routeEntityType, domainEntityType),
createEntityRelationKey(spaceEntityType, organizationEntityType),
]
createEntityRelationKey(applicationEntityType, routeEntityType),
createEntityRelationKey(applicationEntityType, spaceEntityType),
createEntityRelationKey(applicationEntityType, stackEntityType),
createEntityRelationKey(applicationEntityType, serviceBindingEntityType),
createEntityRelationKey(routeEntityType, domainEntityType),
createEntityRelationKey(spaceEntityType, organizationEntityType),
]
);
}

Expand Down Expand Up @@ -289,21 +286,18 @@ export class ApplicationService {
updatedApplication: UpdateApplication,
updateEntities?: AppMetadataTypes[],
existingApplication?: IApp): Observable<ActionState> {
this.store.dispatch(new UpdateExistingApplication(
return cfEntityCatalog.application.api.update<ActionState>(
this.appGuid,
this.cfGuid,
{ ...updatedApplication },
existingApplication,
updateEntities
));

// Create an Observable that can be used to determine when the update completed
const actionState = selectUpdateInfo(
entityCatalog.getEntityKey(CF_ENDPOINT_TYPE, applicationEntityType),
this.appGuid,
UpdateExistingApplication.updateKey
).pipe(
pairwise(),
filter(([oldS, newS]) => oldS.busy && !newS.busy),
map(([, newS]) => newS),
first()
);
return this.store.select(actionState).pipe(filter(item => !item.busy), first());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,9 @@ export class BuildTabComponent implements OnInit {

restageApplication() {
const { cfGuid, appGuid } = this.applicationService;
const restageAppAction = cfEntityCatalog.application.actions.restage(appGuid, cfGuid)
this.confirmAndPollForState(
appRestageConfirmation,
() => this.store.dispatch(restageAppAction),
() => cfEntityCatalog.application.api.restage(appGuid, cfGuid),
'starting',
'STARTED',
() => { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/fo
import { ErrorStateMatcher, ShowOnDirtyErrorStateMatcher } from '@angular/material/core';
import { Store } from '@ngrx/store';
import { combineLatest, Observable, of as observableOf } from 'rxjs';
import { catchError, filter, first, map, mergeMap, switchMap, tap } from 'rxjs/operators';
import { catchError, filter, first, map, mergeMap, pairwise, switchMap, tap } from 'rxjs/operators';

import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state';
import { domainEntityType, organizationEntityType } from '../../../../../../cloud-foundry/src/cf-entity-types';
Expand All @@ -12,7 +12,11 @@ import { CreateNewApplicationState } from '../../../../../../cloud-foundry/src/s
import { IDomain } from '../../../../../../core/src/core/cf-api.types';
import { StepOnNextFunction } from '../../../../../../core/src/shared/components/stepper/step/step.component';
import { RouterNav } from '../../../../../../store/src/actions/router.actions';
import { getDefaultRequestState, RequestInfoState } from '../../../../../../store/src/reducers/api-request-reducer/types';
import {
ActionState,
getDefaultRequestState,
RequestInfoState,
} from '../../../../../../store/src/reducers/api-request-reducer/types';
import { APIResource } from '../../../../../../store/src/types/api.types';
import { cfEntityCatalog } from '../../../../cf-entity-catalog';
import { createEntityRelationKey } from '../../../../entity-relations/entity-relations.types';
Expand Down Expand Up @@ -89,11 +93,9 @@ export class CreateApplicationStep3Component implements OnInit {
const obs$ = cfEntityCatalog.application.api.create<RequestInfoState>(
newAppGuid,
cloudFoundry, {
name,
space_guid: space
}).pipe(
filter(ris => !!ris.response)
);
name,
space_guid: space
});
return this.wrapObservable(obs$, 'Could not create application');
}

Expand All @@ -115,8 +117,6 @@ export class CreateApplicationStep3Component implements OnInit {
domain_guid: selectedDomainGuid,
host: hostName
}
).pipe(
filter(ris => !!ris.response)
)
return this.wrapObservable(obs$, 'Application created. Could not create route');
}
Expand All @@ -127,13 +127,25 @@ export class CreateApplicationStep3Component implements OnInit {
}

associateRoute(appGuid: string, routeGuid: string, endpointGuid: string): Observable<RequestInfoState> {
const obs$ = cfEntityCatalog.application.api.assignRoute<RequestInfoState>(endpointGuid, routeGuid, appGuid)
const obs$ = cfEntityCatalog.application.api.assignRoute<ActionState>(endpointGuid, routeGuid, appGuid).pipe(
map((actionState: ActionState): RequestInfoState => ({
creating: actionState.busy,
error: actionState.error,
message: actionState.message,
fetching: null,
updating: null,
deleting: null,
response: null
}))
)
return this.wrapObservable(obs$, 'Application and route created. Could not associated route with app');
}

private wrapObservable(obs$: Observable<RequestInfoState>, errorString: string): Observable<RequestInfoState> {
return obs$.pipe(
filter((state: RequestInfoState) => state && !state.creating),
pairwise(),
filter(([oldS, newS]) => oldS.creating && !newS.creating),
map(([, newS]) => newS),
first(),
tap(state => {
if (state.error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { Observable, Subscription } from 'rxjs';
import { filter, map, take, tap } from 'rxjs/operators';
import { filter, map, pairwise, take, tap } from 'rxjs/operators';

import { UpdateOrganization } from '../../../../../../cloud-foundry/src/actions/organization.actions';
import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state';
import { organizationEntityType } from '../../../../../../cloud-foundry/src/cf-entity-types';
import {
Expand All @@ -18,8 +17,8 @@ import {
} from '../../../../../../core/src/shared/services/cloud-foundry-user-provided-services.service';
import { endpointSchemaKey } from '../../../../../../store/src/helpers/entity-factory';
import { PaginationMonitorFactory } from '../../../../../../store/src/monitors/pagination-monitor.factory';
import { ActionState } from '../../../../../../store/src/reducers/api-request-reducer/types';
import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper';
import { selectRequestInfo } from '../../../../../../store/src/selectors/api.selectors';
import { APIResource } from '../../../../../../store/src/types/api.types';
import { cfEntityCatalog } from '../../../../cf-entity-catalog';
import { cfEntityFactory } from '../../../../cf-entity-factory';
Expand Down Expand Up @@ -133,17 +132,14 @@ export class EditOrganizationStepComponent implements OnInit, OnDestroy {
}

submit: StepOnNextFunction = () => {
const action = new UpdateOrganization(this.orgGuid, this.cfGuid, {
return cfEntityCatalog.org.api.update<ActionState>(this.orgGuid, this.cfGuid, {
name: this.editOrgName.value.orgName,
quota_definition_guid: this.editOrgName.value.quotaDefinition,
status: this.status ? OrgStatus.ACTIVE : OrgStatus.SUSPENDED
});
this.store.dispatch(action);

// Update action
return this.store.select(selectRequestInfo(action, this.orgGuid)).pipe(
filter(o => !!o && !o.updating[UpdateOrganization.UpdateExistingOrg].busy),
map(o => o.updating[UpdateOrganization.UpdateExistingOrg]),
}).pipe(
pairwise(),
filter(([oldS, newS]) => oldS.busy && !newS.busy),
map(([, newS]) => newS),
map(o => ({
success: !o.error,
redirect: !o.error,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { Store } from '@ngrx/store';
import { Observable, of, Subscription } from 'rxjs';
import { filter, map, pairwise, switchMap, take, tap } from 'rxjs/operators';

import { AssociateSpaceQuota } from '../../../../../../cloud-foundry/src/actions/quota-definitions.actions';
import { CFAppState } from '../../../../../../cloud-foundry/src/cf-app-state';
import { StepOnNextFunction } from '../../../../../../core/src/shared/components/stepper/step/step.component';
import { RequestInfoState } from '../../../../../../store/src/reducers/api-request-reducer/types';
import { ActionState } from '../../../../../../store/src/reducers/api-request-reducer/types';
import { cfEntityCatalog } from '../../../../cf-entity-catalog';
import { AddEditSpaceStepBase } from '../../add-edit-space-step-base';
import { ActiveRouteCfOrgSpace } from '../../cf-page.types';
Expand Down Expand Up @@ -95,36 +94,31 @@ export class EditSpaceStepComponent extends AddEditSpaceStepBase implements OnDe
return of({ success: true, redirect: true });
}

return this.updateSpaceQuota$();
return this.updateSpaceQuota();
}),
);
}

updateSpace() {
const action = cfEntityCatalog.space.actions.update(this.spaceGuid, this.cfGuid, {
return cfEntityCatalog.space.api.update<ActionState>(this.spaceGuid, this.cfGuid, {
name: this.editSpaceForm.value.spaceName,
allow_ssh: this.editSpaceForm.value.toggleSsh as boolean,
})
this.store.dispatch(action);
return cfEntityCatalog.space.store.getEntityMonitor(this.spaceGuid).getUpdatingSection(action.updatingKey).pipe(
}).pipe(
pairwise(),
filter(([oldS, newS]) => oldS.busy && !newS.busy),
map(([, newS]) => newS),
);
}

updateSpaceQuota$() {
updateSpaceQuota() {
const spaceQuotaGuid = this.editSpaceForm.value.quotaDefinition;
const mon = spaceQuotaGuid ?
richard-cox marked this conversation as resolved.
Show resolved Hide resolved
cfEntityCatalog.spaceQuota.api.associateWithSpace<RequestInfoState>(this.spaceGuid, this.cfGuid, spaceQuotaGuid) :
cfEntityCatalog.spaceQuota.api.disassociateFromSpace<RequestInfoState>(this.spaceGuid, this.cfGuid, this.originalSpaceQuotaGuid)
cfEntityCatalog.spaceQuota.api.associateWithSpace<ActionState>(this.spaceGuid, this.cfGuid, spaceQuotaGuid) :
cfEntityCatalog.spaceQuota.api.disassociateFromSpace<ActionState>(this.spaceGuid, this.cfGuid, this.originalSpaceQuotaGuid)
return mon.pipe(
filter(o => {
return !!o &&
o.updating[AssociateSpaceQuota.UpdateExistingSpaceQuota] &&
!o.updating[AssociateSpaceQuota.UpdateExistingSpaceQuota].busy;
}),
map((state) => state.updating[AssociateSpaceQuota.UpdateExistingSpaceQuota]),
pairwise(),
filter(([oldS, newS]) => oldS.busy && !newS.busy),
map(([, newS]) => newS),
map(stateAction => ({
success: !stateAction.error,
redirect: !stateAction.error,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@ import { PaginationMonitorFactory } from '../../../../store/src/monitors/paginat
import { APIResource } from '../../../../store/src/types/api.types';
import { CFAppState } from '../../cf-app-state';
import { cfEntityCatalog } from '../../cf-entity-catalog';
import {
organizationEntityType,
serviceInstancesEntityType,
servicePlanEntityType,
spaceEntityType,
} from '../../cf-entity-types';
import { organizationEntityType, servicePlanEntityType, spaceEntityType } from '../../cf-entity-types';
import { QParam, QParamJoiners } from '../../shared/q-param';
import { fetchTotalResults } from '../cloud-foundry/cf.helpers';
import { ServicePlanAccessibility } from './services.service';
Expand Down Expand Up @@ -73,11 +68,6 @@ export const isEditServiceInstanceMode = (activatedRoute: ActivatedRoute) => {
return !!cfId && !!serviceInstanceId;
};

export const getServiceInstancesInCf = (cfGuid: string) => {
const paginationKey = createEntityRelationPaginationKey(serviceInstancesEntityType, cfGuid);
return cfEntityCatalog.serviceInstance.store.getPaginationService(cfGuid, paginationKey).entities$;
};

export const fetchServiceInstancesCount = (
cfGuid: string,
orgGuid: string = null,
Expand Down Expand Up @@ -194,26 +184,15 @@ export const populateServicePlanExtraTyped = (servicePlan: APIResource<IServiceP
};
};


export const getServiceBroker = (
serviceBrokerGuid: string,
cfGuid: string,
): EntityService<APIResource<IServiceBroker>> => cfEntityCatalog.serviceBroker.store.getEntityService(serviceBrokerGuid, cfGuid, {});

export const getServiceBrokerName = (
serviceBrokerGuid: string,
cfGuid: string,
): Observable<string> => getServiceBroker(serviceBrokerGuid, cfGuid).waitForEntity$.pipe(
): Observable<string> => cfEntityCatalog.serviceBroker.store.getEntityService(serviceBrokerGuid, cfGuid, {}).waitForEntity$.pipe(
filter(res => !!res),
map(a => a.entity.entity.name),
first()
);

export const getCfService = (
serviceGuid: string,
cfGuid: string,
): EntityService<APIResource<IService>> => cfEntityCatalog.service.store.getEntityService(serviceGuid, cfGuid, {});

export const getCfServiceInstance = (
richard-cox marked this conversation as resolved.
Show resolved Hide resolved
serviceInstanceGuid: string,
cfGuid: string,
Expand Down
Loading