Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Mar 14, 2022
2 parents cd75f0f + c8cafef commit 6a6e7d2
Show file tree
Hide file tree
Showing 69 changed files with 2,215 additions and 1,199 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"devDependencies": {
"@yarnpkg/lockfile": "^1.1.0",
"cdk-generate-synthetic-examples": "^0.1.6",
"cdk-generate-synthetic-examples": "^0.1.8",
"conventional-changelog-cli": "^2.2.2",
"fs-extra": "^9.1.0",
"graceful-fs": "^4.2.9",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/cdk-integ-tools": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/aws-lambda": "^8.10.92",
"@types/aws-lambda": "^8.10.93",
"@types/jest": "^27.4.1"
},
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ export class ScalableTarget extends Resource implements IScalableTarget {
if (action.minCapacity === undefined && action.maxCapacity === undefined) {
throw new Error(`You must supply at least one of minCapacity or maxCapacity, got ${JSON.stringify(action)}`);
}

// add a warning on synth when minute is not defined in a cron schedule
action.schedule._bind(this);

this.actions.push({
scheduledActionName: id,
schedule: action.schedule.expressionString,
Expand Down
24 changes: 20 additions & 4 deletions packages/@aws-cdk/aws-applicationautoscaling/lib/schedule.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Duration } from '@aws-cdk/core';
import { Annotations, Duration } from '@aws-cdk/core';
import { Construct } from 'constructs';

/**
* Schedule for scheduled scaling actions
Expand Down Expand Up @@ -58,16 +59,29 @@ export abstract class Schedule {
const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*');
const weekDay = fallback(options.weekDay, '?');

return new LiteralSchedule(`cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`);
return new class extends Schedule {
public readonly expressionString: string = `cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`;
public _bind(scope: Construct) {
if (!options.minute) {
Annotations.of(scope).addWarning('cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.');
}
return new LiteralSchedule(this.expressionString);
}
};
}

/**
* Retrieve the expression for this schedule
*/
public abstract readonly expressionString: string;

protected constructor() {
}
protected constructor() {}

/**
*
* @internal
*/
public abstract _bind(scope: Construct): void;
}

/**
Expand Down Expand Up @@ -126,6 +140,8 @@ class LiteralSchedule extends Schedule {
constructor(public readonly expressionString: string) {
super();
}

public _bind() {}
}

function fallback<T>(x: T | undefined, def: T): T {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Match, Template } from '@aws-cdk/assertions';
import { Annotations, Match, Template } from '@aws-cdk/assertions';
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import * as iam from '@aws-cdk/aws-iam';
import * as cdk from '@aws-cdk/core';
Expand Down Expand Up @@ -79,6 +79,53 @@ describe('scalable target', () => {
});
});

test('scheduled scaling shows warning when minute is not defined in cron', () => {
// GIVEN
const stack = new cdk.Stack();
const target = createScalableTarget(stack);

// WHEN
target.scaleOnSchedule('ScaleUp', {
schedule: appscaling.Schedule.cron({
hour: '8',
day: '1',
}),
maxCapacity: 50,
minCapacity: 1,
});

// THEN
expect(target.node.metadataEntry).toEqual([{
type: 'aws:cdk:warning',
data: 'cron: If you don\'t pass \'minute\', by default the event runs every minute. Pass \'minute: \'*\'\' if that\'s what you intend, or \'minute: 0\' to run once per hour instead.',
trace: undefined,
}]);
Annotations.fromStack(stack).hasWarning('/Default/Target', "cron: If you don't pass 'minute', by default the event runs every minute. Pass 'minute: '*'' if that's what you intend, or 'minute: 0' to run once per hour instead.");

});

test('scheduled scaling shows no warning when minute is * in cron', () => {
// GIVEN
const stack = new cdk.Stack();
const target = createScalableTarget(stack);

// WHEN
target.scaleOnSchedule('ScaleUp', {
schedule: appscaling.Schedule.cron({
hour: '8',
day: '1',
minute: '*',
}),
maxCapacity: 50,
minCapacity: 1,
});

// THEN
expect(target.node.metadataEntry).toEqual([]);
const annotations = Annotations.fromStack(stack).findWarning('*', Match.anyValue());
expect(annotations.length).toBe(0);
});

test('step scaling on MathExpression', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down
17 changes: 9 additions & 8 deletions packages/@aws-cdk/aws-appsync/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,18 +240,19 @@ httpDs.createResolver({
});
```

### Elasticsearch
### Amazon OpenSearch Service

AppSync has builtin support for Elasticsearch from domains that are provisioned
through your AWS account. You can use AppSync resolvers to perform GraphQL operations
such as queries, mutations, and subscriptions.
AppSync has builtin support for Amazon OpenSearch Service (successor to Amazon
Elasticsearch Service) from domains that are provisioned through your AWS account. You can
use AppSync resolvers to perform GraphQL operations such as queries, mutations, and
subscriptions.

```ts
import * as es from '@aws-cdk/aws-elasticsearch';
import * as opensearch from '@aws-cdk/aws-opensearchservice';

const user = new iam.User(this, 'User');
const domain = new es.Domain(this, 'Domain', {
version: es.ElasticsearchVersion.V7_1,
const domain = new opensearch.Domain(this, 'Domain', {
version: opensearch.EngineVersion.OPENSEARCH_1_1,
removalPolicy: RemovalPolicy.DESTROY,
fineGrainedAccessControl: { masterUserArn: user.userArn },
encryptionAtRest: { enabled: true },
Expand All @@ -260,7 +261,7 @@ const domain = new es.Domain(this, 'Domain', {
});

declare const api: appsync.GraphqlApi;
const ds = api.addElasticsearchDataSource('ds', domain);
const ds = api.addOpenSearchDataSource('ds', domain);

ds.createResolver({
typeName: 'Query',
Expand Down
49 changes: 44 additions & 5 deletions packages/@aws-cdk/aws-appsync/lib/data-source.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ITable } from '@aws-cdk/aws-dynamodb';
import { IDomain } from '@aws-cdk/aws-elasticsearch';
import { IDomain as IElasticsearchDomain } from '@aws-cdk/aws-elasticsearch';
import { Grant, IGrantable, IPrincipal, IRole, Role, ServicePrincipal } from '@aws-cdk/aws-iam';
import { IFunction } from '@aws-cdk/aws-lambda';
import { IDomain as IOpenSearchDomain } from '@aws-cdk/aws-opensearchservice';
import { IServerlessCluster } from '@aws-cdk/aws-rds';
import { ISecret } from '@aws-cdk/aws-secretsmanager';
import { IResolvable, Lazy, Stack } from '@aws-cdk/core';
Expand Down Expand Up @@ -64,11 +65,18 @@ export interface ExtendedDataSourceProps {
*/
readonly dynamoDbConfig?: CfnDataSource.DynamoDBConfigProperty | IResolvable;
/**
* configuration for Elasticsearch Datasource
* configuration for Elasticsearch data source
*
* @deprecated - use `openSearchConfig`
* @default - No config
*/
readonly elasticsearchConfig?: CfnDataSource.ElasticsearchConfigProperty | IResolvable;
/**
* configuration for OpenSearch data source
*
* @default - No config
*/
readonly openSearchServiceConfig?: CfnDataSource.OpenSearchServiceConfigProperty | IResolvable;
/**
* configuration for HTTP Datasource
*
Expand Down Expand Up @@ -370,17 +378,21 @@ export class RdsDataSource extends BackedDataSource {
}

/**
* Properities for the Elasticsearch Data Source
* Properties for the Elasticsearch Data Source
*
* @deprecated - use `OpenSearchDataSourceProps` with `OpenSearchDataSource`
*/
export interface ElasticsearchDataSourceProps extends BackedDataSourceProps {
/**
* The elasticsearch domain containing the endpoint for the data source
*/
readonly domain: IDomain;
readonly domain: IElasticsearchDomain;
}

/**
* An Appsync datasource backed by Elasticsearch
*
* @deprecated - use `OpenSearchDataSource`
*/
export class ElasticsearchDataSource extends BackedDataSource {
constructor(scope: Construct, id: string, props: ElasticsearchDataSourceProps) {
Expand All @@ -394,4 +406,31 @@ export class ElasticsearchDataSource extends BackedDataSource {

props.domain.grantReadWrite(this);
}
}
}

/**
* Properties for the OpenSearch Data Source
*/
export interface OpenSearchDataSourceProps extends BackedDataSourceProps {
/**
* The OpenSearch domain containing the endpoint for the data source
*/
readonly domain: IOpenSearchDomain;
}

/**
* An Appsync datasource backed by OpenSearch
*/
export class OpenSearchDataSource extends BackedDataSource {
constructor(scope: Construct, id: string, props: OpenSearchDataSourceProps) {
super(scope, id, props, {
type: 'AMAZON_OPENSEARCH_SERVICE',
openSearchServiceConfig: {
awsRegion: props.domain.stack.region,
endpoint: `https://${props.domain.domainEndpoint}`,
},
});

props.domain.grantReadWrite(this);
}
}
38 changes: 33 additions & 5 deletions packages/@aws-cdk/aws-appsync/lib/graphqlapi-base.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { ITable } from '@aws-cdk/aws-dynamodb';
import { IDomain } from '@aws-cdk/aws-elasticsearch';
import { IDomain as IElasticsearchDomain } from '@aws-cdk/aws-elasticsearch';
import { IFunction } from '@aws-cdk/aws-lambda';
import { IDomain as IOpenSearchDomain } from '@aws-cdk/aws-opensearchservice';
import { IServerlessCluster } from '@aws-cdk/aws-rds';
import { ISecret } from '@aws-cdk/aws-secretsmanager';
import { CfnResource, IResource, Resource } from '@aws-cdk/core';
import { DynamoDbDataSource, HttpDataSource, LambdaDataSource, NoneDataSource, RdsDataSource, AwsIamConfig, ElasticsearchDataSource } from './data-source';
import { DynamoDbDataSource, HttpDataSource, LambdaDataSource, NoneDataSource, RdsDataSource, AwsIamConfig, ElasticsearchDataSource, OpenSearchDataSource } from './data-source';
import { Resolver, ExtendedResolverProps } from './resolver';

/**
Expand Down Expand Up @@ -114,11 +115,21 @@ export interface IGraphqlApi extends IResource {
/**
* add a new elasticsearch data source to this API
*
* @deprecated - use `addOpenSearchDataSource`
* @param id The data source's id
* @param domain The elasticsearch domain for this data source
* @param options The optional configuration for this data source
*/
addElasticsearchDataSource(id: string, domain: IDomain, options?: DataSourceOptions): ElasticsearchDataSource;
addElasticsearchDataSource(id: string, domain: IElasticsearchDomain, options?: DataSourceOptions): ElasticsearchDataSource;

/**
* Add a new OpenSearch data source to this API
*
* @param id The data source's id
* @param domain The OpenSearch domain for this data source
* @param options The optional configuration for this data source
*/
addOpenSearchDataSource(id: string, domain: IOpenSearchDomain, options?: DataSourceOptions): OpenSearchDataSource;

/**
* creates a new resolver for this datasource and API using the given properties
Expand Down Expand Up @@ -241,11 +252,12 @@ export abstract class GraphqlApiBase extends Resource implements IGraphqlApi {
/**
* add a new elasticsearch data source to this API
*
* @deprecated - use `addOpenSearchDataSource`
* @param id The data source's id
* @param domain The elasticsearch domain for this data source
* @param options The optional configuration for this data source
*/
public addElasticsearchDataSource(id: string, domain: IDomain, options?: DataSourceOptions): ElasticsearchDataSource {
public addElasticsearchDataSource(id: string, domain: IElasticsearchDomain, options?: DataSourceOptions): ElasticsearchDataSource {
return new ElasticsearchDataSource(this, id, {
api: this,
name: options?.name,
Expand All @@ -254,6 +266,22 @@ export abstract class GraphqlApiBase extends Resource implements IGraphqlApi {
});
}

/**
* add a new OpenSearch data source to this API
*
* @param id The data source's id
* @param domain The OpenSearch domain for this data source
* @param options The optional configuration for this data source
*/
public addOpenSearchDataSource(id: string, domain: IOpenSearchDomain, options?: DataSourceOptions): OpenSearchDataSource {
return new OpenSearchDataSource(this, id, {
api: this,
name: options?.name,
description: options?.description,
domain,
});
}

/**
* creates a new resolver for this datasource and API using the given properties
*/
Expand All @@ -273,4 +301,4 @@ export abstract class GraphqlApiBase extends Resource implements IGraphqlApi {
construct;
return false;
}
}
}
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-appsync/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"@aws-cdk/aws-elasticsearch": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-opensearchservice": "0.0.0",
"@aws-cdk/aws-rds": "0.0.0",
"@aws-cdk/aws-s3-assets": "0.0.0",
"@aws-cdk/aws-secretsmanager": "0.0.0",
Expand All @@ -109,6 +110,7 @@
"@aws-cdk/aws-elasticsearch": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-opensearchservice": "0.0.0",
"@aws-cdk/aws-rds": "0.0.0",
"@aws-cdk/aws-s3-assets": "0.0.0",
"@aws-cdk/aws-secretsmanager": "0.0.0",
Expand Down
Loading

0 comments on commit 6a6e7d2

Please sign in to comment.