Skip to content

Commit

Permalink
Merge pull request #13 from aws-samples/feature/summarization_construct
Browse files Browse the repository at this point in the history
feat: added common helpers like redis,appsyncmergeapi,event bridge an…
  • Loading branch information
dineshSajwan authored Oct 5, 2023
2 parents aacefab + 23e3b28 commit b0a139a
Show file tree
Hide file tree
Showing 13 changed files with 1,131 additions and 14 deletions.
12 changes: 12 additions & 0 deletions .projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .projen/tasks.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions .projenrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const CDK_VERSION: string = '2.99.1';

const project = new awscdk.AwsCdkConstructLibrary({
author: 'Amazon Web Services - Prototyping and Cloud Engineering',
authorAddress: PROJECT_NAME+'@amazon.com',
authorAddress: PROJECT_NAME + '@amazon.com',
authorOrganization: true,
cdkVersion: CDK_VERSION,
projenVersion: '~0.73.33',
Expand All @@ -30,13 +30,13 @@ const project = new awscdk.AwsCdkConstructLibrary({
jsiiVersion: '~5.0.0',
name: PROJECT_NAME,
projenrcTs: true,
repositoryUrl: 'https://github.com/'+GITHUB_USER+'/'+PROJECT_NAME,
repositoryUrl: 'https://github.com/' + GITHUB_USER + '/' + PROJECT_NAME,

// description: undefined, /* The description is just a string that helps people understand the purpose of the package. */
packageName: '@'+GITHUB_USER+'/'+PROJECT_NAME, /* The "name" in package.json. */
packageName: '@' + GITHUB_USER + '/' + PROJECT_NAME, /* The "name" in package.json. */
keywords: ['constructs', 'aws-cdk', 'generative-ai', 'emerging-tech'],
devDeps: ['eslint-plugin-header'],
//peerDeps: [],
bundledDeps: ['deepmerge', '@types/deep-diff', '@types/npmlog'],

// Keep synchronized with https://github.com/nodejs/release#release-schedule
minNodeVersion: '18.12.0', // 'MAINTENANCE' (first LTS)
Expand Down Expand Up @@ -80,4 +80,5 @@ project.eslint?.addRules({
'header/header': [2, 'header.js'],
});


project.synth();
339 changes: 338 additions & 1 deletion docs/emerging_tech_cdk_constructs.drawio

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

242 changes: 242 additions & 0 deletions src/common/helpers/appsyncmergedapi-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as iam from 'aws-cdk-lib/aws-iam';

import { Construct } from 'constructs';


export interface AppsyncMergedApiProps {
/**
* name of merged api on appsync
* @default 'mergedApi'
*/
readonly appsyncmergedApiName: string;
/**
* cognito user pool id for appsync auth
* @default None
*/
readonly userpoolid: string;

/**
* cognito authentication user pool is used as authentication Type
*/
readonly cognitoAuthenticationUserpool: string;

/**
* AWS region
*/
readonly region: string;

/**
* AWS account
*/
readonly accountid: string;

/**
* appsync service principle role
*/
readonly appsyncServicePrincipleRole: string;

/**
* owner contact for merged api appsync notification
* @default None
*/
readonly appsyncMergedApiContact: string;

/**
* Security configuration for your GraphQL API.
* Allowed values - API_KEY , AWS_IAM , AMAZON_COGNITO_USER_POOLS , OPENID_CONNECT , or AWS_LAMBDA
* @default None
*/
readonly authenticationType: string;

/**
* Configuration for AWS Lambda function authorization.
* Use this if APP sync authentication Type is AWS_LAMBDA
*/
readonly authorizerResultTtlInSeconds: number;

/**
* Configuration for AWS Lambda function authorization.
* Use this if APP sync authentication Type is AWS_LAMBDA
*/
readonly authorizerUri: string;

/**
* Configuration for AWS Lambda function authorization.
* Use this if APP sync authentication Type is AWS_LAMBDA
*/
readonly identityValidationExpression: string;


/**
* Configuration for openIdConnectConfig authorization.
* Use this if APP sync authentication Type is OPENID_CONNECT
*/
readonly authTtl: number;

/**
* Configuration for AWS Lambda function authorization.
* Use this if APP sync authentication Type is OPENID_CONNECT
*/
readonly clientId: string;

/**
* Configuration for AWS Lambda function authorization.
* Use this if APP sync authentication Type is OPENID_CONNECT
*/
readonly iatTtl: number;

/**
* Configuration for AWS Lambda function authorization.
* Use this if APP sync authentication Type is OPENID_CONNECT
*/
readonly issuer: string;

}

export interface LogConfigProps {
/**
* The service role that AWS AppSync assumes to publish to CloudWatch logs in your account.
* @default None
*/
readonly cloudWatchLogsRoleArn: string;

/**
* Log level
* @default None
*/
readonly fieldLogLevel: string;

/**
* Set to TRUE to exclude sections that contain information such as
* headers, context, and evaluated mapping templates, regardless of logging level.
* @default false
*/
readonly excludeVerboseContent: boolean;

}
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*
* build app sync merge api with source api associations
*
* @param AppsyncMergedApiProps The props to be used by the construct
* @returns App sync merge api
*/
export function buildMergedAPI(scope: Construct, props: AppsyncMergedApiProps, logProps: LogConfigProps) {

let mergedapi = new appsync.CfnGraphQLApi(scope, props?.appsyncmergedApiName, {
apiType: 'MERGED',
name: props?.appsyncmergedApiName,
authenticationType: props?.authenticationType,
additionalAuthenticationProviders: [getAdditionalAuthenticationMode(props)],
logConfig: {
cloudWatchLogsRoleArn: setAppsyncCloudWatchlogsRole(scope, props).roleArn,
fieldLogLevel: logProps?.fieldLogLevel,
excludeVerboseContent: logProps.excludeVerboseContent,
},
xrayEnabled: true,
mergedApiExecutionRoleArn: getMergedAPIRole(scope, props).roleArn,
ownerContact: props.appsyncMergedApiContact,
});

return mergedapi;

}

function getAdditionalAuthenticationMode(props: AppsyncMergedApiProps) {

if (props.authenticationType == 'AMAZON_COGNITO_USER_POOLS') {
const additionalAuthenticationMode: appsync.CfnGraphQLApi.AdditionalAuthenticationProviderProperty = {
authenticationType: props?.authenticationType,
userPoolConfig: {
awsRegion: props?.region,
userPoolId: props?.userpoolid,
},
};
return additionalAuthenticationMode;
} else if (props.authenticationType == 'AWS_LAMBDA') {
const additionalAuthenticationMode: appsync.CfnGraphQLApi.AdditionalAuthenticationProviderProperty = {
authenticationType: props?.authenticationType,
lambdaAuthorizerConfig: {
authorizerResultTtlInSeconds: props?.authorizerResultTtlInSeconds,
authorizerUri: props?.authorizerUri,
identityValidationExpression: props?.identityValidationExpression,
},

};
return additionalAuthenticationMode;
} else if (props.authenticationType == 'OPENID_CONNECT') {
const additionalAuthenticationMode: appsync.CfnGraphQLApi.AdditionalAuthenticationProviderProperty = {
authenticationType: props?.authenticationType,
openIdConnectConfig: {
authTtl: props?.authTtl,
clientId: props?.clientId,
iatTtl: props?.iatTtl,
issuer: props?.issuer,
},
};
return additionalAuthenticationMode;
}
const additionalAuthenticationMode: appsync.CfnGraphQLApi.AdditionalAuthenticationProviderProperty = {
authenticationType: props?.authenticationType,
};
return additionalAuthenticationMode;
}

function setAppsyncCloudWatchlogsRole(scope: Construct, props: AppsyncMergedApiProps) {
let appsynccloudWatchlogsRole = new iam.Role(scope, 'appsynccloudWatchlogsRole', {
assumedBy: new iam.ServicePrincipal(props.appsyncServicePrincipleRole),
});
appsynccloudWatchlogsRole.addToPolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'],
resources: ['*'],
}),
);
return appsynccloudWatchlogsRole;
}

function getMergedAPIRole(scope: Construct, props: AppsyncMergedApiProps) {
return new iam.Role(scope, 'mergedapirole', {
assumedBy: new iam.ServicePrincipal(props.appsyncServicePrincipleRole),
});
}

/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*
* set the merge api role to access source api associations
*
* @param AppsyncMergedApiProps The props to be used by the construct
* @param mergedAPI app sync graphql api
* @param mergedApiRole iam role
* @returns App sync merge api role
*/
export function setMergedApiRole(props: AppsyncMergedApiProps, mergedAPI: appsync.CfnGraphQLApi, mergedApiRole: iam.Role ) {
mergedApiRole.addToPolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['appsync:StartSchemaMerge'],
resources: [
'arn:aws:appsync:' + props.region + ':' + props.accountid + ':apis/'
+ mergedAPI.attrApiId + '/sourceApiAssociations/*',
],
}),
);

return mergedApiRole;
}
60 changes: 60 additions & 0 deletions src/common/helpers/eventbridge-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
import * as events from 'aws-cdk-lib/aws-events';
import { Construct } from 'constructs';

export interface buildEventBridgeProps {
/**
* Existing instance of SNS Topic object, providing both this and `topicProps` will cause an error.
*
* @default - None.
*/
readonly existingEventBusInterface?: events.IEventBus;

/**
* Event bus to receive the request
* @default 'eventbus'
*/
readonly eventBusName: string;

}

export function buildEventBus(scope: Construct, props: buildEventBridgeProps) {
if (props.existingEventBusInterface) {
return props.existingEventBusInterface;
} else {
return new events.EventBus(scope, props.eventBusName, {
eventBusName: props.eventBusName,
});
}
}


export interface EventBridgeProps {
readonly existingEventBusInterface: events.IEventBus;
readonly eventBusProps: events.EventBusProps;
}

export function CheckEventBridgeProps(propsObject: EventBridgeProps | any) {
let errorMessages = '';
let errorFound = false;

if (propsObject.existingEventBusInterface && propsObject.eventBusProps) {
errorMessages += 'Error - Either provide existingEventBusInterface or eventBusProps, but not both.\n';
errorFound = true;
}

if (errorFound) {
throw new Error(errorMessages);
}
}
Loading

0 comments on commit b0a139a

Please sign in to comment.