Skip to content

Commit

Permalink
feat(appmesh): add timeout support to Routes (#11973)
Browse files Browse the repository at this point in the history
Add support to http/http2/grpc/tpc route timeouts. 

Reference links for [HttpTimeout](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httptimeout.html), [GrpcTimeout](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpctimeout.html), and [TcpTimeout](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcptimeout.html). (Http2 uses the HttpTimeout object).

closes #11643

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
skiyani committed Dec 15, 2020
1 parent 0802c13 commit 78c185d
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 53 deletions.
5 changes: 5 additions & 0 deletions packages/@aws-cdk/aws-appmesh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ The `tcp()`, `http()` and `http2()` methods provide the spec necessary to define

For HTTP based routes, the match field can be used to match on a route prefix.
By default, an HTTP based route will match on `/`. All matches must start with a leading `/`.
The timeout field can also be specified for `idle` and `perRequest` timeouts.

```ts
router.addRoute('route-http', {
Expand All @@ -301,6 +302,10 @@ router.addRoute('route-http', {
match: {
serviceName: 'my-service.default.svc.cluster.local',
},
timeout: {
idle : Duration.seconds(2),
perRequest: Duration.seconds(1),
},
}),
});
```
Expand Down
62 changes: 61 additions & 1 deletion packages/@aws-cdk/aws-appmesh/lib/route-spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as cdk from '@aws-cdk/core';
import { CfnRoute } from './appmesh.generated';
import { Protocol } from './shared-interfaces';
import { Protocol, HttpTimeout, GrpcTimeout, TcpTimeout } from './shared-interfaces';
import { IVirtualNode } from './virtual-node';

/**
Expand Down Expand Up @@ -58,6 +58,13 @@ export interface HttpRouteSpecOptions {
* List of targets that traffic is routed to when a request matches the route
*/
readonly weightedTargets: WeightedTarget[];

/**
* An object that represents a http timeout
*
* @default - None
*/
readonly timeout?: HttpTimeout;
}

/**
Expand All @@ -68,6 +75,13 @@ export interface TcpRouteSpecOptions {
* List of targets that traffic is routed to when a request matches the route
*/
readonly weightedTargets: WeightedTarget[];

/**
* An object that represents a tcp timeout
*
* @default - None
*/
readonly timeout?: TcpTimeout;
}

/**
Expand All @@ -79,6 +93,13 @@ export interface GrpcRouteSpecOptions {
*/
readonly match: GrpcRouteMatch;

/**
* An object that represents a grpc timeout
*
* @default - None
*/
readonly timeout?: GrpcTimeout;

/**
* List of targets that traffic is routed to when a request matches the route
*/
Expand Down Expand Up @@ -169,6 +190,11 @@ class HttpRouteSpec extends RouteSpec {
*/
public readonly match?: HttpRouteMatch;

/**
* The criteria for determining a timeout configuration
*/
public readonly timeout?: HttpTimeout;

/**
* List of targets that traffic is routed to when a request matches the route
*/
Expand All @@ -179,6 +205,7 @@ class HttpRouteSpec extends RouteSpec {
this.protocol = protocol;
this.match = props.match;
this.weightedTargets = props.weightedTargets;
this.timeout = props.timeout;
}

public bind(_scope: cdk.Construct): RouteSpecConfig {
Expand All @@ -193,6 +220,7 @@ class HttpRouteSpec extends RouteSpec {
match: {
prefix: prefixPath,
},
timeout: renderTimeout(this.timeout),
};
return {
httpRouteSpec: this.protocol === Protocol.HTTP ? httpConfig : undefined,
Expand All @@ -207,9 +235,15 @@ class TcpRouteSpec extends RouteSpec {
*/
public readonly weightedTargets: WeightedTarget[];

/**
* The criteria for determining a timeout configuration
*/
public readonly timeout?: TcpTimeout;

constructor(props: TcpRouteSpecOptions) {
super();
this.weightedTargets = props.weightedTargets;
this.timeout = props.timeout;
}

public bind(_scope: cdk.Construct): RouteSpecConfig {
Expand All @@ -218,6 +252,7 @@ class TcpRouteSpec extends RouteSpec {
action: {
weightedTargets: renderWeightedTargets(this.weightedTargets),
},
timeout: renderTimeout(this.timeout),
},
};
}
Expand All @@ -226,11 +261,13 @@ class TcpRouteSpec extends RouteSpec {
class GrpcRouteSpec extends RouteSpec {
public readonly weightedTargets: WeightedTarget[];
public readonly match: GrpcRouteMatch;
public readonly timeout?: GrpcTimeout;

constructor(props: GrpcRouteSpecOptions) {
super();
this.weightedTargets = props.weightedTargets;
this.match = props.match;
this.timeout = props.timeout;
}

public bind(_scope: cdk.Construct): RouteSpecConfig {
Expand All @@ -242,6 +279,7 @@ class GrpcRouteSpec extends RouteSpec {
match: {
serviceName: this.match.serviceName,
},
timeout: renderTimeout(this.timeout),
},
};
}
Expand All @@ -260,3 +298,25 @@ function renderWeightedTargets(weightedTargets: WeightedTarget[]): CfnRoute.Weig
}
return renderedTargets;
}

/**
* Utility method to construct a route timeout object
*/
function renderTimeout(timeout?: HttpTimeout): CfnRoute.HttpTimeoutProperty | undefined {
return timeout
? {
idle: timeout?.idle !== undefined
? {
unit: 'ms',
value: timeout?.idle.toMilliseconds(),
}
: undefined,
perRequest: timeout?.perRequest !== undefined
? {
unit: 'ms',
value: timeout?.perRequest.toMilliseconds(),
}
: undefined,
}
: undefined;
}
50 changes: 50 additions & 0 deletions packages/@aws-cdk/aws-appmesh/lib/shared-interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,56 @@
import * as cdk from '@aws-cdk/core';
import { CfnVirtualGateway, CfnVirtualNode } from './appmesh.generated';

/**
* Represents timeouts for HTTP protocols.
*/
export interface HttpTimeout {
/**
* Represents an idle timeout. The amount of time that a connection may be idle.
*
* @default - none
*/
readonly idle?: cdk.Duration;

/**
* Represents per request timeout.
*
* @default - 15 s
*/
readonly perRequest?: cdk.Duration;
}

/**
* Represents timeouts for GRPC protocols.
*/
export interface GrpcTimeout {
/**
* Represents an idle timeout. The amount of time that a connection may be idle.
*
* @default - none
*/
readonly idle?: cdk.Duration;

/**
* Represents per request timeout.
*
* @default - 15 s
*/
readonly perRequest?: cdk.Duration;
}

/**
* Represents timeouts for TCP protocols.
*/
export interface TcpTimeout {
/**
* Represents an idle timeout. The amount of time that a connection may be idle.
*
* @default - none
*/
readonly idle?: cdk.Duration;
}

/**
* Enum of supported AppMesh protocols
*/
Expand Down
52 changes: 1 addition & 51 deletions packages/@aws-cdk/aws-appmesh/lib/virtual-node-listener.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as cdk from '@aws-cdk/core';
import { CfnVirtualNode } from './appmesh.generated';
import { validateHealthChecks } from './private/utils';
import { HealthCheck, Protocol } from './shared-interfaces';
import { HealthCheck, Protocol, HttpTimeout, GrpcTimeout, TcpTimeout } from './shared-interfaces';

/**
* Properties for a VirtualNode listener
Expand Down Expand Up @@ -68,56 +68,6 @@ export interface TcpVirtualNodeListenerOptions extends VirtualNodeListenerCommon
readonly timeout?: TcpTimeout;
}

/**
* Represents timeouts for HTTP protocols.
*/
export interface HttpTimeout {
/**
* Represents an idle timeout. The amount of time that a connection may be idle.
*
* @default - none
*/
readonly idle?: cdk.Duration;

/**
* Represents per request timeout.
*
* @default - 15 s
*/
readonly perRequest?: cdk.Duration;
}

/**
* Represents timeouts for GRPC protocols.
*/
export interface GrpcTimeout {
/**
* Represents an idle timeout. The amount of time that a connection may be idle.
*
* @default - none
*/
readonly idle?: cdk.Duration;

/**
* Represents per request timeout.
*
* @default - 15 s
*/
readonly perRequest?: cdk.Duration;
}

/**
* Represents timeouts for TCP protocols.
*/
export interface TcpTimeout {
/**
* Represents an idle timeout. The amount of time that a connection may be idle.
*
* @default - none
*/
readonly idle?: cdk.Duration;
}

/**
* Defines listener for a VirtualNode
*/
Expand Down
5 changes: 4 additions & 1 deletion packages/@aws-cdk/aws-appmesh/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,10 @@
"duration-prop-type:@aws-cdk/aws-appmesh.GrpcVirtualNodeListenerOptions.timeout",
"duration-prop-type:@aws-cdk/aws-appmesh.HttpVirtualNodeListenerOptions.timeout",
"duration-prop-type:@aws-cdk/aws-appmesh.Http2VirtualNodeListenerOptions.timeout",
"duration-prop-type:@aws-cdk/aws-appmesh.TcpVirtualNodeListenerOptions.timeout"
"duration-prop-type:@aws-cdk/aws-appmesh.TcpVirtualNodeListenerOptions.timeout",
"duration-prop-type:@aws-cdk/aws-appmesh.GrpcRouteSpecOptions.timeout",
"duration-prop-type:@aws-cdk/aws-appmesh.HttpRouteSpecOptions.timeout",
"duration-prop-type:@aws-cdk/aws-appmesh.TcpRouteSpecOptions.timeout"
]
},
"stability": "experimental",
Expand Down
26 changes: 26 additions & 0 deletions packages/@aws-cdk/aws-appmesh/test/integ.mesh.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,16 @@
},
"Match": {
"Prefix": "/"
},
"Timeout": {
"Idle": {
"Unit": "ms",
"Value": 10000
},
"PerRequest": {
"Unit": "ms",
"Value": 10000
}
}
}
},
Expand Down Expand Up @@ -553,6 +563,16 @@
},
"Match": {
"Prefix": "/path2"
},
"Timeout": {
"Idle": {
"Unit": "ms",
"Value": 11000
},
"PerRequest": {
"Unit": "ms",
"Value": 11000
}
}
}
},
Expand Down Expand Up @@ -588,6 +608,12 @@
"Weight": 20
}
]
},
"Timeout": {
"Idle": {
"Unit": "ms",
"Value": 12000
}
}
}
},
Expand Down
11 changes: 11 additions & 0 deletions packages/@aws-cdk/aws-appmesh/test/integ.mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ router.addRoute('route-1', {
match: {
prefixPath: '/',
},
timeout: {
idle: cdk.Duration.seconds(10),
perRequest: cdk.Duration.seconds(10),
},
}),
});

Expand Down Expand Up @@ -118,6 +122,10 @@ router.addRoute('route-2', {
match: {
prefixPath: '/path2',
},
timeout: {
idle: cdk.Duration.seconds(11),
perRequest: cdk.Duration.seconds(11),
},
}),
});

Expand All @@ -129,6 +137,9 @@ router.addRoute('route-3', {
weight: 20,
},
],
timeout: {
idle: cdk.Duration.seconds(12),
},
}),
});

Expand Down
Loading

0 comments on commit 78c185d

Please sign in to comment.