Skip to content

Commit

Permalink
Scaling Related & Minor Fixes (#4156)
Browse files Browse the repository at this point in the history
* Fix delete org when org contains spaces

* Fix scaling related test scripts

* Fix double fetching of missing user relations for getUser
- getUser would first attempt to fetch all users via getUsers
- getUsers could take a long time due to missing relations (users with more than 50 per role)
- getUser wouldn't wait for this to finish and then try and make an individual request to fetch user
- this user would then also be validated and missing relations fetched

* Fix create many services script

* Scaling improvements
- Remove org-space-route relation from orgs and org api requests
- Ensure we don't fetch entity counts unless we need to

* Fix handling of generic errors to cf endpoints
- sometimes errorResponse can be null (for instance timeout)

* Fix SI Delete
- Delete SI success handler was incorrectly clearing pagination instead of just removing entity from pagination

* Fix UPSI Delete
- Delete of entity was fine, however it was not removed from list
- With bug entity was still not visible in list afterwards only due to nulls filtered out in list

* Handle error message being in error.status OR as a string in jetstreamErrorResponse

* Block displaying of service wall and cf routes lists until cf/org/space filters have loaded

* Fix failing test

* Fix cf-user getUsers
  • Loading branch information
richard-cox authored Mar 17, 2020
1 parent 0c2f03e commit 861b9d6
Show file tree
Hide file tree
Showing 27 changed files with 232 additions and 124 deletions.
8 changes: 4 additions & 4 deletions deploy/tools/populate-cf/create-many-apps.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
CREATE=true
CREATE="true"
ORG=many-apps
SPACE=many-apps
APP_PREFIX=many-apps
Expand All @@ -25,12 +25,12 @@ done
echo "Creating $COUNT apps in org '$ORG' space '$SPACE'"

# cf login -a https://api.local.pcfdev.io --skip-ssl-validation
if [ "$CREATE" = true ]; then
if [ "$CREATE" = "true" ]; then
cf create-org $ORG
fi
cf target -o $ORG

if [ "$CREATE" = true ]; then
if [ "$CREATE" = "true" ]; then
cf create-space $SPACE
fi
cf target -s $SPACE
Expand All @@ -48,4 +48,4 @@ do
cf bind-service $APP $SERVICE
fi
done
echo "Created $COUNT apps in org '$ORG' space '$SPACE'"
echo "Created $counter apps in org '$ORG' space '$SPACE'"
13 changes: 8 additions & 5 deletions deploy/tools/populate-cf/create-many-orgs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ COUNT=10
SPACE_COUNT=
DELETE=false

while getopts o:c:s: option
while getopts o:c:s:d: option
do
case "${option}"
in
Expand All @@ -18,22 +18,25 @@ done

echo "Creating $COUNT orgs with $SPACE_COUNT spaces"

counter=0
counter=14
COUNT=$(expr $COUNT - 1)
while [ $counter -le $COUNT ]
do
ORG=$ORG_PREFIX-$counter
if [ "$DELETE" == "true" ]; then
# echo "DELETE $ORG"
cf delete-org $ORG
else
# echo "CREATE $ORG"
cf create-org $ORG
fi

if [ "$SPACE_COUNT" == "true" ]; then
if [ "$SPACE_COUNT" != "" ]; then
# echo "$ORG SPACES: $SPACE_COUNT"
cf target -o $ORG
./create-many-spaces.sh -o "$ORG" -s "$ORG-spaces" -c $SPACE_COUNT -a 0 -r 0
./create-many-spaces.sh -o "$ORG" -s "$ORG-spaces" -c $SPACE_COUNT -a 0 -r 0 -p "false"
fi
((counter++))

done
echo "Created $COUNT orgs with $SPACE_COUNT spaces"
echo "Created $counter orgs with $SPACE_COUNT spaces"
8 changes: 4 additions & 4 deletions deploy/tools/populate-cf/create-many-services.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
CREATE=true
CREATE="true"
ORG=many-apps
SPACE=many-apps
SERVICE_PREFIX=many-services-
Expand All @@ -26,12 +26,12 @@ echo $SERVICE_PLAN

echo "Creating $COUNT service instances in org '$ORG' space '$SPACE'"

if [ "$CREATE" = true ]; then
if [ "$CREATE" = "true" ]; then
cf create-org $ORG
fi
cf target -o $ORG

if [ "$CREATE" = true ]; then
if [ "$CREATE" = "true" ]; then
cf create-space $SPACE
fi
cf target -s $SPACE
Expand All @@ -43,4 +43,4 @@ do
cf create-service "$SERVICE" "$SERVICE_PLAN" "$SERVICE_PREFIX-$counter"
((counter++))
done
echo "Created $COUNT service instances in org '$ORG' space '$SPACE'"
echo "Created $counter service instances in org '$ORG' space '$SPACE'"
11 changes: 6 additions & 5 deletions deploy/tools/populate-cf/create-many-spaces.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
CREATE=true
CREATE_ORG_SPACE="true"
ORG=many-spaces
SPACE_PREFIX=many-spaces
COUNT=10
Expand All @@ -10,11 +10,12 @@ SERVICE_COUNT=0
SERVICE=
SERVICE_PLAN=

while getopts o:s:c:a:r:d:j:v:i: option
while getopts o:p:s:c:a:r:d:j:v:i: option
do
case "${option}"
in
o) ORG=${OPTARG};;
p) CREATE_ORG_SPACE=${OPTARG};;
s) SPACE_PREFIX=${OPTARG};;
c) COUNT=${OPTARG};;
a) APP_COUNT=${OPTARG};;
Expand All @@ -29,7 +30,7 @@ done
echo "Creating $COUNT spaces with '$APP_COUNT' apps in org '$ORG'"


if [ "$CREATE" = true ]; then
if [ "$CREATE_ORG_SPACE" = "true" ]; then
cf create-org $ORG
fi
cf target -o $ORG
Expand All @@ -45,6 +46,6 @@ do
if [ -n "$SERVICE" ]; then
./create-many-services.sh -o "$ORG" -s "$SPACE" -a "$SERVICE_INSTANCE" -c $SERVICE_COUNT -e false -v "$SERVICE" -i "$SERVICE_PLAN"
fi
./create-many-apps.sh -o "$ORG" -s "$SPACE" -a "$SPACE-app-" -c $APP_COUNT -r "false" -r $APP_ROUTES -d "$DOMAIN" -v "$SERVICE_INSTANCE-0"
./create-many-apps.sh -o "$ORG" -s "$SPACE" -a "$SPACE-app-" -c $APP_COUNT -r "false" -r $APP_ROUTES -d "$DOMAIN" -v "$SERVICE_INSTANCE-0" -e $CREATE_ORG_SPACE
done
echo "Created $COUNT spaces with '$APP_COUNT' apps in org '$ORG'"
echo "Created $counter spaces with '$APP_COUNT' apps in org '$ORG'"
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { HttpHeaders, HttpRequest } from '@angular/common/http';
import { HttpParams, HttpRequest } from '@angular/common/http';

import { IUpdateOrganization } from '../../../core/src/core/cf-api.types';
import { getActions } from '../../../store/src/actions/action.helper';
import { PaginatedAction } from '../../../store/src/types/pagination.types';
import { ICFAction } from '../../../store/src/types/request.types';
import { CFEntityConfig } from '../cf-types';
import { cfEntityFactory } from '../cf-entity-factory';
import {
cfUserEntityType,
Expand All @@ -13,6 +12,7 @@ import {
spaceEntityType,
spaceWithOrgEntityType,
} from '../cf-entity-types';
import { CFEntityConfig } from '../cf-types';
import {
createEntityRelationPaginationKey,
EntityInlineChildAction,
Expand Down Expand Up @@ -173,9 +173,11 @@ export class DeleteOrganization extends CFStartAction implements ICFAction {
'DELETE',
`organizations/${guid}`,
{
params: new HttpHeaders({
recursive: 'true',
async: 'false'
params: new HttpParams({
fromObject: {
recursive: 'true',
async: 'false'
}
})
}
);
Expand Down
12 changes: 7 additions & 5 deletions src/frontend/packages/cloud-foundry/src/actions/route.actions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { HttpParams, HttpRequest } from '@angular/common/http';

import { getActions } from '../../../store/src/actions/action.helper';
import { PaginatedAction } from '../../../store/src/types/pagination.types';
import { PaginatedAction, PaginationParam } from '../../../store/src/types/pagination.types';
import { ICFAction } from '../../../store/src/types/request.types';
import { cfEntityFactory } from '../cf-entity-factory';
import { applicationEntityType, domainEntityType, routeEntityType, spaceEntityType } from '../cf-entity-types';
Expand All @@ -9,7 +11,6 @@ import {
EntityInlineParentAction,
} from '../entity-relations/entity-relations.types';
import { CFStartAction } from './cf-action.types';
import { HttpRequest, HttpParams } from '@angular/common/http';

export const CREATE_ROUTE = '[Route] Create start';
export const CREATE_ROUTE_SUCCESS = '[Route] Create success';
Expand Down Expand Up @@ -123,10 +124,11 @@ export class UnmapRoute extends BaseRouteAction {
}

export class GetAllRoutes extends CFStartAction implements PaginatedAction, EntityInlineParentAction, ICFAction {
paginationKey: string;
endpointType = 'cf';
paginationKey: string;
constructor(
public endpointGuid: string,
pKey?: string,
public includeRelations = [
createEntityRelationKey(routeEntityType, applicationEntityType),
createEntityRelationKey(routeEntityType, domainEntityType),
Expand All @@ -139,13 +141,13 @@ export class GetAllRoutes extends CFStartAction implements PaginatedAction, Enti
'GET',
'routes'
);
this.paginationKey = createEntityRelationPaginationKey('cf', this.endpointGuid);
this.paginationKey = pKey || createEntityRelationPaginationKey('cf', this.endpointGuid);
}
entity = [cfEntityFactory(routeEntityType)];
entityType = routeEntityType;
options: HttpRequest<any>;
actions = getActions('Routes', 'Fetch all');
initialParams = {
initialParams: PaginationParam = {
'results-per-page': 100,
page: 1,
'order-direction': 'desc',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class ChangeUserRole extends CFStartAction implements EntityRequestAction
this.entity = cfEntityFactory(this.entityType);
}

guid: string; you
guid: string;
entity: EntitySchema;
entityType: string;
options: HttpRequest<any>;
Expand Down
7 changes: 6 additions & 1 deletion src/frontend/packages/cloud-foundry/src/cf-error-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ export interface CfErrorObject {
export type CfErrorResponse = CfErrorObject | string | any;

function isCfError(errorResponse: CfErrorResponse): CfErrorObject {
return !!errorResponse.code && !!errorResponse.description && !!errorResponse.error_code ? errorResponse as CfErrorObject : null;
return !!errorResponse &&
!!errorResponse.code &&
!!errorResponse.description &&
!!errorResponse.error_code ?
errorResponse as CfErrorObject :
null;
}

export function getCfError(jetStreamErrorResponse: JetStreamErrorResponse<CfErrorResponse>): string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
import { OrchestratedActionBuilders } from '../../../store/src/entity-catalog/action-orchestrator/action-orchestrator';
import { GetAllOrganizations, DeleteOrganization, UpdateOrganization, GetOrganization } from '../actions/organization.actions';
import { IUpdateOrganization } from '../../../core/src/core/cf-api.types';
import {
DeleteOrganization,
GetAllOrganizations,
GetOrganization,
UpdateOrganization,
} from '../actions/organization.actions';
import { CFBasePipelineRequestActionMeta } from '../cf-entity-generator';
import { CFOrchestratedActionBuilders } from './cf.action-builder.types';

export const organizationActionBuilders = {
export interface OrganizationActionBuilders extends CFOrchestratedActionBuilders {
get: (
guid: string,
endpointGuid: string,
{ includeRelations, populateMissing }?: CFBasePipelineRequestActionMeta
) => GetOrganization;
getMultiple: (
endpointGuid: string,
paginationKey: string,
{ includeRelations, populateMissing }?: CFBasePipelineRequestActionMeta
) => GetAllOrganizations;
remove: (guid: string, endpointGuid: string) => DeleteOrganization;
update: (guid: string, endpointGuid: string, updatedOrg: IUpdateOrganization) => UpdateOrganization;
}

export const organizationActionBuilders: OrganizationActionBuilders = {
get: (
guid,
endpointGuid,
Expand All @@ -20,4 +40,4 @@ export const organizationActionBuilders = {
endpointGuid,
updatedOrg
)
} as OrchestratedActionBuilders;
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const routesActionBuilders = {
endpointGuid,
paginationKey: string,
{ includeRelations, populateMissing }: CFBasePipelineRequestActionMeta = {}
) => new GetAllRoutes(endpointGuid, includeRelations, populateMissing),
) => new GetAllRoutes(endpointGuid, paginationKey, includeRelations, populateMissing),
unmap: (
guid: string,
appGuid: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,15 @@ export function fetchTotalResults(
newAction.flattenPagination
)
});
// Ensure the request is made by sub'ing to the entities observable
pagObs.entities$.pipe(
first(),
).subscribe();

return pagObs.pagination$.pipe(
return combineLatest(
pagObs.entities$, // Ensure the request is made by sub'ing to the entities observable
pagObs.pagination$
).pipe(
map(([, pagination]) => pagination),
filter(pagination => !!pagination && !!pagination.pageRequests && !!pagination.pageRequests[1] && !pagination.pageRequests[1].busy),
first(),
map(pag => pag.totalResults)
map(pagination => pagination.totalResults)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
organizationEntityType,
privateDomainsEntityType,
quotaDefinitionEntityType,
routeEntityType,
spaceEntityType,
} from '../../../../../cloud-foundry/src/cf-entity-types';
import {
Expand All @@ -24,6 +23,7 @@ import { IApp, ICfV2Info, IOrganization, ISpace } from '../../../../../core/src/
import { EndpointsService } from '../../../../../core/src/core/endpoints.service';
import { GetAllEndpoints } from '../../../../../store/src/actions/endpoint.actions';
import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog.service';
import { IEntityMetadata } from '../../../../../store/src/entity-catalog/entity-catalog.types';
import { EntityService } from '../../../../../store/src/entity-service';
import { EntityServiceFactory } from '../../../../../store/src/entity-service-factory.service';
import { endpointSchemaKey } from '../../../../../store/src/helpers/entity-factory';
Expand All @@ -35,9 +35,12 @@ import {
import { APIResource, EntityInfo } from '../../../../../store/src/types/api.types';
import { EndpointModel, EndpointUser } from '../../../../../store/src/types/endpoint.types';
import { PaginatedAction } from '../../../../../store/src/types/pagination.types';
import { GetAllRoutes } from '../../../actions/route.actions';
import { GetSpaceRoutes } from '../../../actions/space.actions';
import { cfEntityFactory } from '../../../cf-entity-factory';
import { CF_ENDPOINT_TYPE } from '../../../cf-types';
import { CfInfoDefinitionActionBuilders } from '../../../entity-action-builders/cf-info.action-builders';
import { OrganizationActionBuilders } from '../../../entity-action-builders/organization.action-builders';
import { CfUserService } from '../../../shared/data-services/cf-user.service';
import { QParam, QParamJoiners } from '../../../shared/q-param';
import { ActiveRouteCfOrgSpace } from '../cf-page.types';
Expand Down Expand Up @@ -81,7 +84,8 @@ export class CloudFoundryEndpointService {
const paginationKey = cfGuid ?
createEntityRelationPaginationKey(endpointSchemaKey, cfGuid)
: createEntityRelationPaginationKey(endpointSchemaKey);
const organizationEntity = entityCatalog.getEntity(CF_ENDPOINT_TYPE, organizationEntityType);
const organizationEntity = entityCatalog
.getEntity<IEntityMetadata, any, OrganizationActionBuilders>(CF_ENDPOINT_TYPE, organizationEntityType);
const actionBuilder = organizationEntity.actionOrchestrator.getActionBuilder('getMultiple');
const getAllOrganizationsAction = actionBuilder(cfGuid, paginationKey,
{
Expand All @@ -90,10 +94,8 @@ export class CloudFoundryEndpointService {
createEntityRelationKey(organizationEntityType, domainEntityType),
createEntityRelationKey(organizationEntityType, quotaDefinitionEntityType),
createEntityRelationKey(organizationEntityType, privateDomainsEntityType),
createEntityRelationKey(spaceEntityType, routeEntityType), // Not really needed at top level, but if we drop down into an org with
// lots of spaces it saves spaces x routes requests
], populateMissing: false
}) as PaginatedAction;
});
return getAllOrganizationsAction;
}
static createGetAllOrganizationsLimitedSchema(cfGuid: string) {
Expand Down Expand Up @@ -127,6 +129,30 @@ export class CloudFoundryEndpointService {
return fetchTotalResults(action, store, pmf);
}

public static fetchRouteCount(
store: Store<CFAppState>,
pmf: PaginationMonitorFactory,
cfGuid: string,
orgGuid?: string,
spaceGuid?: string)
: Observable<number> {
if (spaceGuid) {
const spaceAction =
new GetSpaceRoutes(spaceGuid, cfGuid, createEntityRelationPaginationKey(spaceEntityType, spaceGuid), [], false, false);
return fetchTotalResults(spaceAction, store, pmf);
}

const parentSchemaKey = orgGuid ? organizationEntityType : 'cf';
const uniqueKey = orgGuid || cfGuid;
const action = new GetAllRoutes(cfGuid, createEntityRelationPaginationKey(parentSchemaKey, uniqueKey), [], false);
action.initialParams = {};
action.initialParams.q = [];
if (orgGuid) {
action.initialParams.q.push(new QParam('organization_guid', orgGuid, QParamJoiners.in).toString());
}
return fetchTotalResults(action, store, pmf);
}

constructor(
public activeRouteCfOrgSpace: ActiveRouteCfOrgSpace,
private store: Store<CFAppState>,
Expand Down
Loading

0 comments on commit 861b9d6

Please sign in to comment.