Skip to content

Commit

Permalink
Ensure both private and shared domains are included in domain lists (#…
Browse files Browse the repository at this point in the history
…3695)

* Ensure both private and shared domains are included in create/map drop downs
- Before we were using `shared_domains` to fetch domains. This fetched all shared domains of the cf
- In a lot of cases we just needed the domains available to the org
- So the following usages have been updated to use org/<guid>/domain
  - app routes table
  - app create/bind stepper create form
  - app create/bind stepper bind form
  - deploy app stepper overrides step
- Note - The create app stepper worked before as it fetched them directly from the org entity

* Fix linting

* Fix unit tests

* Fix GET_ORGANIZATION_DOMAINS strings
  • Loading branch information
richard-cox authored and nwmac committed Jul 16, 2019
1 parent 5b225ab commit e87f91e
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 80 deletions.
7 changes: 5 additions & 2 deletions src/frontend/packages/core/src/core/cf-api.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,11 @@ export interface IOrganization<spaceT = APIResource<ISpace>[]> {

export interface IDomain {
name: string;
router_group_guid?: any;
router_group_type?: any;
router_group_guid?: string;
router_group_type?: string;
owning_organization_guid?: string;
owning_organization_url?: string;
shared_organizations_url?: string;
}

export interface ICfV2Info {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
UpdateApplication,
UpdateExistingApplication,
} from '../../../../store/src/actions/application.actions';
import { GetAllOrganizationDomains } from '../../../../store/src/actions/organization.actions';
import { GetSpace } from '../../../../store/src/actions/space.actions';
import { AppState } from '../../../../store/src/app-state';
import {
Expand Down Expand Up @@ -41,7 +42,7 @@ import { endpointEntitiesSelector } from '../../../../store/src/selectors/endpoi
import { APIResource, EntityInfo } from '../../../../store/src/types/api.types';
import { AppStat } from '../../../../store/src/types/app-metadata.types';
import { PaginationEntityState } from '../../../../store/src/types/pagination.types';
import { IApp, IAppSummary, IOrganization, ISpace } from '../../core/cf-api.types';
import { IApp, IAppSummary, IDomain, IOrganization, ISpace } from '../../core/cf-api.types';
import { EntityService } from '../../core/entity-service';
import { EntityServiceFactory } from '../../core/entity-service-factory.service';
import {
Expand Down Expand Up @@ -144,6 +145,7 @@ export class ApplicationService {
applicationState$: Observable<ApplicationStateData>;
applicationUrl$: Observable<string>;
applicationRunning$: Observable<boolean>;
orgDomains$: Observable<APIResource<IDomain>[]>;

/**
* Fetch the current state of the app (given it's instances) as an object ready
Expand Down Expand Up @@ -269,6 +271,25 @@ export class ApplicationService {
map(app => app ? app.app.entity.state === 'STARTED' : false)
);

// In an ideal world we'd get domains inline with the application, however the inline path from app to org domains exceeds max cf depth
// of 2 (app --> space --> org --> domains).
this.orgDomains$ = this.appOrg$.pipe(
switchMap(org => {
const domainsAction = new GetAllOrganizationDomains(org.metadata.guid, this.cfGuid);
return getPaginationObservables<APIResource<IDomain>>(
{
store: this.store,
action: domainsAction,
paginationMonitor: this.paginationMonitorFactory.create(
domainsAction.paginationKey,
entityFactory(domainSchemaKey)
)
},
true
).entities$;
}),
);

}

private constructStatusObservables() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,17 @@ import { DatePipe } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs';
import { first } from 'rxjs/operators';

import { AppState } from '../../../../../../../../../store/src/app-state';
import { CurrentUserPermissionsService } from '../../../../../../../core/current-user-permissions.service';
import { ConfirmationDialogService } from '../../../../../../../shared/components/confirmation-dialog.service';
import {
CfAppRoutesListConfigService,
} from '../../../../../../../shared/components/list/list-types/app-route/cf-app-routes-list-config.service';
import { ListConfig } from '../../../../../../../shared/components/list/list.component.types';
import { PaginationMonitorFactory } from '../../../../../../../shared/monitors/pagination-monitor.factory';
import { first } from 'rxjs/operators';
import { AppState } from '../../../../../../../../../store/src/app-state';
import { ApplicationService } from '../../../../../application.service';
import { APIResource } from '../../../../../../../../../store/src/types/api.types';
import { FetchAllDomains } from '../../../../../../../../../store/src/actions/domains.actions';
import { getPaginationObservables } from '../../../../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper';
import { entityFactory, domainSchemaKey } from '../../../../../../../../../store/src/helpers/entity-factory';
import { CfOrgSpaceDataService } from '../../../../../../../shared/data-services/cf-org-space-service.service';
import { ApplicationService } from '../../../../../application.service';

@Component({
selector: 'app-routes-tab',
Expand All @@ -44,25 +39,11 @@ export class RoutesTabComponent implements OnInit {

paginationSubscription: Subscription;
constructor(
private store: Store<AppState>,
private appService: ApplicationService,
private paginationMonitorFactory: PaginationMonitorFactory
) {
}
ngOnInit() {
const { cfGuid } = this.appService;
const action = new FetchAllDomains(cfGuid);
getPaginationObservables<APIResource>(
{
store: this.store,
action,
paginationMonitor: this.paginationMonitorFactory.create(
action.paginationKey,
entityFactory(domainSchemaKey)
)
},
true
).entities$.pipe(
this.appService.orgDomains$.pipe(
first()
).subscribe();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { combineLatest, Observable, of as observableOf, Subscription } from 'rxj
import { filter, first, map, share, startWith, switchMap } from 'rxjs/operators';

import { SaveAppOverrides } from '../../../../../../store/src/actions/deploy-applications.actions';
import { FetchAllDomains } from '../../../../../../store/src/actions/domains.actions';
import { GetAllOrganizationDomains } from '../../../../../../store/src/actions/organization.actions';
import { GetAllStacks } from '../../../../../../store/src/actions/stack.action';
import { AppState } from '../../../../../../store/src/app-state';
import { entityFactory } from '../../../../../../store/src/helpers/entity-factory';
Expand Down Expand Up @@ -103,7 +103,7 @@ export class DeployApplicationOptionsStepComponent implements OnInit, OnDestroy
// Create the domains list for the domains drop down
this.domains$ = cfDetails$.pipe(
switchMap(cfDetails => {
const action = new FetchAllDomains(cfDetails.cloudFoundry);
const action = new GetAllOrganizationDomains(cfDetails.org, cfDetails.cloudFoundry);
return getPaginationObservables<APIResource<IDomain>>(
{
store: this.store,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
AssociateRouteWithAppApplication,
GetAppRoutes,
} from '../../../../../../store/src/actions/application-service-routes.actions';
import { FetchAllDomains } from '../../../../../../store/src/actions/domains.actions';
import { CreateRoute } from '../../../../../../store/src/actions/route.actions';
import { RouterNav } from '../../../../../../store/src/actions/router.actions';
import { GetSpace } from '../../../../../../store/src/actions/space.actions';
Expand All @@ -23,7 +22,6 @@ import {
} from '../../../../../../store/src/helpers/entity-factory';
import { createEntityRelationKey } from '../../../../../../store/src/helpers/entity-relations/entity-relations.types';
import { RequestInfoState } 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 { Route, RouteMode } from '../../../../../../store/src/types/route.types';
Expand Down Expand Up @@ -114,22 +112,9 @@ export class AddRoutesComponent implements OnInit, OnDestroy {
}
}));

const fetchAllDomainsAction = new FetchAllDomains(this.cfGuid);
const sharedDomains$ = getPaginationObservables<APIResource>(
{
store: this.store,
action: fetchAllDomainsAction,
paginationMonitor: this.paginationMonitorFactory.create(
fetchAllDomainsAction.paginationKey,
entityFactory(domainSchemaKey)
)
},
true
).entities$;

const space$ = sharedDomains$.pipe(
// We don't need the shared domains, but we need them fetched first so we get the router_group_type
switchMap(sharedDomains => this.appService.waitForAppEntity$
const space$ = this.applicationService.orgDomains$.pipe(
// We don't need the domains, but we need them fetched first so we get the router_group_type
switchMap(() => this.appService.waitForAppEntity$
.pipe(
switchMap(app => {
this.spaceGuid = app.entity.entity.space_guid;
Expand All @@ -141,8 +126,8 @@ export class AddRoutesComponent implements OnInit, OnDestroy {
);
return spaceService.waitForEntity$;
}),
filter(({ entity, entityRequestInfo }) => !!entity.entity.domains),
tap(({ entity, entityRequestInfo }) => {
filter(({ entity }) => !!entity.entity.domains),
tap(({ entity }) => {
this.domains = [];
const domains = entity.entity.domains;
domains.forEach(domain => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { BehaviorSubject, Subscription } from 'rxjs';
import { filter, tap } from 'rxjs/operators';
import { tap } from 'rxjs/operators';

import { AppState } from '../../../../../../store/src/app-state';
import { APIResource } from '../../../../../../store/src/types/api.types';
import {
CfAppMapRoutesListConfigService,
} from '../../../../shared/components/list/list-types/app-route/cf-app-map-routes-list-config.service';
import { CfAppRoutesDataSource } from '../../../../shared/components/list/list-types/app-route/cf-app-routes-data-source';
import { ListConfig } from '../../../../shared/components/list/list.component.types';
import { PaginationMonitorFactory } from '../../../../shared/monitors/pagination-monitor.factory';
import { APIResource } from '../../../../../../store/src/types/api.types';
import { AppState } from '../../../../../../store/src/app-state';
import { ApplicationService } from '../../application.service';
import { FetchAllDomains } from '../../../../../../store/src/actions/domains.actions';
import { getPaginationObservables } from '../../../../../../store/src/reducers/pagination-reducer/pagination-reducer.helper';
import { entityFactory, domainSchemaKey } from '../../../../../../store/src/helpers/entity-factory';

@Component({
selector: 'app-map-routes',
Expand Down Expand Up @@ -53,18 +50,7 @@ export class MapRoutesComponent implements OnInit, OnDestroy {
)
.subscribe();

const action = new FetchAllDomains(this.appService.cfGuid);
this.paginationSubscription = getPaginationObservables<APIResource>(
{
store: this.store,
action,
paginationMonitor: this.paginationMonitorFactory.create(
action.paginationKey,
entityFactory(domainSchemaKey)
)
},
true
).entities$.subscribe();
this.paginationSubscription = this.appService.orgDomains$.subscribe();
}

ngOnDestroy(): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Store } from '@ngrx/store';
import { APIResource, EntityInfo } from '../../store/src/types/api.types';
import { ApplicationData, ApplicationService } from '../src/features/applications/application.service';
import { Observable, of as observableOf } from 'rxjs';

import { AppState } from '../../store/src/app-state';
import { RequestInfoState } from '../../store/src/reducers/api-request-reducer/types';
import { APIResource, EntityInfo } from '../../store/src/types/api.types';
import { AppStat } from '../../store/src/types/app-metadata.types';
import { IApp, IAppSummary, IDomain, ISpace } from '../src/core/cf-api.types';
import { EntityServiceFactory } from '../src/core/entity-service-factory.service';
import { ApplicationData, ApplicationService } from '../src/features/applications/application.service';
import {
ApplicationEnvVarsHelper,
EnvVarStratosProject,
ApplicationEnvVarsHelper
} from '../src/features/applications/application/application-tabs-base/tabs/build-tab/application-env-vars.service';
import { ApplicationStateData, ApplicationStateService } from '../src/shared/components/application-state/application-state.service';
import { ISpace, IApp, IAppSummary } from '../src/core/cf-api.types';
import { AppState } from '../../store/src/app-state';
import { EntityServiceFactory } from '../src/core/entity-service-factory.service';
import {
ApplicationStateData,
ApplicationStateService,
} from '../src/shared/components/application-state/application-state.service';
import { PaginationMonitorFactory } from '../src/shared/monitors/pagination-monitor.factory';
import { Observable, of as observableOf } from 'rxjs';

function createEntity<T>(entity: T): APIResource<T> {
return {
Expand Down Expand Up @@ -77,6 +81,7 @@ export class ApplicationServiceMock {
});
appSpace$: Observable<APIResource<ISpace>> = observableOf(createEntity<ISpace>({} as ISpace));
applicationRunning$: Observable<boolean> = observableOf(false);
orgDomains$: Observable<APIResource<IDomain>[]> = observableOf([]);
}

export function generateTestApplicationServiceProvider(appGuid, cfGuid) {
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/packages/store/src/actions/domains.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class FetchDomain extends CFStartAction implements ICFAction {
constructor(public guid: string, public endpointGuid: string) {
super();
this.options = new RequestOptions();
this.options.url = `shared_domains/${guid}`;
this.options.url = `domains/${guid}`;
this.options.method = 'get';
this.options.params = new URLSearchParams();
}
Expand All @@ -30,7 +30,7 @@ export class FetchAllDomains extends CFStartAction implements PaginatedAction {
constructor(public endpointGuid: string, public flattenPagination = true) {
super();
this.options = new RequestOptions();
this.options.url = 'shared_domains';
this.options.url = 'domains';
this.options.method = 'get';
this.options.params = new URLSearchParams();
this.paginationKey = createEntityRelationPaginationKey(endpointSchemaKey, endpointGuid);
Expand Down
51 changes: 48 additions & 3 deletions src/frontend/packages/store/src/actions/organization.actions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { RequestOptions, URLSearchParams, RequestMethod } from '@angular/http';
import { RequestMethod, RequestOptions, URLSearchParams } from '@angular/http';

import { IUpdateOrganization } from '../../../core/src/core/cf-api.types';
import { cfUserSchemaKey, entityFactory, organizationSchemaKey, spaceSchemaKey } from '../helpers/entity-factory';
import { EntityInlineChildAction, EntityInlineParentAction } from '../helpers/entity-relations/entity-relations.types';
import {
cfUserSchemaKey,
domainSchemaKey,
entityFactory,
organizationSchemaKey,
spaceSchemaKey,
} from '../helpers/entity-factory';
import {
createEntityRelationPaginationKey,
EntityInlineChildAction,
EntityInlineParentAction,
} from '../helpers/entity-relations/entity-relations.types';
import { PaginatedAction } from '../types/pagination.types';
import { CFStartAction, ICFAction } from '../types/request.types';
import { getActions } from './action.helper';
Expand All @@ -20,6 +30,10 @@ export const GET_ORGANIZATION_SPACES = '[Space] Get all org spaces';
export const GET_ORGANIZATION_SPACES_SUCCESS = '[Space] Get all org spaces success';
export const GET_ORGANIZATION_SPACES_FAILED = '[Space] Get all org spaces failed';

export const GET_ORGANIZATION_DOMAINS = '[Organization] Get all org domains';
export const GET_ORGANIZATION_DOMAINS_SUCCESS = '[Organization] Get all org domains success';
export const GET_ORGANIZATION_DOMAINS_FAILED = '[Organization] Get all org domains failed';

export const DELETE_ORGANIZATION = '[Organization] Delete organization';
export const DELETE_ORGANIZATION_SUCCESS = '[Organization] Delete organization success';
export const DELETE_ORGANIZATION_FAILED = '[Organization] Delete organization failed';
Expand Down Expand Up @@ -77,6 +91,37 @@ export class GetAllOrganizationSpaces extends CFStartAction implements Paginated
parentEntitySchema = entityFactory(organizationSchemaKey);
}

export class GetAllOrganizationDomains extends CFStartAction implements PaginatedAction, EntityInlineParentAction, EntityInlineChildAction {
constructor(
public orgGuid: string,
public endpointGuid: string,
public paginationKey: string = null,
public includeRelations = [],
public populateMissing = true
) {
super();
if (!this.paginationKey) {
this.paginationKey = createEntityRelationPaginationKey(organizationSchemaKey, orgGuid);
}
this.options = new RequestOptions();
this.options.url = `organizations/${orgGuid}/domains`;
this.options.method = 'get';
this.parentGuid = orgGuid;
}
actions = [GET_ORGANIZATION_DOMAINS, GET_ORGANIZATION_DOMAINS_SUCCESS, GET_ORGANIZATION_DOMAINS_FAILED];
entity = entityFactory(domainSchemaKey);
entityKey = domainSchemaKey;
options: RequestOptions;
flattenPagination = true;
initialParams = {
'results-per-page': 100,
'order-direction': 'desc',
'order-direction-field': 'name'
};
parentGuid: string;
parentEntitySchema = entityFactory(organizationSchemaKey);
}

export class GetAllOrganizations extends CFStartAction implements PaginatedAction, EntityInlineParentAction {
constructor(
public paginationKey: string,
Expand Down

0 comments on commit e87f91e

Please sign in to comment.