Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(appmesh): change Route's spec to a union-like class #11343

Merged
merged 12 commits into from
Nov 19, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -293,22 +293,24 @@ export class AppMeshExtension extends ServiceExtension {
virtualRouterName: `${this.parentService.id}`,
});

// Form the service name that requests will be made to
const serviceName = `${this.parentService.id}.${cloudmapNamespace.namespaceName}`;
const weightedTargets: appmesh.WeightedTarget[] = [{
virtualNode: this.virtualNode,
weight: 1,
}];
// Now add the virtual node as a route in the virtual router
// Ensure that the route type matches the protocol type.
this.route = this.virtualRouter.addRoute(`${this.parentService.id}-route`, {
routeTargets: [{
virtualNode: this.virtualNode,
weight: 1,
}],
// Ensure that the route type matches the protocol type.
routeType: this.protocol == appmesh.Protocol.HTTP ? appmesh.RouteType.HTTP : appmesh.RouteType.TCP,
routeSpec: this.routeSpec(weightedTargets, serviceName),
});

// Now create a virtual service. Relationship goes like this:
// virtual service -> virtual router -> virtual node
this.virtualService = new appmesh.VirtualService(this.scope, `${this.parentService.id}-virtual-service`, {
mesh: this.mesh,
virtualRouter: this.virtualRouter,
virtualServiceName: `${this.parentService.id}.${cloudmapNamespace.namespaceName}`,
virtualServiceName: serviceName,
});
}

Expand Down Expand Up @@ -340,6 +342,26 @@ export class AppMeshExtension extends ServiceExtension {
this.virtualNode.addBackend(otherAppMesh.virtualService);
}

private routeSpec(weightedTargets: appmesh.WeightedTarget[], serviceName: string): appmesh.RouteSpec {
switch (this.protocol) {
case appmesh.Protocol.HTTP: return appmesh.RouteSpec.http({
weightedTargets: weightedTargets,
});
case appmesh.Protocol.HTTP2: return appmesh.RouteSpec.http2({
weightedTargets: weightedTargets,
});
case appmesh.Protocol.GRPC: return appmesh.RouteSpec.grpc({
weightedTargets: weightedTargets,
match: {
serviceName: serviceName,
},
});
case appmesh.Protocol.TCP: return appmesh.RouteSpec.tcp({
weightedTargets: weightedTargets,
});
}
}

private virtualRouterListener(port: number): appmesh.VirtualRouterListener {
switch (this.protocol) {
case appmesh.Protocol.HTTP: return appmesh.VirtualRouterListener.http(port);
Expand Down
66 changes: 45 additions & 21 deletions packages/@aws-cdk/aws-appmesh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,39 +188,63 @@ The `listeners` property can be left blank and added later with the `node.addLis

A `route` is associated with a virtual router, and it's used to match requests for a virtual router and distribute traffic accordingly to its associated virtual nodes.

You can use the prefix parameter in your `route` specification for path-based routing of requests. For example, if your virtual service name is my-service.local and you want the `route` to match requests to my-service.local/metrics, your prefix should be /metrics.

If your `route` matches a request, you can distribute traffic to one or more target virtual nodes with relative weighting.

```typescript
router.addRoute('route', {
routeTargets: [
{
virtualNode,
weight: 1,
router.addRoute('route-http', {
routeSpec: appmesh.RouteSpec.http({
weightedTargets: [
{
virtualNode: node,
},
],
match: {
prefixPath: '/path-to-app',
},
],
prefix: `/path-to-app`,
routeType: RouteType.HTTP,
}),
});
```

Add a single route with multiple targets and split traffic 50/50

```typescript
router.addRoute('route', {
routeTargets: [
{
virtualNode,
weight: 50,
router.addRoute('route-http', {
routeSpec: appmesh.RouteSpec.http({
weightedTargets: [
{
virtualNode: node,
weight: 50,
},
{
virtualNode: node,
weight: 50,
},
],
match: {
prefixPath: '/path-to-app',
},
{
virtualNode2,
weight: 50,
}),
});
```

The _RouteSpec_ class provides an easy interface for defining new protocol specific route specs.
The `tcp()`, `http()` and `http2()` methods provide the spec necessary to define a protocol specific spec.

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 `/`.

```typescript
router.addRoute('route-http', {
dfezzie marked this conversation as resolved.
Show resolved Hide resolved
routeSpec: appmesh.RouteSpec.grpc({
weightedTargets: [
{
virtualNode: node,
},
],
match: {
serviceName: 'my-service.default.svc.cluster.local',
},
],
prefix: `/path-to-app`,
routeType: RouteType.HTTP,
}),
});
```

Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-appmesh/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * from './appmesh.generated';
export * from './mesh';
export * from './route';
export * from './route-spec';
export * from './shared-interfaces';
export * from './virtual-node';
export * from './virtual-router';
Expand Down
Loading