Skip to content

Commit

Permalink
use IEventManager in place of concrete implementation
Browse files Browse the repository at this point in the history
- Introduce IEventManager interface and refactor EventManager to
  implement it
- Refactor BillingProvider and Services to use IEventManager
- Make eventManager property optional in ControlPlane and
  CoreApplicationPlane
- Remove unused IncomingEventMetadata and OutgoingEventMetadata
  interfaces
  • Loading branch information
suhussai committed May 1, 2024
1 parent ce567ea commit 799a55a
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 231 deletions.
372 changes: 222 additions & 150 deletions API.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/control-plane/auth/cognito-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export interface CognitoAuthProps {
readonly systemAdminEmail: string;

/**
* The callback URL for the control plane. If not provided, defaults to 'http://localhost'.
* @default - 'http://localhost'
* The callback URL for the control plane.
* @default 'http://localhost'
*/
readonly controlPlaneCallbackURL?: string;

Expand Down
8 changes: 4 additions & 4 deletions src/control-plane/billing/billing-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { IFunction } from 'aws-cdk-lib/aws-lambda';
import { NagSuppressions } from 'cdk-nag';
import { Construct } from 'constructs';
import { IBilling, IFunctionTrigger } from './billing-interface';
import { EventManager, DetailType } from '../../utils';
import { DetailType, IEventManager } from '../../utils';

/**
* Encapsulates the list of properties for a BillingProvider.
Expand All @@ -21,9 +21,9 @@ export interface BillingProviderProps {
readonly billing: IBilling;

/**
* An EventManager object to help coordinate events.
* An IEventManager object to help coordinate events.
*/
readonly eventManager: EventManager;
readonly eventManager: IEventManager;

/**
* An API Gateway Resource for the BillingProvider to use
Expand Down Expand Up @@ -143,7 +143,7 @@ export class BillingProvider extends Construct {
}

private createEventTarget(
eventManager: EventManager,
eventManager: IEventManager,
defaultEvent: DetailType,
fn?: IFunction | IFunctionTrigger
) {
Expand Down
47 changes: 38 additions & 9 deletions src/control-plane/control-plane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,63 @@ import { Services } from './services';
import { Tables } from './tables';
import { TenantConfigService } from './tenant-config/tenant-config-service';
import { DestroyPolicySetter } from '../cdk-aspect/destroy-policy-setter';
import { setTemplateDesc, DetailType, EventManager } from '../utils';
import { setTemplateDesc, DetailType, EventManager, IEventManager } from '../utils';

export interface ControlPlaneProps {
/**
* The authentication provider for the control plane.
*/
readonly auth: IAuth;

/**
* The billing provider configuration.
*/
readonly billing?: IBilling;
readonly eventManager: EventManager;

/**
* (Optional) If true, the API Gateway will not log requests to the CloudWatch Logs.
* (Default: false)
* The event manager instance. If not provided, a new instance will be created.
*/
readonly eventManager?: EventManager;

/**
* If true, the API Gateway will not log requests to the CloudWatch Logs.
* @default false
*/
readonly disableAPILogging?: boolean;
}

export class ControlPlane extends Construct {
/**
* The URL of the control plane API Gateway.
*/
readonly controlPlaneAPIGatewayUrl: string;

/**
* The Tables instance containing the DynamoDB tables for tenant data and configurations.
*/
readonly tables: Tables;

/**
* The EventManager instance that allows connecting to events flowing between
* the Control Plane and other components.
*/
readonly eventManager: IEventManager;

constructor(scope: Construct, id: string, props: ControlPlaneProps) {
super(scope, id);
setTemplateDesc(this, 'SaaS Builder Toolkit - CoreApplicationPlane (uksb-1tupboc57)');

cdk.Aspects.of(this).add(new DestroyPolicySetter());

// todo: decompose 'Tables' into purpose-specific constructs (ex. TenantManagement)
this.tables = new Tables(this, 'tables-stack');

this.eventManager = props.eventManager ?? new EventManager(this, 'EventManager');

// todo: decompose 'Services' into purpose-specific constructs (ex. TenantManagement)
const services = new Services(this, 'services-stack', {
tables: this.tables,
eventManager: props.eventManager,
eventManager: this.eventManager,
});

const tenantConfigService = new TenantConfigService(this, 'auth-info-service-stack', {
Expand All @@ -49,6 +77,7 @@ export class ControlPlane extends Construct {
tenantDetailsTenantConfigColumn: this.tables.tenantConfigColumn,
});

// todo: decompose 'ControlPlaneAPI' into purpose-specific constructs (ex. TenantManagement)
const controlPlaneAPI = new ControlPlaneAPI(this, 'controlplane-api-stack', {
auth: props.auth,
disableAPILogging: props.disableAPILogging,
Expand All @@ -58,12 +87,12 @@ export class ControlPlane extends Construct {

this.controlPlaneAPIGatewayUrl = controlPlaneAPI.apiUrl;

props.eventManager.addTargetToEvent(
this.eventManager.addTargetToEvent(
DetailType.PROVISION_SUCCESS,
controlPlaneAPI.tenantUpdateServiceTarget
);

props.eventManager.addTargetToEvent(
this.eventManager.addTargetToEvent(
DetailType.DEPROVISION_SUCCESS,
controlPlaneAPI.tenantUpdateServiceTarget
);
Expand All @@ -74,14 +103,14 @@ export class ControlPlane extends Construct {
});

new cdk.CfnOutput(this, 'eventBridgeArn', {
value: props.eventManager.eventBus.eventBusArn,
value: this.eventManager.busArn,
key: 'eventBridgeArn',
});

if (props.billing) {
const billingTemplate = new BillingProvider(this, 'Billing', {
billing: props.billing,
eventManager: props.eventManager,
eventManager: this.eventManager,
controlPlaneAPIBillingResource: controlPlaneAPI.billingResource,
});

Expand Down
7 changes: 5 additions & 2 deletions src/control-plane/integ.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class IntegStack extends cdk.Stack {

const eventManager = new EventManager(this, 'EventManager');

new ControlPlane(this, 'ControlPlane', {
const controlPlane = new ControlPlane(this, 'ControlPlane', {
auth: cognitoAuth,
eventManager: eventManager,
});
Expand All @@ -33,7 +33,10 @@ export class IntegStack extends cdk.Stack {
eventBus: eventManager.eventBus,
enabled: true,
eventPattern: {
source: [eventManager.controlPlaneEventSource, eventManager.applicationPlaneEventSource],
source: [
controlPlane.eventManager.controlPlaneEventSource,
controlPlane.eventManager.applicationPlaneEventSource,
],
},
});

Expand Down
8 changes: 4 additions & 4 deletions src/control-plane/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { Runtime, LayerVersion, Function } from 'aws-cdk-lib/aws-lambda';
import { NagSuppressions } from 'cdk-nag';
import { Construct } from 'constructs';
import { Tables } from './tables';
import { DetailType, EventManager } from '../utils';
import { DetailType, IEventManager } from '../utils';

export interface ServicesProps {
readonly tables: Tables;
readonly eventManager: EventManager;
readonly eventManager: IEventManager;
}

export class Services extends Construct {
Expand All @@ -27,7 +27,7 @@ export class Services extends Construct {
});

props.tables.tenantDetails.grantReadWriteData(tenantManagementExecRole);
props.eventManager.eventBus.grantPutEventsTo(tenantManagementExecRole);
props.eventManager.grantPutEventsTo(tenantManagementExecRole);

tenantManagementExecRole.addManagedPolicy(
ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')
Expand Down Expand Up @@ -77,7 +77,7 @@ export class Services extends Construct {
LayerVersion.fromLayerVersionArn(this, 'LambdaPowerTools', lambdaPowerToolsLayerARN),
],
environment: {
EVENTBUS_NAME: props.eventManager.eventBus.eventBusName,
EVENTBUS_NAME: props.eventManager.busName,
EVENT_SOURCE: props.eventManager.controlPlaneEventSource,
TENANT_DETAILS_TABLE: props.tables.tenantDetails.tableName,
ONBOARDING_DETAIL_TYPE: DetailType.ONBOARDING_REQUEST,
Expand Down
64 changes: 11 additions & 53 deletions src/core-app-plane/core-app-plane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,6 @@ import { BashJobOrchestrator } from './bash-job-orchestrator';
import { BashJobRunner } from './bash-job-runner';
import { EventManager, DetailType, setTemplateDesc } from '../utils';

/**
* Provides metadata for outgoing events.
*/
export interface OutgoingEventMetadata {
/**
* The detailType to set in the outgoing event.
*/
readonly detailType: string;

/**
* The source to set in the outgoing event.
*
* @default CoreApplicationPlaneProps.applicationPlaneEventSource
*/
readonly source?: string;
}

/**
* Provides metadata for incoming events.
*/
export interface IncomingEventMetadata {
/**
* The list of detailTypes to listen for in the incoming event.
*/
readonly detailType: string[];

/**
* The list of sources to listen for in the incoming event.
*
* @default CoreApplicationPlaneProps.controlPlaneEventSource
*/
readonly source?: string[];
}

/**
* Encapsulates the list of properties for a CoreApplicationPlaneJobRunner.
*/
Expand Down Expand Up @@ -105,19 +71,7 @@ export interface CoreApplicationPlaneJobRunnerProps {
* Encapsulates the list of properties for a CoreApplicationPlane.
*/
export interface CoreApplicationPlaneProps {
readonly eventManager: EventManager;

/**
* The source to use when listening for events coming from the SBT control plane.
* This is used as the default if the IncomingEventMetadata source field is not set.
*/
readonly controlPlaneEventSource?: string;

/**
* The source to use for outgoing events that will be placed on the EventBus.
* This is used as the default if the OutgoingEventMetadata source field is not set.
*/
readonly applicationPlaneEventSource?: string;
readonly eventManager?: EventManager;

/**
* The list of JobRunner definitions to create.
Expand All @@ -132,9 +86,16 @@ export interface CoreApplicationPlaneProps {
* and respond to events created by the control plane.
*/
export class CoreApplicationPlane extends Construct {
/**
* The EventManager instance that allows connecting to events flowing between
* the Control Plane and other components.
*/
readonly eventManager: EventManager;

constructor(scope: Construct, id: string, props: CoreApplicationPlaneProps) {
super(scope, id);
setTemplateDesc(this, 'SaaS Builder Toolkit - CoreApplicationPlane (uksb-1tupboc57)');
this.eventManager = props.eventManager ?? new EventManager(this, 'EventManager');

props.jobRunnerPropsList?.forEach((jobRunnerProps) => {
// Only BashJobOrchestrator requires differentiating between
Expand All @@ -159,9 +120,9 @@ export class CoreApplicationPlane extends Construct {
});

let jobOrchestrator = new BashJobOrchestrator(this, `${jobRunnerProps.name}-orchestrator`, {
targetEventBus: props.eventManager.eventBus,
targetEventBus: this.eventManager.eventBus,
detailType: jobRunnerProps.outgoingEvent,
eventSource: props.eventManager.supportedEvents[jobRunnerProps.outgoingEvent],
eventSource: this.eventManager.supportedEvents[jobRunnerProps.outgoingEvent],
environmentVariablesToOutgoingEvent: jobRunnerProps.environmentVariablesToOutgoingEvent,
environmentStringVariablesFromIncomingEvent:
jobRunnerProps.environmentStringVariablesFromIncomingEvent,
Expand All @@ -170,10 +131,7 @@ export class CoreApplicationPlane extends Construct {
bashJobRunner: job,
});

props.eventManager.addTargetToEvent(
jobRunnerProps.incomingEvent,
jobOrchestrator.eventTarget
);
this.eventManager.addTargetToEvent(jobRunnerProps.incomingEvent, jobOrchestrator.eventTarget);
});
}
}
Loading

0 comments on commit 799a55a

Please sign in to comment.