'''
# AWS App Mesh Construct Library

<!--BEGIN STABILITY BANNER-->---


![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)

![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)

---
<!--END STABILITY BANNER-->

AWS App Mesh is a service mesh based on the [Envoy](https://www.envoyproxy.io/) proxy that makes it easy to monitor and control microservices. App Mesh standardizes how your microservices communicate, giving you end-to-end visibility and helping to ensure high-availability for your applications.

App Mesh gives you consistent visibility and network traffic controls for every microservice in an application.

App Mesh supports microservice applications that use service discovery naming for their components. To use App Mesh, you must have an existing application running on AWS Fargate, Amazon ECS, Amazon EKS, Kubernetes on AWS, or Amazon EC2.

For further information on **AWS App Mesh**, visit the [AWS App Mesh Documentation](https://docs.aws.amazon.com/app-mesh/index.html).

## Create the App and Stack

```python
app = cdk.App()
stack = cdk.Stack(app, "stack")
```

## Creating the Mesh

A service mesh is a logical boundary for network traffic between the services that reside within it.

After you create your service mesh, you can create virtual services, virtual nodes, virtual routers, and routes to distribute traffic between the applications in your mesh.

The following example creates the `AppMesh` service mesh with the default egress filter of `DROP_ALL`. See [the AWS CloudFormation `EgressFilter` resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-egressfilter.html) for more info on egress filters.

```python
mesh = appmesh.Mesh(self, "AppMesh",
    mesh_name="myAwsMesh"
)
```

The mesh can instead be created with the `ALLOW_ALL` egress filter by providing the `egressFilter` property.

```python
mesh = appmesh.Mesh(self, "AppMesh",
    mesh_name="myAwsMesh",
    egress_filter=appmesh.MeshFilterType.ALLOW_ALL
)
```

## Adding VirtualRouters

A *mesh* uses  *virtual routers* as logical units to route requests to *virtual nodes*.

Virtual routers handle traffic for one or more virtual services within your mesh.
After you create a virtual router, you can create and associate routes to your virtual router that direct incoming requests to different virtual nodes.

```python
# mesh: appmesh.Mesh

router = mesh.add_virtual_router("router",
    listeners=[appmesh.VirtualRouterListener.http(8080)]
)
```

Note that creating the router using the `addVirtualRouter()` method places it in the same stack as the mesh
(which might be different from the current stack).
The router can also be created using the `VirtualRouter` constructor (passing in the mesh) instead of calling the `addVirtualRouter()` method.
This is particularly useful when splitting your resources between many stacks: for example, defining the mesh itself as part of an infrastructure stack, but defining the other resources, such as routers, in the application stack:

```python
# infra_stack: cdk.Stack
# app_stack: cdk.Stack


mesh = appmesh.Mesh(infra_stack, "AppMesh",
    mesh_name="myAwsMesh",
    egress_filter=appmesh.MeshFilterType.ALLOW_ALL
)

# the VirtualRouter will belong to 'appStack',
# even though the Mesh belongs to 'infraStack'
router = appmesh.VirtualRouter(app_stack, "router",
    mesh=mesh,  # notice that mesh is a required property when creating a router with the 'new' statement
    listeners=[appmesh.VirtualRouterListener.http(8081)]
)
```

The same is true for other `add*()` methods in the App Mesh construct library.

The `VirtualRouterListener` class lets you define protocol-specific listeners.
The `http()`, `http2()`, `grpc()` and `tcp()` methods create listeners for the named protocols.
They accept a single parameter that defines the port to on which requests will be matched.
The port parameter defaults to 8080 if omitted.

## Adding a VirtualService

A *virtual service* is an abstraction of a real service that is provided by a virtual node directly, or indirectly by means of a virtual router. Dependent services call your virtual service by its `virtualServiceName`, and those requests are routed to the virtual node or virtual router specified as the provider for the virtual service.

We recommend that you use the service discovery name of the real service that you're targeting (such as `my-service.default.svc.cluster.local`).

When creating a virtual service:

* If you want the virtual service to spread traffic across multiple virtual nodes, specify a virtual router.
* If you want the virtual service to reach a virtual node directly, without a virtual router, specify a virtual node.

Adding a virtual router as the provider:

```python
# router: appmesh.VirtualRouter


appmesh.VirtualService(self, "virtual-service",
    virtual_service_name="my-service.default.svc.cluster.local",  # optional
    virtual_service_provider=appmesh.VirtualServiceProvider.virtual_router(router)
)
```

Adding a virtual node as the provider:

```python
# node: appmesh.VirtualNode


appmesh.VirtualService(self, "virtual-service",
    virtual_service_name="my-service.default.svc.cluster.local",  # optional
    virtual_service_provider=appmesh.VirtualServiceProvider.virtual_node(node)
)
```

## Adding a VirtualNode

A *virtual node* acts as a logical pointer to a particular task group, such as an Amazon ECS service or a Kubernetes deployment.

When you create a virtual node, accept inbound traffic by specifying a *listener*. Outbound traffic that your virtual node expects to send should be specified as a *back end*.

The response metadata for your new virtual node contains the Amazon Resource Name (ARN) that is associated with the virtual node. Set this value (either the full ARN or the truncated resource name) as the `APPMESH_VIRTUAL_NODE_NAME` environment variable for your task group's Envoy proxy container in your task definition or pod spec. For example, the value could be `mesh/default/virtualNode/simpleapp`. This is then mapped to the `node.id` and `node.cluster` Envoy parameters.

> **Note**
> If you require your Envoy stats or tracing to use a different name, you can override the `node.cluster` value that is set by `APPMESH_VIRTUAL_NODE_NAME` with the `APPMESH_VIRTUAL_NODE_CLUSTER` environment variable.

```python
# mesh: appmesh.Mesh
vpc = ec2.Vpc(self, "vpc")
namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
    vpc=vpc,
    name="domain.local"
)
service = namespace.create_service("Svc")
node = mesh.add_virtual_node("virtual-node",
    service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
    listeners=[appmesh.VirtualNodeListener.http(
        port=8081,
        health_check=appmesh.HealthCheck.http(
            healthy_threshold=3,
            interval=cdk.Duration.seconds(5),  # minimum
            path="/health-check-path",
            timeout=cdk.Duration.seconds(2),  # minimum
            unhealthy_threshold=2
        )
    )],
    access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
)
```

Create a `VirtualNode` with the constructor and add tags.

```python
# mesh: appmesh.Mesh
# service: cloudmap.Service


node = appmesh.VirtualNode(self, "node",
    mesh=mesh,
    service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
    listeners=[appmesh.VirtualNodeListener.http(
        port=8080,
        health_check=appmesh.HealthCheck.http(
            healthy_threshold=3,
            interval=cdk.Duration.seconds(5),
            path="/ping",
            timeout=cdk.Duration.seconds(2),
            unhealthy_threshold=2
        ),
        timeout=appmesh.HttpTimeout(
            idle=cdk.Duration.seconds(5)
        )
    )],
    backend_defaults=appmesh.BackendDefaults(
        tls_client_policy=appmesh.TlsClientPolicy(
            validation=appmesh.TlsValidation(
                trust=appmesh.TlsValidationTrust.file("/keys/local_cert_chain.pem")
            )
        )
    ),
    access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
)

cdk.Tags.of(node).add("Environment", "Dev")
```

Create a `VirtualNode` with the constructor and add backend virtual service.

```python
# mesh: appmesh.Mesh
# router: appmesh.VirtualRouter
# service: cloudmap.Service


node = appmesh.VirtualNode(self, "node",
    mesh=mesh,
    service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
    listeners=[appmesh.VirtualNodeListener.http(
        port=8080,
        health_check=appmesh.HealthCheck.http(
            healthy_threshold=3,
            interval=cdk.Duration.seconds(5),
            path="/ping",
            timeout=cdk.Duration.seconds(2),
            unhealthy_threshold=2
        ),
        timeout=appmesh.HttpTimeout(
            idle=cdk.Duration.seconds(5)
        )
    )],
    access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
)

virtual_service = appmesh.VirtualService(self, "service-1",
    virtual_service_provider=appmesh.VirtualServiceProvider.virtual_router(router),
    virtual_service_name="service1.domain.local"
)

node.add_backend(appmesh.Backend.virtual_service(virtual_service))
```

The `listeners` property can be left blank and added later with the `node.addListener()` method. The `serviceDiscovery` property must be specified when specifying a listener.

The `backends` property can be added with `node.addBackend()`. In the example, we define a virtual service and add it to the virtual node to allow egress traffic to other nodes.

The `backendDefaults` property is added to the node while creating the virtual node. These are the virtual node's default settings for all backends.

The `VirtualNode.addBackend()` method is especially useful if you want to create a circular traffic flow by having a Virtual Service as a backend whose provider is that same Virtual Node:

```python
# mesh: appmesh.Mesh


node = appmesh.VirtualNode(self, "node",
    mesh=mesh,
    service_discovery=appmesh.ServiceDiscovery.dns("node")
)

virtual_service = appmesh.VirtualService(self, "service-1",
    virtual_service_provider=appmesh.VirtualServiceProvider.virtual_node(node),
    virtual_service_name="service1.domain.local"
)

node.add_backend(appmesh.Backend.virtual_service(virtual_service))
```

### Adding TLS to a listener

The `tls` property specifies TLS configuration when creating a listener for a virtual node or a virtual gateway.
Provide the TLS certificate to the proxy in one of the following ways:

* A certificate from AWS Certificate Manager (ACM).
* A customer-provided certificate (specify a `certificateChain` path file and a `privateKey` file path).
* A certificate provided by a Secrets Discovery Service (SDS) endpoint over local Unix Domain Socket (specify its `secretName`).

```python
# A Virtual Node with listener TLS from an ACM provided certificate
# cert: certificatemanager.Certificate
# mesh: appmesh.Mesh


node = appmesh.VirtualNode(self, "node",
    mesh=mesh,
    service_discovery=appmesh.ServiceDiscovery.dns("node"),
    listeners=[appmesh.VirtualNodeListener.grpc(
        port=80,
        tls=appmesh.ListenerTlsOptions(
            mode=appmesh.TlsMode.STRICT,
            certificate=appmesh.TlsCertificate.acm(cert)
        )
    )]
)

# A Virtual Gateway with listener TLS from a customer provided file certificate
gateway = appmesh.VirtualGateway(self, "gateway",
    mesh=mesh,
    listeners=[appmesh.VirtualGatewayListener.grpc(
        port=8080,
        tls=appmesh.ListenerTlsOptions(
            mode=appmesh.TlsMode.STRICT,
            certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey")
        )
    )],
    virtual_gateway_name="gateway"
)

# A Virtual Gateway with listener TLS from a SDS provided certificate
gateway2 = appmesh.VirtualGateway(self, "gateway2",
    mesh=mesh,
    listeners=[appmesh.VirtualGatewayListener.http2(
        port=8080,
        tls=appmesh.ListenerTlsOptions(
            mode=appmesh.TlsMode.STRICT,
            certificate=appmesh.TlsCertificate.sds("secrete_certificate")
        )
    )],
    virtual_gateway_name="gateway2"
)
```

### Adding mutual TLS authentication

Mutual TLS authentication is an optional component of TLS that offers two-way peer authentication.
To enable mutual TLS authentication, add the `mutualTlsCertificate` property to TLS client policy and/or the `mutualTlsValidation` property to your TLS listener.

`tls.mutualTlsValidation` and `tlsClientPolicy.mutualTlsCertificate` can be sourced from either:

* A customer-provided certificate (specify a `certificateChain` path file and a `privateKey` file path).
* A certificate provided by a Secrets Discovery Service (SDS) endpoint over local Unix Domain Socket (specify its `secretName`).

> **Note**
> Currently, a certificate from AWS Certificate Manager (ACM) cannot be used for mutual TLS authentication.

```python
# mesh: appmesh.Mesh


node1 = appmesh.VirtualNode(self, "node1",
    mesh=mesh,
    service_discovery=appmesh.ServiceDiscovery.dns("node"),
    listeners=[appmesh.VirtualNodeListener.grpc(
        port=80,
        tls=appmesh.ListenerTlsOptions(
            mode=appmesh.TlsMode.STRICT,
            certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey"),
            # Validate a file client certificates to enable mutual TLS authentication when a client provides a certificate.
            mutual_tls_validation=appmesh.MutualTlsValidation(
                trust=appmesh.TlsValidationTrust.file("path-to-certificate")
            )
        )
    )]
)

certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
node2 = appmesh.VirtualNode(self, "node2",
    mesh=mesh,
    service_discovery=appmesh.ServiceDiscovery.dns("node2"),
    backend_defaults=appmesh.BackendDefaults(
        tls_client_policy=appmesh.TlsClientPolicy(
            ports=[8080, 8081],
            validation=appmesh.TlsValidation(
                subject_alternative_names=appmesh.SubjectAlternativeNames.matching_exactly("mesh-endpoint.apps.local"),
                trust=appmesh.TlsValidationTrust.acm([
                    acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                ])
            ),
            # Provide a SDS client certificate when a server requests it and enable mutual TLS authentication.
            mutual_tls_certificate=appmesh.TlsCertificate.sds("secret_certificate")
        )
    )
)
```

### Adding outlier detection to a Virtual Node listener

The `outlierDetection` property adds outlier detection to a Virtual Node listener. The properties
`baseEjectionDuration`, `interval`, `maxEjectionPercent`, and `maxServerErrors` are required.

```python
# mesh: appmesh.Mesh
# Cloud Map service discovery is currently required for host ejection by outlier detection
vpc = ec2.Vpc(self, "vpc")
namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
    vpc=vpc,
    name="domain.local"
)
service = namespace.create_service("Svc")
node = mesh.add_virtual_node("virtual-node",
    service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
    listeners=[appmesh.VirtualNodeListener.http(
        outlier_detection=appmesh.OutlierDetection(
            base_ejection_duration=cdk.Duration.seconds(10),
            interval=cdk.Duration.seconds(30),
            max_ejection_percent=50,
            max_server_errors=5
        )
    )]
)
```

### Adding a connection pool to a listener

The `connectionPool` property can be added to a Virtual Node listener or Virtual Gateway listener to add a request connection pool. Each listener protocol type has its own connection pool properties.

```python
# A Virtual Node with a gRPC listener with a connection pool set
# mesh: appmesh.Mesh

node = appmesh.VirtualNode(self, "node",
    mesh=mesh,
    # DNS service discovery can optionally specify the DNS response type as either LOAD_BALANCER or ENDPOINTS.
    # LOAD_BALANCER means that the DNS resolver returns a loadbalanced set of endpoints,
    # whereas ENDPOINTS means that the DNS resolver is returning all the endpoints.
    # By default, the response type is assumed to be LOAD_BALANCER
    service_discovery=appmesh.ServiceDiscovery.dns("node", appmesh.DnsResponseType.ENDPOINTS),
    listeners=[appmesh.VirtualNodeListener.http(
        port=80,
        connection_pool=appmesh.HttpConnectionPool(
            max_connections=100,
            max_pending_requests=10
        )
    )]
)

# A Virtual Gateway with a gRPC listener with a connection pool set
gateway = appmesh.VirtualGateway(self, "gateway",
    mesh=mesh,
    listeners=[appmesh.VirtualGatewayListener.grpc(
        port=8080,
        connection_pool=appmesh.GrpcConnectionPool(
            max_requests=10
        )
    )],
    virtual_gateway_name="gateway"
)
```

## Adding a Route

A *route* matches requests with an associated virtual router and distributes traffic to its associated virtual nodes.
The route distributes matching requests to one or more target virtual nodes with relative weighting.

The `RouteSpec` class lets you define protocol-specific route specifications.
The `tcp()`, `http()`, `http2()`, and `grpc()` methods create a specification for the named protocols.

For HTTP-based routes, the match field can match on path (prefix, exact, or regex), HTTP method, scheme,
HTTP headers, and query parameters. By default, HTTP-based routes match all requests.

For gRPC-based routes, the match field can  match on service name, method name, and metadata.
When specifying the method name, the service name must also be specified.

For example, here's how to add an HTTP route that matches based on a prefix of the URL path:

```python
# router: appmesh.VirtualRouter
# node: appmesh.VirtualNode


router.add_route("route-http",
    route_spec=appmesh.RouteSpec.http(
        weighted_targets=[appmesh.WeightedTarget(
            virtual_node=node
        )
        ],
        match=appmesh.HttpRouteMatch(
            # Path that is passed to this method must start with '/'.
            path=appmesh.HttpRoutePathMatch.starts_with("/path-to-app")
        )
    )
)
```

Add an HTTP2 route that matches based on exact path, method, scheme, headers, and query parameters:

```python
# router: appmesh.VirtualRouter
# node: appmesh.VirtualNode


router.add_route("route-http2",
    route_spec=appmesh.RouteSpec.http2(
        weighted_targets=[appmesh.WeightedTarget(
            virtual_node=node
        )
        ],
        match=appmesh.HttpRouteMatch(
            path=appmesh.HttpRoutePathMatch.exactly("/exact"),
            method=appmesh.HttpRouteMethod.POST,
            protocol=appmesh.HttpRouteProtocol.HTTPS,
            headers=[
                # All specified headers must match for the route to match.
                appmesh.HeaderMatch.value_is("Content-Type", "application/json"),
                appmesh.HeaderMatch.value_is_not("Content-Type", "application/json")
            ],
            query_parameters=[
                # All specified query parameters must match for the route to match.
                appmesh.QueryParameterMatch.value_is("query-field", "value")
            ]
        )
    )
)
```

Add a single route with two targets and split traffic 50/50:

```python
# router: appmesh.VirtualRouter
# node: appmesh.VirtualNode


router.add_route("route-http",
    route_spec=appmesh.RouteSpec.http(
        weighted_targets=[appmesh.WeightedTarget(
            virtual_node=node,
            weight=50
        ), appmesh.WeightedTarget(
            virtual_node=node,
            weight=50
        )
        ],
        match=appmesh.HttpRouteMatch(
            path=appmesh.HttpRoutePathMatch.starts_with("/path-to-app")
        )
    )
)
```

Add an http2 route with retries:

```python
# router: appmesh.VirtualRouter
# node: appmesh.VirtualNode


router.add_route("route-http2-retry",
    route_spec=appmesh.RouteSpec.http2(
        weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
        retry_policy=appmesh.HttpRetryPolicy(
            # Retry if the connection failed
            tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
            # Retry if HTTP responds with a gateway error (502, 503, 504)
            http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
            # Retry five times
            retry_attempts=5,
            # Use a 1 second timeout per retry
            retry_timeout=cdk.Duration.seconds(1)
        )
    )
)
```

Add a gRPC route with retries:

```python
# router: appmesh.VirtualRouter
# node: appmesh.VirtualNode


router.add_route("route-grpc-retry",
    route_spec=appmesh.RouteSpec.grpc(
        weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
        match=appmesh.GrpcRouteMatch(service_name="servicename"),
        retry_policy=appmesh.GrpcRetryPolicy(
            tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
            http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
            # Retry if gRPC responds that the request was cancelled, a resource
            # was exhausted, or if the service is unavailable
            grpc_retry_events=[appmesh.GrpcRetryEvent.CANCELLED, appmesh.GrpcRetryEvent.RESOURCE_EXHAUSTED, appmesh.GrpcRetryEvent.UNAVAILABLE
            ],
            retry_attempts=5,
            retry_timeout=cdk.Duration.seconds(1)
        )
    )
)
```

Add an gRPC route that matches based on method name and metadata:

```python
# router: appmesh.VirtualRouter
# node: appmesh.VirtualNode


router.add_route("route-grpc-retry",
    route_spec=appmesh.RouteSpec.grpc(
        weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
        match=appmesh.GrpcRouteMatch(
            # When method name is specified, service name must be also specified.
            method_name="methodname",
            service_name="servicename",
            metadata=[
                # All specified metadata must match for the route to match.
                appmesh.HeaderMatch.value_starts_with("Content-Type", "application/"),
                appmesh.HeaderMatch.value_does_not_start_with("Content-Type", "text/")
            ]
        )
    )
)
```

Add a gRPC route with timeout:

```python
# router: appmesh.VirtualRouter
# node: appmesh.VirtualNode


router.add_route("route-http",
    route_spec=appmesh.RouteSpec.grpc(
        weighted_targets=[appmesh.WeightedTarget(
            virtual_node=node
        )
        ],
        match=appmesh.GrpcRouteMatch(
            service_name="my-service.default.svc.cluster.local"
        ),
        timeout=appmesh.GrpcTimeout(
            idle=cdk.Duration.seconds(2),
            per_request=cdk.Duration.seconds(1)
        )
    )
)
```

## Adding a Virtual Gateway

A *virtual gateway* allows resources outside your mesh to communicate with resources inside your mesh.
The virtual gateway represents an Envoy proxy running in an Amazon ECS task, in a Kubernetes service, or on an Amazon EC2 instance.
Unlike a virtual node, which represents Envoy running with an application, a virtual gateway represents Envoy deployed by itself.

A virtual gateway is similar to a virtual node in that it has a listener that accepts traffic for a particular port and protocol (HTTP, HTTP2, gRPC).
Traffic received by the virtual gateway is directed to other services in your mesh
using rules defined in gateway routes which can be added to your virtual gateway.

Create a virtual gateway with the constructor:

```python
# mesh: appmesh.Mesh

certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"

gateway = appmesh.VirtualGateway(self, "gateway",
    mesh=mesh,
    listeners=[appmesh.VirtualGatewayListener.http(
        port=443,
        health_check=appmesh.HealthCheck.http(
            interval=cdk.Duration.seconds(10)
        )
    )],
    backend_defaults=appmesh.BackendDefaults(
        tls_client_policy=appmesh.TlsClientPolicy(
            ports=[8080, 8081],
            validation=appmesh.TlsValidation(
                trust=appmesh.TlsValidationTrust.acm([
                    acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                ])
            )
        )
    ),
    access_log=appmesh.AccessLog.from_file_path("/dev/stdout"),
    virtual_gateway_name="virtualGateway"
)
```

Add a virtual gateway directly to the mesh:

```python
# mesh: appmesh.Mesh


gateway = mesh.add_virtual_gateway("gateway",
    access_log=appmesh.AccessLog.from_file_path("/dev/stdout"),
    virtual_gateway_name="virtualGateway",
    listeners=[appmesh.VirtualGatewayListener.http(
        port=443,
        health_check=appmesh.HealthCheck.http(
            interval=cdk.Duration.seconds(10)
        )
    )]
)
```

The `listeners` field defaults to an HTTP Listener on port 8080 if omitted.
A gateway route can be added using the `gateway.addGatewayRoute()` method.

The `backendDefaults` property, provided when creating the virtual gateway, specifies the virtual gateway's default settings for all backends.

## Adding a Gateway Route

A *gateway route* is attached to a virtual gateway and routes matching traffic to an existing virtual service.

For HTTP-based gateway routes, the `match` field can be used to match on
path (prefix, exact, or regex), HTTP method, host name, HTTP headers, and query parameters.
By default, HTTP-based gateway routes match all requests.

```python
# gateway: appmesh.VirtualGateway
# virtual_service: appmesh.VirtualService


gateway.add_gateway_route("gateway-route-http",
    route_spec=appmesh.GatewayRouteSpec.http(
        route_target=virtual_service,
        match=appmesh.HttpGatewayRouteMatch(
            path=appmesh.HttpGatewayRoutePathMatch.regex("regex")
        )
    )
)
```

For gRPC-based gateway routes, the `match` field can be used to match on service name, host name, and metadata.

```python
# gateway: appmesh.VirtualGateway
# virtual_service: appmesh.VirtualService


gateway.add_gateway_route("gateway-route-grpc",
    route_spec=appmesh.GatewayRouteSpec.grpc(
        route_target=virtual_service,
        match=appmesh.GrpcGatewayRouteMatch(
            hostname=appmesh.GatewayRouteHostnameMatch.ends_with(".example.com")
        )
    )
)
```

For HTTP based gateway routes, App Mesh automatically rewrites the matched prefix path in Gateway Route to “/”.
This automatic rewrite configuration can be overwritten in following ways:

```python
# gateway: appmesh.VirtualGateway
# virtual_service: appmesh.VirtualService


gateway.add_gateway_route("gateway-route-http",
    route_spec=appmesh.GatewayRouteSpec.http(
        route_target=virtual_service,
        match=appmesh.HttpGatewayRouteMatch(
            # This disables the default rewrite to '/', and retains original path.
            path=appmesh.HttpGatewayRoutePathMatch.starts_with("/path-to-app/", "")
        )
    )
)

gateway.add_gateway_route("gateway-route-http-1",
    route_spec=appmesh.GatewayRouteSpec.http(
        route_target=virtual_service,
        match=appmesh.HttpGatewayRouteMatch(
            # If the request full path is '/path-to-app/xxxxx', this rewrites the path to '/rewrittenUri/xxxxx'.
            # Please note both `prefixPathMatch` and `rewriteTo` must start and end with the `/` character.
            path=appmesh.HttpGatewayRoutePathMatch.starts_with("/path-to-app/", "/rewrittenUri/")
        )
    )
)
```

If matching other path (exact or regex), only specific rewrite path can be specified.
Unlike `startsWith()` method above, no default rewrite is performed.

```python
# gateway: appmesh.VirtualGateway
# virtual_service: appmesh.VirtualService


gateway.add_gateway_route("gateway-route-http-2",
    route_spec=appmesh.GatewayRouteSpec.http(
        route_target=virtual_service,
        match=appmesh.HttpGatewayRouteMatch(
            # This rewrites the path from '/test' to '/rewrittenPath'.
            path=appmesh.HttpGatewayRoutePathMatch.exactly("/test", "/rewrittenPath")
        )
    )
)
```

For HTTP/gRPC based routes, App Mesh automatically rewrites
the original request received at the Virtual Gateway to the destination Virtual Service name.
This default host name rewrite can be configured by specifying the rewrite rule as one of the `match` property:

```python
# gateway: appmesh.VirtualGateway
# virtual_service: appmesh.VirtualService


gateway.add_gateway_route("gateway-route-grpc",
    route_spec=appmesh.GatewayRouteSpec.grpc(
        route_target=virtual_service,
        match=appmesh.GrpcGatewayRouteMatch(
            hostname=appmesh.GatewayRouteHostnameMatch.exactly("example.com"),
            # This disables the default rewrite to virtual service name and retain original request.
            rewrite_request_hostname=False
        )
    )
)
```

## Importing Resources

Each App Mesh resource class comes with two static methods, `from<Resource>Arn` and `from<Resource>Attributes` (where `<Resource>` is replaced with the resource name, such as `VirtualNode`) for importing a reference to an existing App Mesh resource.
These imported resources can be used with other resources in your mesh as if they were defined directly in your CDK application.

```python
arn = "arn:aws:appmesh:us-east-1:123456789012:mesh/testMesh/virtualNode/testNode"
appmesh.VirtualNode.from_virtual_node_arn(self, "importedVirtualNode", arn)
```

```python
virtual_node_name = "my-virtual-node"
appmesh.VirtualNode.from_virtual_node_attributes(self, "imported-virtual-node",
    mesh=appmesh.Mesh.from_mesh_name(self, "Mesh", "testMesh"),
    virtual_node_name=virtual_node_name
)
```

To import a mesh, again there are two static methods, `fromMeshArn` and `fromMeshName`.

```python
arn = "arn:aws:appmesh:us-east-1:123456789012:mesh/testMesh"
appmesh.Mesh.from_mesh_arn(self, "imported-mesh", arn)
```

```python
appmesh.Mesh.from_mesh_name(self, "imported-mesh", "abc")
```

## IAM Grants

`VirtualNode` and `VirtualGateway` provide `grantStreamAggregatedResources` methods that grant identities that are running
Envoy access to stream generated config from App Mesh.

```python
# mesh: appmesh.Mesh

gateway = appmesh.VirtualGateway(self, "testGateway", mesh=mesh)
envoy_user = iam.User(self, "envoyUser")

#
# This will grant `grantStreamAggregatedResources` ONLY for this gateway.
#
gateway.grant_stream_aggregated_resources(envoy_user)
```

## Adding Resources to shared meshes

A shared mesh allows resources created by different accounts to communicate with each other in the same mesh:

```python
# This is the ARN for the mesh from different AWS IAM account ID.
# Ensure mesh is properly shared with your account. For more details, see: https://github.com/aws/aws-cdk/issues/15404
arn = "arn:aws:appmesh:us-east-1:123456789012:mesh/testMesh"
shared_mesh = appmesh.Mesh.from_mesh_arn(self, "imported-mesh", arn)

# This VirtualNode resource can communicate with the resources in the mesh from different AWS IAM account ID.
appmesh.VirtualNode(self, "test-node",
    mesh=shared_mesh
)
```
'''
import abc
import builtins
import datetime
import enum
import typing

import jsii
import publication
import typing_extensions

from typeguard import check_type

from ._jsii import *

import aws_cdk.aws_acmpca
import aws_cdk.aws_certificatemanager
import aws_cdk.aws_iam
import aws_cdk.aws_servicediscovery
import aws_cdk.core
import constructs


class AccessLog(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.AccessLog",
):
    '''Configuration for Envoy Access logs for mesh endpoints.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        vpc = ec2.Vpc(self, "vpc")
        namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
            vpc=vpc,
            name="domain.local"
        )
        service = namespace.create_service("Svc")
        node = mesh.add_virtual_node("virtual-node",
            service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
            listeners=[appmesh.VirtualNodeListener.http(
                port=8081,
                health_check=appmesh.HealthCheck.http(
                    healthy_threshold=3,
                    interval=cdk.Duration.seconds(5),  # minimum
                    path="/health-check-path",
                    timeout=cdk.Duration.seconds(2),  # minimum
                    unhealthy_threshold=2
                )
            )],
            access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="fromFilePath")
    @builtins.classmethod
    def from_file_path(cls, file_path: builtins.str) -> "AccessLog":
        '''Path to a file to write access logs to.

        :param file_path: -

        :default: - no file based access logging
        '''
        if __debug__:
            type_hints = typing.get_type_hints(AccessLog.from_file_path)
            check_type(argname="argument file_path", value=file_path, expected_type=type_hints["file_path"])
        return typing.cast("AccessLog", jsii.sinvoke(cls, "fromFilePath", [file_path]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "AccessLogConfig":
        '''Called when the AccessLog type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        '''
        ...


class _AccessLogProxy(AccessLog):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "AccessLogConfig":
        '''Called when the AccessLog type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(AccessLog.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("AccessLogConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, AccessLog).__jsii_proxy_class__ = lambda : _AccessLogProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.AccessLogConfig",
    jsii_struct_bases=[],
    name_mapping={
        "virtual_gateway_access_log": "virtualGatewayAccessLog",
        "virtual_node_access_log": "virtualNodeAccessLog",
    },
)
class AccessLogConfig:
    def __init__(
        self,
        *,
        virtual_gateway_access_log: typing.Optional[typing.Union["CfnVirtualGateway.VirtualGatewayAccessLogProperty", typing.Dict[str, typing.Any]]] = None,
        virtual_node_access_log: typing.Optional[typing.Union["CfnVirtualNode.AccessLogProperty", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''All Properties for Envoy Access logs for mesh endpoints.

        :param virtual_gateway_access_log: VirtualGateway CFN configuration for Access Logging. Default: - no access logging
        :param virtual_node_access_log: VirtualNode CFN configuration for Access Logging. Default: - no access logging

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            access_log_config = appmesh.AccessLogConfig(
                virtual_gateway_access_log=appmesh.CfnVirtualGateway.VirtualGatewayAccessLogProperty(
                    file=appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty(
                        path="path",
            
                        # the properties below are optional
                        format=appmesh.CfnVirtualGateway.LoggingFormatProperty(
                            json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                                key="key",
                                value="value"
                            )],
                            text="text"
                        )
                    )
                ),
                virtual_node_access_log=appmesh.CfnVirtualNode.AccessLogProperty(
                    file=appmesh.CfnVirtualNode.FileAccessLogProperty(
                        path="path",
            
                        # the properties below are optional
                        format=appmesh.CfnVirtualNode.LoggingFormatProperty(
                            json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                                key="key",
                                value="value"
                            )],
                            text="text"
                        )
                    )
                )
            )
        '''
        if isinstance(virtual_gateway_access_log, dict):
            virtual_gateway_access_log = CfnVirtualGateway.VirtualGatewayAccessLogProperty(**virtual_gateway_access_log)
        if isinstance(virtual_node_access_log, dict):
            virtual_node_access_log = CfnVirtualNode.AccessLogProperty(**virtual_node_access_log)
        if __debug__:
            type_hints = typing.get_type_hints(AccessLogConfig.__init__)
            check_type(argname="argument virtual_gateway_access_log", value=virtual_gateway_access_log, expected_type=type_hints["virtual_gateway_access_log"])
            check_type(argname="argument virtual_node_access_log", value=virtual_node_access_log, expected_type=type_hints["virtual_node_access_log"])
        self._values: typing.Dict[str, typing.Any] = {}
        if virtual_gateway_access_log is not None:
            self._values["virtual_gateway_access_log"] = virtual_gateway_access_log
        if virtual_node_access_log is not None:
            self._values["virtual_node_access_log"] = virtual_node_access_log

    @builtins.property
    def virtual_gateway_access_log(
        self,
    ) -> typing.Optional["CfnVirtualGateway.VirtualGatewayAccessLogProperty"]:
        '''VirtualGateway CFN configuration for Access Logging.

        :default: - no access logging
        '''
        result = self._values.get("virtual_gateway_access_log")
        return typing.cast(typing.Optional["CfnVirtualGateway.VirtualGatewayAccessLogProperty"], result)

    @builtins.property
    def virtual_node_access_log(
        self,
    ) -> typing.Optional["CfnVirtualNode.AccessLogProperty"]:
        '''VirtualNode CFN configuration for Access Logging.

        :default: - no access logging
        '''
        result = self._values.get("virtual_node_access_log")
        return typing.cast(typing.Optional["CfnVirtualNode.AccessLogProperty"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AccessLogConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class Backend(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.Backend",
):
    '''Contains static factory methods to create backends.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        # router: appmesh.VirtualRouter
        # service: cloudmap.Service
        
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
            listeners=[appmesh.VirtualNodeListener.http(
                port=8080,
                health_check=appmesh.HealthCheck.http(
                    healthy_threshold=3,
                    interval=cdk.Duration.seconds(5),
                    path="/ping",
                    timeout=cdk.Duration.seconds(2),
                    unhealthy_threshold=2
                ),
                timeout=appmesh.HttpTimeout(
                    idle=cdk.Duration.seconds(5)
                )
            )],
            access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
        )
        
        virtual_service = appmesh.VirtualService(self, "service-1",
            virtual_service_provider=appmesh.VirtualServiceProvider.virtual_router(router),
            virtual_service_name="service1.domain.local"
        )
        
        node.add_backend(appmesh.Backend.virtual_service(virtual_service))
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="virtualService")
    @builtins.classmethod
    def virtual_service(
        cls,
        virtual_service: "IVirtualService",
        *,
        tls_client_policy: typing.Optional[typing.Union["TlsClientPolicy", typing.Dict[str, typing.Any]]] = None,
    ) -> "Backend":
        '''Construct a Virtual Service backend.

        :param virtual_service: -
        :param tls_client_policy: TLS properties for Client policy for the backend. Default: - none
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Backend.virtual_service)
            check_type(argname="argument virtual_service", value=virtual_service, expected_type=type_hints["virtual_service"])
        props = VirtualServiceBackendOptions(tls_client_policy=tls_client_policy)

        return typing.cast("Backend", jsii.sinvoke(cls, "virtualService", [virtual_service, props]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, _scope: aws_cdk.core.Construct) -> "BackendConfig":
        '''Return backend config.

        :param _scope: -
        '''
        ...


class _BackendProxy(Backend):
    @jsii.member(jsii_name="bind")
    def bind(self, _scope: aws_cdk.core.Construct) -> "BackendConfig":
        '''Return backend config.

        :param _scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Backend.bind)
            check_type(argname="argument _scope", value=_scope, expected_type=type_hints["_scope"])
        return typing.cast("BackendConfig", jsii.invoke(self, "bind", [_scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, Backend).__jsii_proxy_class__ = lambda : _BackendProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.BackendConfig",
    jsii_struct_bases=[],
    name_mapping={"virtual_service_backend": "virtualServiceBackend"},
)
class BackendConfig:
    def __init__(
        self,
        *,
        virtual_service_backend: typing.Union["CfnVirtualNode.BackendProperty", typing.Dict[str, typing.Any]],
    ) -> None:
        '''Properties for a backend.

        :param virtual_service_backend: Config for a Virtual Service backend.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            backend_config = appmesh.BackendConfig(
                virtual_service_backend=appmesh.CfnVirtualNode.BackendProperty(
                    virtual_service=appmesh.CfnVirtualNode.VirtualServiceBackendProperty(
                        virtual_service_name="virtualServiceName",
            
                        # the properties below are optional
                        client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                            tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                                validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                    trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                        acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                            certificate_authority_arns=["certificateAuthorityArns"]
                                        ),
                                        file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                            certificate_chain="certificateChain"
                                        ),
                                        sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                            secret_name="secretName"
                                        )
                                    ),
            
                                    # the properties below are optional
                                    subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                        match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                            exact=["exact"]
                                        )
                                    )
                                ),
            
                                # the properties below are optional
                                certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                        certificate_chain="certificateChain",
                                        private_key="privateKey"
                                    ),
                                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                        secret_name="secretName"
                                    )
                                ),
                                enforce=False,
                                ports=[123]
                            )
                        )
                    )
                )
            )
        '''
        if isinstance(virtual_service_backend, dict):
            virtual_service_backend = CfnVirtualNode.BackendProperty(**virtual_service_backend)
        if __debug__:
            type_hints = typing.get_type_hints(BackendConfig.__init__)
            check_type(argname="argument virtual_service_backend", value=virtual_service_backend, expected_type=type_hints["virtual_service_backend"])
        self._values: typing.Dict[str, typing.Any] = {
            "virtual_service_backend": virtual_service_backend,
        }

    @builtins.property
    def virtual_service_backend(self) -> "CfnVirtualNode.BackendProperty":
        '''Config for a Virtual Service backend.'''
        result = self._values.get("virtual_service_backend")
        assert result is not None, "Required property 'virtual_service_backend' is missing"
        return typing.cast("CfnVirtualNode.BackendProperty", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "BackendConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.BackendDefaults",
    jsii_struct_bases=[],
    name_mapping={"tls_client_policy": "tlsClientPolicy"},
)
class BackendDefaults:
    def __init__(
        self,
        *,
        tls_client_policy: typing.Optional[typing.Union["TlsClientPolicy", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents the properties needed to define backend defaults.

        :param tls_client_policy: TLS properties for Client policy for backend defaults. Default: - none

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            # service: cloudmap.Service
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=8080,
                    health_check=appmesh.HealthCheck.http(
                        healthy_threshold=3,
                        interval=cdk.Duration.seconds(5),
                        path="/ping",
                        timeout=cdk.Duration.seconds(2),
                        unhealthy_threshold=2
                    ),
                    timeout=appmesh.HttpTimeout(
                        idle=cdk.Duration.seconds(5)
                    )
                )],
                backend_defaults=appmesh.BackendDefaults(
                    tls_client_policy=appmesh.TlsClientPolicy(
                        validation=appmesh.TlsValidation(
                            trust=appmesh.TlsValidationTrust.file("/keys/local_cert_chain.pem")
                        )
                    )
                ),
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
            )
            
            cdk.Tags.of(node).add("Environment", "Dev")
        '''
        if isinstance(tls_client_policy, dict):
            tls_client_policy = TlsClientPolicy(**tls_client_policy)
        if __debug__:
            type_hints = typing.get_type_hints(BackendDefaults.__init__)
            check_type(argname="argument tls_client_policy", value=tls_client_policy, expected_type=type_hints["tls_client_policy"])
        self._values: typing.Dict[str, typing.Any] = {}
        if tls_client_policy is not None:
            self._values["tls_client_policy"] = tls_client_policy

    @builtins.property
    def tls_client_policy(self) -> typing.Optional["TlsClientPolicy"]:
        '''TLS properties for Client policy for backend defaults.

        :default: - none
        '''
        result = self._values.get("tls_client_policy")
        return typing.cast(typing.Optional["TlsClientPolicy"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "BackendDefaults(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnGatewayRoute(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute",
):
    '''A CloudFormation ``AWS::AppMesh::GatewayRoute``.

    Creates a gateway route.

    A gateway route is attached to a virtual gateway and routes traffic to an existing virtual service. If a route matches a request, it can distribute traffic to a target virtual service.

    For more information about gateway routes, see `Gateway routes <https://docs.aws.amazon.com/app-mesh/latest/userguide/gateway-routes.html>`_ .

    :cloudformationResource: AWS::AppMesh::GatewayRoute
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        cfn_gateway_route = appmesh.CfnGatewayRoute(self, "MyCfnGatewayRoute",
            mesh_name="meshName",
            spec=appmesh.CfnGatewayRoute.GatewayRouteSpecProperty(
                grpc_route=appmesh.CfnGatewayRoute.GrpcGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.GrpcGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
        
                            # the properties below are optional
                            port=123
                        ),
        
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.GrpcGatewayRouteMatchProperty(
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        metadata=[appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty(
                            name="name",
        
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        port=123,
                        service_name="serviceName"
                    )
                ),
                http2_route=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
        
                            # the properties below are optional
                            port=123
                        ),
        
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            ),
                            path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                exact="exact"
                            ),
                            prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                default_prefix="defaultPrefix",
                                value="value"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                        headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                            name="name",
        
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        method="method",
                        path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                            name="name",
        
                            # the properties below are optional
                            match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )]
                    )
                ),
                http_route=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
        
                            # the properties below are optional
                            port=123
                        ),
        
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            ),
                            path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                exact="exact"
                            ),
                            prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                default_prefix="defaultPrefix",
                                value="value"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                        headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                            name="name",
        
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        method="method",
                        path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                            name="name",
        
                            # the properties below are optional
                            match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )]
                    )
                ),
                priority=123
            ),
            virtual_gateway_name="virtualGatewayName",
        
            # the properties below are optional
            gateway_route_name="gatewayRouteName",
            mesh_owner="meshOwner",
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[typing.Union["CfnGatewayRoute.GatewayRouteSpecProperty", typing.Dict[str, typing.Any]], aws_cdk.core.IResolvable],
        virtual_gateway_name: builtins.str,
        gateway_route_name: typing.Optional[builtins.str] = None,
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Create a new ``AWS::AppMesh::GatewayRoute``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param mesh_name: The name of the service mesh that the resource resides in.
        :param spec: The specifications of the gateway route.
        :param virtual_gateway_name: The virtual gateway that the gateway route is associated with.
        :param gateway_route_name: The name of the gateway route.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the gateway route to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnGatewayRoute.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = CfnGatewayRouteProps(
            mesh_name=mesh_name,
            spec=spec,
            virtual_gateway_name=virtual_gateway_name,
            gateway_route_name=gateway_route_name,
            mesh_owner=mesh_owner,
            tags=tags,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnGatewayRoute.inspect)
            check_type(argname="argument inspector", value=inspector, expected_type=type_hints["inspector"])
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnGatewayRoute._render_properties)
            check_type(argname="argument props", value=props, expected_type=type_hints["props"])
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''The full Amazon Resource Name (ARN) for the gateway route.

        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property
    @jsii.member(jsii_name="attrGatewayRouteName")
    def attr_gateway_route_name(self) -> builtins.str:
        '''The name of the gateway route.

        :cloudformationAttribute: GatewayRouteName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrGatewayRouteName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshName")
    def attr_mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the gateway route resides in.

        :cloudformationAttribute: MeshName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshOwner")
    def attr_mesh_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: MeshOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrResourceOwner")
    def attr_resource_owner(self) -> builtins.str:
        '''The IAM account ID of the resource owner.

        If the account ID is not your own, then it's the ID of the mesh owner or of another account that the mesh is shared with. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: ResourceOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrUid")
    def attr_uid(self) -> builtins.str:
        '''The unique identifier for the gateway route.

        :cloudformationAttribute: Uid
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrUid"))

    @builtins.property
    @jsii.member(jsii_name="attrVirtualGatewayName")
    def attr_virtual_gateway_name(self) -> builtins.str:
        '''The name of the virtual gateway that the gateway route is associated with.

        :cloudformationAttribute: VirtualGatewayName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVirtualGatewayName"))

    @builtins.property
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''Optional metadata that you can apply to the gateway route to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the resource resides in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-meshname
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))

    @mesh_name.setter
    def mesh_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnGatewayRoute, "mesh_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshName", value)

    @builtins.property
    @jsii.member(jsii_name="spec")
    def spec(
        self,
    ) -> typing.Union["CfnGatewayRoute.GatewayRouteSpecProperty", aws_cdk.core.IResolvable]:
        '''The specifications of the gateway route.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-spec
        '''
        return typing.cast(typing.Union["CfnGatewayRoute.GatewayRouteSpecProperty", aws_cdk.core.IResolvable], jsii.get(self, "spec"))

    @spec.setter
    def spec(
        self,
        value: typing.Union["CfnGatewayRoute.GatewayRouteSpecProperty", aws_cdk.core.IResolvable],
    ) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnGatewayRoute, "spec").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "spec", value)

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayName")
    def virtual_gateway_name(self) -> builtins.str:
        '''The virtual gateway that the gateway route is associated with.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-virtualgatewayname
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualGatewayName"))

    @virtual_gateway_name.setter
    def virtual_gateway_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnGatewayRoute, "virtual_gateway_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "virtualGatewayName", value)

    @builtins.property
    @jsii.member(jsii_name="gatewayRouteName")
    def gateway_route_name(self) -> typing.Optional[builtins.str]:
        '''The name of the gateway route.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-gatewayroutename
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "gatewayRouteName"))

    @gateway_route_name.setter
    def gateway_route_name(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnGatewayRoute, "gateway_route_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "gatewayRouteName", value)

    @builtins.property
    @jsii.member(jsii_name="meshOwner")
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-meshowner
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "meshOwner"))

    @mesh_owner.setter
    def mesh_owner(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnGatewayRoute, "mesh_owner").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshOwner", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact", "suffix": "suffix"},
    )
    class GatewayRouteHostnameMatchProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[builtins.str] = None,
            suffix: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object representing the gateway route host name to match.

            :param exact: The exact host name to match on.
            :param suffix: The specified ending characters of the host name to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutehostnamematch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                gateway_route_hostname_match_property = appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                    exact="exact",
                    suffix="suffix"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GatewayRouteHostnameMatchProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
                check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact
            if suffix is not None:
                self._values["suffix"] = suffix

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The exact host name to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutehostnamematch.html#cfn-appmesh-gatewayroute-gatewayroutehostnamematch-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def suffix(self) -> typing.Optional[builtins.str]:
            '''The specified ending characters of the host name to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutehostnamematch.html#cfn-appmesh-gatewayroute-gatewayroutehostnamematch-suffix
            '''
            result = self._values.get("suffix")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GatewayRouteHostnameMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty",
        jsii_struct_bases=[],
        name_mapping={"default_target_hostname": "defaultTargetHostname"},
    )
    class GatewayRouteHostnameRewriteProperty:
        def __init__(
            self,
            *,
            default_target_hostname: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object representing the gateway route host name to rewrite.

            :param default_target_hostname: The default target host name to write to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutehostnamerewrite.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                gateway_route_hostname_rewrite_property = appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                    default_target_hostname="defaultTargetHostname"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GatewayRouteHostnameRewriteProperty.__init__)
                check_type(argname="argument default_target_hostname", value=default_target_hostname, expected_type=type_hints["default_target_hostname"])
            self._values: typing.Dict[str, typing.Any] = {}
            if default_target_hostname is not None:
                self._values["default_target_hostname"] = default_target_hostname

        @builtins.property
        def default_target_hostname(self) -> typing.Optional[builtins.str]:
            '''The default target host name to write to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutehostnamerewrite.html#cfn-appmesh-gatewayroute-gatewayroutehostnamerewrite-defaulttargethostname
            '''
            result = self._values.get("default_target_hostname")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GatewayRouteHostnameRewriteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty",
        jsii_struct_bases=[],
        name_mapping={
            "exact": "exact",
            "prefix": "prefix",
            "range": "range",
            "regex": "regex",
            "suffix": "suffix",
        },
    )
    class GatewayRouteMetadataMatchProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[builtins.str] = None,
            prefix: typing.Optional[builtins.str] = None,
            range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteRangeMatchProperty", typing.Dict[str, typing.Any]]]] = None,
            regex: typing.Optional[builtins.str] = None,
            suffix: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object representing the method header to be matched.

            :param exact: The exact method header to be matched on.
            :param prefix: The specified beginning characters of the method header to be matched on.
            :param range: An object that represents the range of values to match on.
            :param regex: The regex used to match the method header.
            :param suffix: The specified ending characters of the method header to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutemetadatamatch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                gateway_route_metadata_match_property = appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                    exact="exact",
                    prefix="prefix",
                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                        end=123,
                        start=123
                    ),
                    regex="regex",
                    suffix="suffix"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GatewayRouteMetadataMatchProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
                check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
                check_type(argname="argument range", value=range, expected_type=type_hints["range"])
                check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
                check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact
            if prefix is not None:
                self._values["prefix"] = prefix
            if range is not None:
                self._values["range"] = range
            if regex is not None:
                self._values["regex"] = regex
            if suffix is not None:
                self._values["suffix"] = suffix

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The exact method header to be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutemetadatamatch.html#cfn-appmesh-gatewayroute-gatewayroutemetadatamatch-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def prefix(self) -> typing.Optional[builtins.str]:
            '''The specified beginning characters of the method header to be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutemetadatamatch.html#cfn-appmesh-gatewayroute-gatewayroutemetadatamatch-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def range(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteRangeMatchProperty"]]:
            '''An object that represents the range of values to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutemetadatamatch.html#cfn-appmesh-gatewayroute-gatewayroutemetadatamatch-range
            '''
            result = self._values.get("range")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteRangeMatchProperty"]], result)

        @builtins.property
        def regex(self) -> typing.Optional[builtins.str]:
            '''The regex used to match the method header.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutemetadatamatch.html#cfn-appmesh-gatewayroute-gatewayroutemetadatamatch-regex
            '''
            result = self._values.get("regex")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def suffix(self) -> typing.Optional[builtins.str]:
            '''The specified ending characters of the method header to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutemetadatamatch.html#cfn-appmesh-gatewayroute-gatewayroutemetadatamatch-suffix
            '''
            result = self._values.get("suffix")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GatewayRouteMetadataMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty",
        jsii_struct_bases=[],
        name_mapping={"end": "end", "start": "start"},
    )
    class GatewayRouteRangeMatchProperty:
        def __init__(self, *, end: jsii.Number, start: jsii.Number) -> None:
            '''An object that represents the range of values to match on.

            The first character of the range is included in the range, though the last character is not. For example, if the range specified were 1-100, only values 1-99 would be matched.

            :param end: The end of the range.
            :param start: The start of the range.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayrouterangematch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                gateway_route_range_match_property = appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                    end=123,
                    start=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GatewayRouteRangeMatchProperty.__init__)
                check_type(argname="argument end", value=end, expected_type=type_hints["end"])
                check_type(argname="argument start", value=start, expected_type=type_hints["start"])
            self._values: typing.Dict[str, typing.Any] = {
                "end": end,
                "start": start,
            }

        @builtins.property
        def end(self) -> jsii.Number:
            '''The end of the range.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayrouterangematch.html#cfn-appmesh-gatewayroute-gatewayrouterangematch-end
            '''
            result = self._values.get("end")
            assert result is not None, "Required property 'end' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def start(self) -> jsii.Number:
            '''The start of the range.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayrouterangematch.html#cfn-appmesh-gatewayroute-gatewayrouterangematch-start
            '''
            result = self._values.get("start")
            assert result is not None, "Required property 'start' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GatewayRouteRangeMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GatewayRouteSpecProperty",
        jsii_struct_bases=[],
        name_mapping={
            "grpc_route": "grpcRoute",
            "http2_route": "http2Route",
            "http_route": "httpRoute",
            "priority": "priority",
        },
    )
    class GatewayRouteSpecProperty:
        def __init__(
            self,
            *,
            grpc_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GrpcGatewayRouteProperty", typing.Dict[str, typing.Any]]]] = None,
            http2_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRouteProperty", typing.Dict[str, typing.Any]]]] = None,
            http_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRouteProperty", typing.Dict[str, typing.Any]]]] = None,
            priority: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''An object that represents a gateway route specification.

            Specify one gateway route type.

            :param grpc_route: An object that represents the specification of a gRPC gateway route.
            :param http2_route: An object that represents the specification of an HTTP/2 gateway route.
            :param http_route: An object that represents the specification of an HTTP gateway route.
            :param priority: The ordering of the gateway routes spec.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutespec.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                gateway_route_spec_property = appmesh.CfnGatewayRoute.GatewayRouteSpecProperty(
                    grpc_route=appmesh.CfnGatewayRoute.GrpcGatewayRouteProperty(
                        action=appmesh.CfnGatewayRoute.GrpcGatewayRouteActionProperty(
                            target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                                virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                    virtual_service_name="virtualServiceName"
                                ),
                
                                # the properties below are optional
                                port=123
                            ),
                
                            # the properties below are optional
                            rewrite=appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty(
                                hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                    default_target_hostname="defaultTargetHostname"
                                )
                            )
                        ),
                        match=appmesh.CfnGatewayRoute.GrpcGatewayRouteMatchProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                                exact="exact",
                                suffix="suffix"
                            ),
                            metadata=[appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty(
                                name="name",
                
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            port=123,
                            service_name="serviceName"
                        )
                    ),
                    http2_route=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                        action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                            target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                                virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                    virtual_service_name="virtualServiceName"
                                ),
                
                                # the properties below are optional
                                port=123
                            ),
                
                            # the properties below are optional
                            rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                                hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                    default_target_hostname="defaultTargetHostname"
                                ),
                                path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                    exact="exact"
                                ),
                                prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                    default_prefix="defaultPrefix",
                                    value="value"
                                )
                            )
                        ),
                        match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                            headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                                name="name",
                
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                                exact="exact",
                                suffix="suffix"
                            ),
                            method="method",
                            path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                                name="name",
                
                                # the properties below are optional
                                match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )]
                        )
                    ),
                    http_route=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                        action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                            target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                                virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                    virtual_service_name="virtualServiceName"
                                ),
                
                                # the properties below are optional
                                port=123
                            ),
                
                            # the properties below are optional
                            rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                                hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                    default_target_hostname="defaultTargetHostname"
                                ),
                                path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                    exact="exact"
                                ),
                                prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                    default_prefix="defaultPrefix",
                                    value="value"
                                )
                            )
                        ),
                        match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                            headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                                name="name",
                
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                                exact="exact",
                                suffix="suffix"
                            ),
                            method="method",
                            path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                                name="name",
                
                                # the properties below are optional
                                match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )]
                        )
                    ),
                    priority=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GatewayRouteSpecProperty.__init__)
                check_type(argname="argument grpc_route", value=grpc_route, expected_type=type_hints["grpc_route"])
                check_type(argname="argument http2_route", value=http2_route, expected_type=type_hints["http2_route"])
                check_type(argname="argument http_route", value=http_route, expected_type=type_hints["http_route"])
                check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            self._values: typing.Dict[str, typing.Any] = {}
            if grpc_route is not None:
                self._values["grpc_route"] = grpc_route
            if http2_route is not None:
                self._values["http2_route"] = http2_route
            if http_route is not None:
                self._values["http_route"] = http_route
            if priority is not None:
                self._values["priority"] = priority

        @builtins.property
        def grpc_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteProperty"]]:
            '''An object that represents the specification of a gRPC gateway route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutespec.html#cfn-appmesh-gatewayroute-gatewayroutespec-grpcroute
            '''
            result = self._values.get("grpc_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteProperty"]], result)

        @builtins.property
        def http2_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteProperty"]]:
            '''An object that represents the specification of an HTTP/2 gateway route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutespec.html#cfn-appmesh-gatewayroute-gatewayroutespec-http2route
            '''
            result = self._values.get("http2_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteProperty"]], result)

        @builtins.property
        def http_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteProperty"]]:
            '''An object that represents the specification of an HTTP gateway route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutespec.html#cfn-appmesh-gatewayroute-gatewayroutespec-httproute
            '''
            result = self._values.get("http_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteProperty"]], result)

        @builtins.property
        def priority(self) -> typing.Optional[jsii.Number]:
            '''The ordering of the gateway routes spec.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutespec.html#cfn-appmesh-gatewayroute-gatewayroutespec-priority
            '''
            result = self._values.get("priority")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GatewayRouteSpecProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GatewayRouteTargetProperty",
        jsii_struct_bases=[],
        name_mapping={"virtual_service": "virtualService", "port": "port"},
    )
    class GatewayRouteTargetProperty:
        def __init__(
            self,
            *,
            virtual_service: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteVirtualServiceProperty", typing.Dict[str, typing.Any]]],
            port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''An object that represents a gateway route target.

            :param virtual_service: An object that represents a virtual service gateway route target.
            :param port: ``CfnGatewayRoute.GatewayRouteTargetProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutetarget.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                gateway_route_target_property = appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                    virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                        virtual_service_name="virtualServiceName"
                    ),
                
                    # the properties below are optional
                    port=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GatewayRouteTargetProperty.__init__)
                check_type(argname="argument virtual_service", value=virtual_service, expected_type=type_hints["virtual_service"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            self._values: typing.Dict[str, typing.Any] = {
                "virtual_service": virtual_service,
            }
            if port is not None:
                self._values["port"] = port

        @builtins.property
        def virtual_service(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteVirtualServiceProperty"]:
            '''An object that represents a virtual service gateway route target.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutetarget.html#cfn-appmesh-gatewayroute-gatewayroutetarget-virtualservice
            '''
            result = self._values.get("virtual_service")
            assert result is not None, "Required property 'virtual_service' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteVirtualServiceProperty"], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnGatewayRoute.GatewayRouteTargetProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutetarget.html#cfn-appmesh-gatewayroute-gatewayroutetarget-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GatewayRouteTargetProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty",
        jsii_struct_bases=[],
        name_mapping={"virtual_service_name": "virtualServiceName"},
    )
    class GatewayRouteVirtualServiceProperty:
        def __init__(self, *, virtual_service_name: builtins.str) -> None:
            '''An object that represents the virtual service that traffic is routed to.

            :param virtual_service_name: The name of the virtual service that traffic is routed to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutevirtualservice.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                gateway_route_virtual_service_property = appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                    virtual_service_name="virtualServiceName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GatewayRouteVirtualServiceProperty.__init__)
                check_type(argname="argument virtual_service_name", value=virtual_service_name, expected_type=type_hints["virtual_service_name"])
            self._values: typing.Dict[str, typing.Any] = {
                "virtual_service_name": virtual_service_name,
            }

        @builtins.property
        def virtual_service_name(self) -> builtins.str:
            '''The name of the virtual service that traffic is routed to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-gatewayroutevirtualservice.html#cfn-appmesh-gatewayroute-gatewayroutevirtualservice-virtualservicename
            '''
            result = self._values.get("virtual_service_name")
            assert result is not None, "Required property 'virtual_service_name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GatewayRouteVirtualServiceProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GrpcGatewayRouteActionProperty",
        jsii_struct_bases=[],
        name_mapping={"target": "target", "rewrite": "rewrite"},
    )
    class GrpcGatewayRouteActionProperty:
        def __init__(
            self,
            *,
            target: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteTargetProperty", typing.Dict[str, typing.Any]]],
            rewrite: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GrpcGatewayRouteRewriteProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the action to take if a match is determined.

            :param target: An object that represents the target that traffic is routed to when a request matches the gateway route.
            :param rewrite: The gateway route action to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayrouteaction.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_gateway_route_action_property = appmesh.CfnGatewayRoute.GrpcGatewayRouteActionProperty(
                    target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                        virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                            virtual_service_name="virtualServiceName"
                        ),
                
                        # the properties below are optional
                        port=123
                    ),
                
                    # the properties below are optional
                    rewrite=appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty(
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                            default_target_hostname="defaultTargetHostname"
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GrpcGatewayRouteActionProperty.__init__)
                check_type(argname="argument target", value=target, expected_type=type_hints["target"])
                check_type(argname="argument rewrite", value=rewrite, expected_type=type_hints["rewrite"])
            self._values: typing.Dict[str, typing.Any] = {
                "target": target,
            }
            if rewrite is not None:
                self._values["rewrite"] = rewrite

        @builtins.property
        def target(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteTargetProperty"]:
            '''An object that represents the target that traffic is routed to when a request matches the gateway route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayrouteaction.html#cfn-appmesh-gatewayroute-grpcgatewayrouteaction-target
            '''
            result = self._values.get("target")
            assert result is not None, "Required property 'target' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteTargetProperty"], result)

        @builtins.property
        def rewrite(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteRewriteProperty"]]:
            '''The gateway route action to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayrouteaction.html#cfn-appmesh-gatewayroute-grpcgatewayrouteaction-rewrite
            '''
            result = self._values.get("rewrite")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteRewriteProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcGatewayRouteActionProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GrpcGatewayRouteMatchProperty",
        jsii_struct_bases=[],
        name_mapping={
            "hostname": "hostname",
            "metadata": "metadata",
            "port": "port",
            "service_name": "serviceName",
        },
    )
    class GrpcGatewayRouteMatchProperty:
        def __init__(
            self,
            *,
            hostname: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteHostnameMatchProperty", typing.Dict[str, typing.Any]]]] = None,
            metadata: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GrpcGatewayRouteMetadataProperty", typing.Dict[str, typing.Any]]]]]] = None,
            port: typing.Optional[jsii.Number] = None,
            service_name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the criteria for determining a request match.

            :param hostname: The gateway route host name to be matched on.
            :param metadata: The gateway route metadata to be matched on.
            :param port: ``CfnGatewayRoute.GrpcGatewayRouteMatchProperty.Port``.
            :param service_name: The fully qualified domain name for the service to match from the request.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutematch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_gateway_route_match_property = appmesh.CfnGatewayRoute.GrpcGatewayRouteMatchProperty(
                    hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                        exact="exact",
                        suffix="suffix"
                    ),
                    metadata=[appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty(
                        name="name",
                
                        # the properties below are optional
                        invert=False,
                        match=appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                            exact="exact",
                            prefix="prefix",
                            range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                end=123,
                                start=123
                            ),
                            regex="regex",
                            suffix="suffix"
                        )
                    )],
                    port=123,
                    service_name="serviceName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GrpcGatewayRouteMatchProperty.__init__)
                check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
                check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
                check_type(argname="argument service_name", value=service_name, expected_type=type_hints["service_name"])
            self._values: typing.Dict[str, typing.Any] = {}
            if hostname is not None:
                self._values["hostname"] = hostname
            if metadata is not None:
                self._values["metadata"] = metadata
            if port is not None:
                self._values["port"] = port
            if service_name is not None:
                self._values["service_name"] = service_name

        @builtins.property
        def hostname(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameMatchProperty"]]:
            '''The gateway route host name to be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutematch.html#cfn-appmesh-gatewayroute-grpcgatewayroutematch-hostname
            '''
            result = self._values.get("hostname")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameMatchProperty"]], result)

        @builtins.property
        def metadata(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteMetadataProperty"]]]]:
            '''The gateway route metadata to be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutematch.html#cfn-appmesh-gatewayroute-grpcgatewayroutematch-metadata
            '''
            result = self._values.get("metadata")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteMetadataProperty"]]]], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnGatewayRoute.GrpcGatewayRouteMatchProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutematch.html#cfn-appmesh-gatewayroute-grpcgatewayroutematch-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def service_name(self) -> typing.Optional[builtins.str]:
            '''The fully qualified domain name for the service to match from the request.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutematch.html#cfn-appmesh-gatewayroute-grpcgatewayroutematch-servicename
            '''
            result = self._values.get("service_name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcGatewayRouteMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty",
        jsii_struct_bases=[],
        name_mapping={"name": "name", "invert": "invert", "match": "match"},
    )
    class GrpcGatewayRouteMetadataProperty:
        def __init__(
            self,
            *,
            name: builtins.str,
            invert: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            match: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteMetadataMatchProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object representing the metadata of the gateway route.

            :param name: A name for the gateway route metadata.
            :param invert: Specify ``True`` to match anything except the match criteria. The default value is ``False`` .
            :param match: The criteria for determining a metadata match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutemetadata.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_gateway_route_metadata_property = appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty(
                    name="name",
                
                    # the properties below are optional
                    invert=False,
                    match=appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                        exact="exact",
                        prefix="prefix",
                        range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                            end=123,
                            start=123
                        ),
                        regex="regex",
                        suffix="suffix"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GrpcGatewayRouteMetadataProperty.__init__)
                check_type(argname="argument name", value=name, expected_type=type_hints["name"])
                check_type(argname="argument invert", value=invert, expected_type=type_hints["invert"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "name": name,
            }
            if invert is not None:
                self._values["invert"] = invert
            if match is not None:
                self._values["match"] = match

        @builtins.property
        def name(self) -> builtins.str:
            '''A name for the gateway route metadata.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutemetadata.html#cfn-appmesh-gatewayroute-grpcgatewayroutemetadata-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def invert(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''Specify ``True`` to match anything except the match criteria.

            The default value is ``False`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutemetadata.html#cfn-appmesh-gatewayroute-grpcgatewayroutemetadata-invert
            '''
            result = self._values.get("invert")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteMetadataMatchProperty"]]:
            '''The criteria for determining a metadata match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroutemetadata.html#cfn-appmesh-gatewayroute-grpcgatewayroutemetadata-match
            '''
            result = self._values.get("match")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteMetadataMatchProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcGatewayRouteMetadataProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GrpcGatewayRouteProperty",
        jsii_struct_bases=[],
        name_mapping={"action": "action", "match": "match"},
    )
    class GrpcGatewayRouteProperty:
        def __init__(
            self,
            *,
            action: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GrpcGatewayRouteActionProperty", typing.Dict[str, typing.Any]]],
            match: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GrpcGatewayRouteMatchProperty", typing.Dict[str, typing.Any]]],
        ) -> None:
            '''An object that represents a gRPC gateway route.

            :param action: An object that represents the action to take if a match is determined.
            :param match: An object that represents the criteria for determining a request match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroute.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_gateway_route_property = appmesh.CfnGatewayRoute.GrpcGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.GrpcGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
                
                            # the properties below are optional
                            port=123
                        ),
                
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.GrpcGatewayRouteMatchProperty(
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        metadata=[appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty(
                            name="name",
                
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        port=123,
                        service_name="serviceName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GrpcGatewayRouteProperty.__init__)
                check_type(argname="argument action", value=action, expected_type=type_hints["action"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "action": action,
                "match": match,
            }

        @builtins.property
        def action(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteActionProperty"]:
            '''An object that represents the action to take if a match is determined.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroute.html#cfn-appmesh-gatewayroute-grpcgatewayroute-action
            '''
            result = self._values.get("action")
            assert result is not None, "Required property 'action' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteActionProperty"], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteMatchProperty"]:
            '''An object that represents the criteria for determining a request match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayroute.html#cfn-appmesh-gatewayroute-grpcgatewayroute-match
            '''
            result = self._values.get("match")
            assert result is not None, "Required property 'match' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GrpcGatewayRouteMatchProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcGatewayRouteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty",
        jsii_struct_bases=[],
        name_mapping={"hostname": "hostname"},
    )
    class GrpcGatewayRouteRewriteProperty:
        def __init__(
            self,
            *,
            hostname: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteHostnameRewriteProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the gateway route to rewrite.

            :param hostname: The host name of the gateway route to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayrouterewrite.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_gateway_route_rewrite_property = appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty(
                    hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                        default_target_hostname="defaultTargetHostname"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.GrpcGatewayRouteRewriteProperty.__init__)
                check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            self._values: typing.Dict[str, typing.Any] = {}
            if hostname is not None:
                self._values["hostname"] = hostname

        @builtins.property
        def hostname(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameRewriteProperty"]]:
            '''The host name of the gateway route to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-grpcgatewayrouterewrite.html#cfn-appmesh-gatewayroute-grpcgatewayrouterewrite-hostname
            '''
            result = self._values.get("hostname")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameRewriteProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcGatewayRouteRewriteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty",
        jsii_struct_bases=[],
        name_mapping={"target": "target", "rewrite": "rewrite"},
    )
    class HttpGatewayRouteActionProperty:
        def __init__(
            self,
            *,
            target: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteTargetProperty", typing.Dict[str, typing.Any]]],
            rewrite: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRouteRewriteProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the action to take if a match is determined.

            :param target: An object that represents the target that traffic is routed to when a request matches the gateway route.
            :param rewrite: The gateway route action to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteaction.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_action_property = appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                    target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                        virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                            virtual_service_name="virtualServiceName"
                        ),
                
                        # the properties below are optional
                        port=123
                    ),
                
                    # the properties below are optional
                    rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                            default_target_hostname="defaultTargetHostname"
                        ),
                        path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                            exact="exact"
                        ),
                        prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                            default_prefix="defaultPrefix",
                            value="value"
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRouteActionProperty.__init__)
                check_type(argname="argument target", value=target, expected_type=type_hints["target"])
                check_type(argname="argument rewrite", value=rewrite, expected_type=type_hints["rewrite"])
            self._values: typing.Dict[str, typing.Any] = {
                "target": target,
            }
            if rewrite is not None:
                self._values["rewrite"] = rewrite

        @builtins.property
        def target(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteTargetProperty"]:
            '''An object that represents the target that traffic is routed to when a request matches the gateway route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteaction.html#cfn-appmesh-gatewayroute-httpgatewayrouteaction-target
            '''
            result = self._values.get("target")
            assert result is not None, "Required property 'target' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteTargetProperty"], result)

        @builtins.property
        def rewrite(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteRewriteProperty"]]:
            '''The gateway route action to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteaction.html#cfn-appmesh-gatewayroute-httpgatewayrouteaction-rewrite
            '''
            result = self._values.get("rewrite")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteRewriteProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRouteActionProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty",
        jsii_struct_bases=[],
        name_mapping={
            "exact": "exact",
            "prefix": "prefix",
            "range": "range",
            "regex": "regex",
            "suffix": "suffix",
        },
    )
    class HttpGatewayRouteHeaderMatchProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[builtins.str] = None,
            prefix: typing.Optional[builtins.str] = None,
            range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteRangeMatchProperty", typing.Dict[str, typing.Any]]]] = None,
            regex: typing.Optional[builtins.str] = None,
            suffix: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the method and value to match with the header value sent in a request.

            Specify one match method.

            :param exact: The value sent by the client must match the specified value exactly.
            :param prefix: The value sent by the client must begin with the specified characters.
            :param range: An object that represents the range of values to match on.
            :param regex: The value sent by the client must include the specified characters.
            :param suffix: The value sent by the client must end with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheadermatch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_header_match_property = appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                    exact="exact",
                    prefix="prefix",
                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                        end=123,
                        start=123
                    ),
                    regex="regex",
                    suffix="suffix"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
                check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
                check_type(argname="argument range", value=range, expected_type=type_hints["range"])
                check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
                check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact
            if prefix is not None:
                self._values["prefix"] = prefix
            if range is not None:
                self._values["range"] = range
            if regex is not None:
                self._values["regex"] = regex
            if suffix is not None:
                self._values["suffix"] = suffix

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must match the specified value exactly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheadermatch.html#cfn-appmesh-gatewayroute-httpgatewayrouteheadermatch-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def prefix(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must begin with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheadermatch.html#cfn-appmesh-gatewayroute-httpgatewayrouteheadermatch-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def range(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteRangeMatchProperty"]]:
            '''An object that represents the range of values to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheadermatch.html#cfn-appmesh-gatewayroute-httpgatewayrouteheadermatch-range
            '''
            result = self._values.get("range")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteRangeMatchProperty"]], result)

        @builtins.property
        def regex(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must include the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheadermatch.html#cfn-appmesh-gatewayroute-httpgatewayrouteheadermatch-regex
            '''
            result = self._values.get("regex")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def suffix(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must end with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheadermatch.html#cfn-appmesh-gatewayroute-httpgatewayrouteheadermatch-suffix
            '''
            result = self._values.get("suffix")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRouteHeaderMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty",
        jsii_struct_bases=[],
        name_mapping={"name": "name", "invert": "invert", "match": "match"},
    )
    class HttpGatewayRouteHeaderProperty:
        def __init__(
            self,
            *,
            name: builtins.str,
            invert: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            match: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the HTTP header in the gateway route.

            :param name: A name for the HTTP header in the gateway route that will be matched on.
            :param invert: Specify ``True`` to match anything except the match criteria. The default value is ``False`` .
            :param match: An object that represents the method and value to match with the header value sent in a request. Specify one match method.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheader.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_header_property = appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                    name="name",
                
                    # the properties below are optional
                    invert=False,
                    match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                        exact="exact",
                        prefix="prefix",
                        range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                            end=123,
                            start=123
                        ),
                        regex="regex",
                        suffix="suffix"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRouteHeaderProperty.__init__)
                check_type(argname="argument name", value=name, expected_type=type_hints["name"])
                check_type(argname="argument invert", value=invert, expected_type=type_hints["invert"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "name": name,
            }
            if invert is not None:
                self._values["invert"] = invert
            if match is not None:
                self._values["match"] = match

        @builtins.property
        def name(self) -> builtins.str:
            '''A name for the HTTP header in the gateway route that will be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheader.html#cfn-appmesh-gatewayroute-httpgatewayrouteheader-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def invert(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''Specify ``True`` to match anything except the match criteria.

            The default value is ``False`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheader.html#cfn-appmesh-gatewayroute-httpgatewayrouteheader-invert
            '''
            result = self._values.get("invert")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty"]]:
            '''An object that represents the method and value to match with the header value sent in a request.

            Specify one match method.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteheader.html#cfn-appmesh-gatewayroute-httpgatewayrouteheader-match
            '''
            result = self._values.get("match")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRouteHeaderProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty",
        jsii_struct_bases=[],
        name_mapping={
            "headers": "headers",
            "hostname": "hostname",
            "method": "method",
            "path": "path",
            "port": "port",
            "prefix": "prefix",
            "query_parameters": "queryParameters",
        },
    )
    class HttpGatewayRouteMatchProperty:
        def __init__(
            self,
            *,
            headers: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRouteHeaderProperty", typing.Dict[str, typing.Any]]]]]] = None,
            hostname: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteHostnameMatchProperty", typing.Dict[str, typing.Any]]]] = None,
            method: typing.Optional[builtins.str] = None,
            path: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpPathMatchProperty", typing.Dict[str, typing.Any]]]] = None,
            port: typing.Optional[jsii.Number] = None,
            prefix: typing.Optional[builtins.str] = None,
            query_parameters: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.QueryParameterProperty", typing.Dict[str, typing.Any]]]]]] = None,
        ) -> None:
            '''An object that represents the criteria for determining a request match.

            :param headers: The client request headers to match on.
            :param hostname: The host name to match on.
            :param method: The method to match on.
            :param path: The path to match on.
            :param port: ``CfnGatewayRoute.HttpGatewayRouteMatchProperty.Port``.
            :param prefix: Specifies the path to match requests with. This parameter must always start with ``/`` , which by itself matches all requests to the virtual service name. You can also match 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`` .
            :param query_parameters: The query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_match_property = appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                    headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                        name="name",
                
                        # the properties below are optional
                        invert=False,
                        match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                            exact="exact",
                            prefix="prefix",
                            range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                end=123,
                                start=123
                            ),
                            regex="regex",
                            suffix="suffix"
                        )
                    )],
                    hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                        exact="exact",
                        suffix="suffix"
                    ),
                    method="method",
                    path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                        exact="exact",
                        regex="regex"
                    ),
                    port=123,
                    prefix="prefix",
                    query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                        name="name",
                
                        # the properties below are optional
                        match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                            exact="exact"
                        )
                    )]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRouteMatchProperty.__init__)
                check_type(argname="argument headers", value=headers, expected_type=type_hints["headers"])
                check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
                check_type(argname="argument method", value=method, expected_type=type_hints["method"])
                check_type(argname="argument path", value=path, expected_type=type_hints["path"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
                check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
                check_type(argname="argument query_parameters", value=query_parameters, expected_type=type_hints["query_parameters"])
            self._values: typing.Dict[str, typing.Any] = {}
            if headers is not None:
                self._values["headers"] = headers
            if hostname is not None:
                self._values["hostname"] = hostname
            if method is not None:
                self._values["method"] = method
            if path is not None:
                self._values["path"] = path
            if port is not None:
                self._values["port"] = port
            if prefix is not None:
                self._values["prefix"] = prefix
            if query_parameters is not None:
                self._values["query_parameters"] = query_parameters

        @builtins.property
        def headers(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteHeaderProperty"]]]]:
            '''The client request headers to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html#cfn-appmesh-gatewayroute-httpgatewayroutematch-headers
            '''
            result = self._values.get("headers")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteHeaderProperty"]]]], result)

        @builtins.property
        def hostname(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameMatchProperty"]]:
            '''The host name to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html#cfn-appmesh-gatewayroute-httpgatewayroutematch-hostname
            '''
            result = self._values.get("hostname")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameMatchProperty"]], result)

        @builtins.property
        def method(self) -> typing.Optional[builtins.str]:
            '''The method to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html#cfn-appmesh-gatewayroute-httpgatewayroutematch-method
            '''
            result = self._values.get("method")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def path(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpPathMatchProperty"]]:
            '''The path to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html#cfn-appmesh-gatewayroute-httpgatewayroutematch-path
            '''
            result = self._values.get("path")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpPathMatchProperty"]], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnGatewayRoute.HttpGatewayRouteMatchProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html#cfn-appmesh-gatewayroute-httpgatewayroutematch-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def prefix(self) -> typing.Optional[builtins.str]:
            '''Specifies the path to match requests with.

            This parameter must always start with ``/`` , which by itself matches all requests to the virtual service name. You can also match 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`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html#cfn-appmesh-gatewayroute-httpgatewayroutematch-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def query_parameters(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.QueryParameterProperty"]]]]:
            '''The query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutematch.html#cfn-appmesh-gatewayroute-httpgatewayroutematch-queryparameters
            '''
            result = self._values.get("query_parameters")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.QueryParameterProperty"]]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRouteMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact"},
    )
    class HttpGatewayRoutePathRewriteProperty:
        def __init__(self, *, exact: typing.Optional[builtins.str] = None) -> None:
            '''An object that represents the path to rewrite.

            :param exact: The exact path to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutepathrewrite.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_path_rewrite_property = appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                    exact="exact"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The exact path to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroutepathrewrite.html#cfn-appmesh-gatewayroute-httpgatewayroutepathrewrite-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRoutePathRewriteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty",
        jsii_struct_bases=[],
        name_mapping={"default_prefix": "defaultPrefix", "value": "value"},
    )
    class HttpGatewayRoutePrefixRewriteProperty:
        def __init__(
            self,
            *,
            default_prefix: typing.Optional[builtins.str] = None,
            value: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object representing the beginning characters of the route to rewrite.

            :param default_prefix: The default prefix used to replace the incoming route prefix when rewritten.
            :param value: The value used to replace the incoming route prefix when rewritten.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteprefixrewrite.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_prefix_rewrite_property = appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                    default_prefix="defaultPrefix",
                    value="value"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty.__init__)
                check_type(argname="argument default_prefix", value=default_prefix, expected_type=type_hints["default_prefix"])
                check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            self._values: typing.Dict[str, typing.Any] = {}
            if default_prefix is not None:
                self._values["default_prefix"] = default_prefix
            if value is not None:
                self._values["value"] = value

        @builtins.property
        def default_prefix(self) -> typing.Optional[builtins.str]:
            '''The default prefix used to replace the incoming route prefix when rewritten.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteprefixrewrite.html#cfn-appmesh-gatewayroute-httpgatewayrouteprefixrewrite-defaultprefix
            '''
            result = self._values.get("default_prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def value(self) -> typing.Optional[builtins.str]:
            '''The value used to replace the incoming route prefix when rewritten.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouteprefixrewrite.html#cfn-appmesh-gatewayroute-httpgatewayrouteprefixrewrite-value
            '''
            result = self._values.get("value")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRoutePrefixRewriteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRouteProperty",
        jsii_struct_bases=[],
        name_mapping={"action": "action", "match": "match"},
    )
    class HttpGatewayRouteProperty:
        def __init__(
            self,
            *,
            action: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRouteActionProperty", typing.Dict[str, typing.Any]]],
            match: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRouteMatchProperty", typing.Dict[str, typing.Any]]],
        ) -> None:
            '''An object that represents an HTTP gateway route.

            :param action: An object that represents the action to take if a match is determined.
            :param match: An object that represents the criteria for determining a request match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroute.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_property = appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
                
                            # the properties below are optional
                            port=123
                        ),
                
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            ),
                            path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                exact="exact"
                            ),
                            prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                default_prefix="defaultPrefix",
                                value="value"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                        headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                            name="name",
                
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        method="method",
                        path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                            name="name",
                
                            # the properties below are optional
                            match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )]
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRouteProperty.__init__)
                check_type(argname="argument action", value=action, expected_type=type_hints["action"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "action": action,
                "match": match,
            }

        @builtins.property
        def action(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteActionProperty"]:
            '''An object that represents the action to take if a match is determined.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroute.html#cfn-appmesh-gatewayroute-httpgatewayroute-action
            '''
            result = self._values.get("action")
            assert result is not None, "Required property 'action' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteActionProperty"], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteMatchProperty"]:
            '''An object that represents the criteria for determining a request match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayroute.html#cfn-appmesh-gatewayroute-httpgatewayroute-match
            '''
            result = self._values.get("match")
            assert result is not None, "Required property 'match' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRouteMatchProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRouteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty",
        jsii_struct_bases=[],
        name_mapping={"hostname": "hostname", "path": "path", "prefix": "prefix"},
    )
    class HttpGatewayRouteRewriteProperty:
        def __init__(
            self,
            *,
            hostname: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.GatewayRouteHostnameRewriteProperty", typing.Dict[str, typing.Any]]]] = None,
            path: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty", typing.Dict[str, typing.Any]]]] = None,
            prefix: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object representing the gateway route to rewrite.

            :param hostname: The host name to rewrite.
            :param path: The path to rewrite.
            :param prefix: The specified beginning characters to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouterewrite.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_gateway_route_rewrite_property = appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                    hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                        default_target_hostname="defaultTargetHostname"
                    ),
                    path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                        exact="exact"
                    ),
                    prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                        default_prefix="defaultPrefix",
                        value="value"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpGatewayRouteRewriteProperty.__init__)
                check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
                check_type(argname="argument path", value=path, expected_type=type_hints["path"])
                check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
            self._values: typing.Dict[str, typing.Any] = {}
            if hostname is not None:
                self._values["hostname"] = hostname
            if path is not None:
                self._values["path"] = path
            if prefix is not None:
                self._values["prefix"] = prefix

        @builtins.property
        def hostname(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameRewriteProperty"]]:
            '''The host name to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouterewrite.html#cfn-appmesh-gatewayroute-httpgatewayrouterewrite-hostname
            '''
            result = self._values.get("hostname")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.GatewayRouteHostnameRewriteProperty"]], result)

        @builtins.property
        def path(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty"]]:
            '''The path to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouterewrite.html#cfn-appmesh-gatewayroute-httpgatewayrouterewrite-path
            '''
            result = self._values.get("path")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty"]], result)

        @builtins.property
        def prefix(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty"]]:
            '''The specified beginning characters to rewrite.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpgatewayrouterewrite.html#cfn-appmesh-gatewayroute-httpgatewayrouterewrite-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpGatewayRouteRewriteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpPathMatchProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact", "regex": "regex"},
    )
    class HttpPathMatchProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[builtins.str] = None,
            regex: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object representing the path to match in the request.

            :param exact: The exact path to match on.
            :param regex: The regex used to match the path.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httppathmatch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_path_match_property = appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                    exact="exact",
                    regex="regex"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpPathMatchProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
                check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact
            if regex is not None:
                self._values["regex"] = regex

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The exact path to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httppathmatch.html#cfn-appmesh-gatewayroute-httppathmatch-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def regex(self) -> typing.Optional[builtins.str]:
            '''The regex used to match the path.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httppathmatch.html#cfn-appmesh-gatewayroute-httppathmatch-regex
            '''
            result = self._values.get("regex")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpPathMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact"},
    )
    class HttpQueryParameterMatchProperty:
        def __init__(self, *, exact: typing.Optional[builtins.str] = None) -> None:
            '''An object representing the query parameter to match.

            :param exact: The exact query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpqueryparametermatch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_query_parameter_match_property = appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                    exact="exact"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.HttpQueryParameterMatchProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The exact query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-httpqueryparametermatch.html#cfn-appmesh-gatewayroute-httpqueryparametermatch-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpQueryParameterMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRoute.QueryParameterProperty",
        jsii_struct_bases=[],
        name_mapping={"name": "name", "match": "match"},
    )
    class QueryParameterProperty:
        def __init__(
            self,
            *,
            name: builtins.str,
            match: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnGatewayRoute.HttpQueryParameterMatchProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the query parameter in the request.

            :param name: A name for the query parameter that will be matched on.
            :param match: The query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-queryparameter.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                query_parameter_property = appmesh.CfnGatewayRoute.QueryParameterProperty(
                    name="name",
                
                    # the properties below are optional
                    match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                        exact="exact"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnGatewayRoute.QueryParameterProperty.__init__)
                check_type(argname="argument name", value=name, expected_type=type_hints["name"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "name": name,
            }
            if match is not None:
                self._values["match"] = match

        @builtins.property
        def name(self) -> builtins.str:
            '''A name for the query parameter that will be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-queryparameter.html#cfn-appmesh-gatewayroute-queryparameter-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def match(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpQueryParameterMatchProperty"]]:
            '''The query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-gatewayroute-queryparameter.html#cfn-appmesh-gatewayroute-queryparameter-match
            '''
            result = self._values.get("match")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnGatewayRoute.HttpQueryParameterMatchProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "QueryParameterProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CfnGatewayRouteProps",
    jsii_struct_bases=[],
    name_mapping={
        "mesh_name": "meshName",
        "spec": "spec",
        "virtual_gateway_name": "virtualGatewayName",
        "gateway_route_name": "gatewayRouteName",
        "mesh_owner": "meshOwner",
        "tags": "tags",
    },
)
class CfnGatewayRouteProps:
    def __init__(
        self,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[typing.Union[CfnGatewayRoute.GatewayRouteSpecProperty, typing.Dict[str, typing.Any]], aws_cdk.core.IResolvable],
        virtual_gateway_name: builtins.str,
        gateway_route_name: typing.Optional[builtins.str] = None,
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Properties for defining a ``CfnGatewayRoute``.

        :param mesh_name: The name of the service mesh that the resource resides in.
        :param spec: The specifications of the gateway route.
        :param virtual_gateway_name: The virtual gateway that the gateway route is associated with.
        :param gateway_route_name: The name of the gateway route.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the gateway route to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html
        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            cfn_gateway_route_props = appmesh.CfnGatewayRouteProps(
                mesh_name="meshName",
                spec=appmesh.CfnGatewayRoute.GatewayRouteSpecProperty(
                    grpc_route=appmesh.CfnGatewayRoute.GrpcGatewayRouteProperty(
                        action=appmesh.CfnGatewayRoute.GrpcGatewayRouteActionProperty(
                            target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                                virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                    virtual_service_name="virtualServiceName"
                                ),
            
                                # the properties below are optional
                                port=123
                            ),
            
                            # the properties below are optional
                            rewrite=appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty(
                                hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                    default_target_hostname="defaultTargetHostname"
                                )
                            )
                        ),
                        match=appmesh.CfnGatewayRoute.GrpcGatewayRouteMatchProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                                exact="exact",
                                suffix="suffix"
                            ),
                            metadata=[appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty(
                                name="name",
            
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            port=123,
                            service_name="serviceName"
                        )
                    ),
                    http2_route=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                        action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                            target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                                virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                    virtual_service_name="virtualServiceName"
                                ),
            
                                # the properties below are optional
                                port=123
                            ),
            
                            # the properties below are optional
                            rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                                hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                    default_target_hostname="defaultTargetHostname"
                                ),
                                path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                    exact="exact"
                                ),
                                prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                    default_prefix="defaultPrefix",
                                    value="value"
                                )
                            )
                        ),
                        match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                            headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                                name="name",
            
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                                exact="exact",
                                suffix="suffix"
                            ),
                            method="method",
                            path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                                name="name",
            
                                # the properties below are optional
                                match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )]
                        )
                    ),
                    http_route=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                        action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                            target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                                virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                    virtual_service_name="virtualServiceName"
                                ),
            
                                # the properties below are optional
                                port=123
                            ),
            
                            # the properties below are optional
                            rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                                hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                    default_target_hostname="defaultTargetHostname"
                                ),
                                path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                    exact="exact"
                                ),
                                prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                    default_prefix="defaultPrefix",
                                    value="value"
                                )
                            )
                        ),
                        match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                            headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                                name="name",
            
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                                exact="exact",
                                suffix="suffix"
                            ),
                            method="method",
                            path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                                name="name",
            
                                # the properties below are optional
                                match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )]
                        )
                    ),
                    priority=123
                ),
                virtual_gateway_name="virtualGatewayName",
            
                # the properties below are optional
                gateway_route_name="gatewayRouteName",
                mesh_owner="meshOwner",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnGatewayRouteProps.__init__)
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument virtual_gateway_name", value=virtual_gateway_name, expected_type=type_hints["virtual_gateway_name"])
            check_type(argname="argument gateway_route_name", value=gateway_route_name, expected_type=type_hints["gateway_route_name"])
            check_type(argname="argument mesh_owner", value=mesh_owner, expected_type=type_hints["mesh_owner"])
            check_type(argname="argument tags", value=tags, expected_type=type_hints["tags"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh_name": mesh_name,
            "spec": spec,
            "virtual_gateway_name": virtual_gateway_name,
        }
        if gateway_route_name is not None:
            self._values["gateway_route_name"] = gateway_route_name
        if mesh_owner is not None:
            self._values["mesh_owner"] = mesh_owner
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the resource resides in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-meshname
        '''
        result = self._values.get("mesh_name")
        assert result is not None, "Required property 'mesh_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def spec(
        self,
    ) -> typing.Union[CfnGatewayRoute.GatewayRouteSpecProperty, aws_cdk.core.IResolvable]:
        '''The specifications of the gateway route.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(typing.Union[CfnGatewayRoute.GatewayRouteSpecProperty, aws_cdk.core.IResolvable], result)

    @builtins.property
    def virtual_gateway_name(self) -> builtins.str:
        '''The virtual gateway that the gateway route is associated with.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-virtualgatewayname
        '''
        result = self._values.get("virtual_gateway_name")
        assert result is not None, "Required property 'virtual_gateway_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def gateway_route_name(self) -> typing.Optional[builtins.str]:
        '''The name of the gateway route.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-gatewayroutename
        '''
        result = self._values.get("gateway_route_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-meshowner
        '''
        result = self._values.get("mesh_owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''Optional metadata that you can apply to the gateway route to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-gatewayroute.html#cfn-appmesh-gatewayroute-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnGatewayRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnMesh(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.CfnMesh",
):
    '''A CloudFormation ``AWS::AppMesh::Mesh``.

    Creates a service mesh.

    A service mesh is a logical boundary for network traffic between services that are represented by resources within the mesh. After you create your service mesh, you can create virtual services, virtual nodes, virtual routers, and routes to distribute traffic between the applications in your mesh.

    For more information about service meshes, see `Service meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/meshes.html>`_ .

    :cloudformationResource: AWS::AppMesh::Mesh
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        cfn_mesh = appmesh.CfnMesh(self, "MyCfnMesh",
            mesh_name="meshName",
            spec=appmesh.CfnMesh.MeshSpecProperty(
                egress_filter=appmesh.CfnMesh.EgressFilterProperty(
                    type="type"
                ),
                service_discovery=appmesh.CfnMesh.MeshServiceDiscoveryProperty(
                    ip_preference="ipPreference"
                )
            ),
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        mesh_name: typing.Optional[builtins.str] = None,
        spec: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnMesh.MeshSpecProperty", typing.Dict[str, typing.Any]]]] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Create a new ``AWS::AppMesh::Mesh``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param mesh_name: The name to use for the service mesh.
        :param spec: The service mesh specification to apply.
        :param tags: Optional metadata that you can apply to the service mesh to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnMesh.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = CfnMeshProps(mesh_name=mesh_name, spec=spec, tags=tags)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnMesh.inspect)
            check_type(argname="argument inspector", value=inspector, expected_type=type_hints["inspector"])
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnMesh._render_properties)
            check_type(argname="argument props", value=props, expected_type=type_hints["props"])
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''The full Amazon Resource Name (ARN) for the mesh.

        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshName")
    def attr_mesh_name(self) -> builtins.str:
        '''The name of the service mesh.

        :cloudformationAttribute: MeshName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshOwner")
    def attr_mesh_owner(self) -> builtins.str:
        '''The IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: MeshOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrResourceOwner")
    def attr_resource_owner(self) -> builtins.str:
        '''The IAM account ID of the resource owner.

        If the account ID is not your own, then it's the ID of the mesh owner or of another account that the mesh is shared with. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: ResourceOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrUid")
    def attr_uid(self) -> builtins.str:
        '''The unique identifier for the mesh.

        :cloudformationAttribute: Uid
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrUid"))

    @builtins.property
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''Optional metadata that you can apply to the service mesh to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html#cfn-appmesh-mesh-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the service mesh.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html#cfn-appmesh-mesh-meshname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "meshName"))

    @mesh_name.setter
    def mesh_name(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnMesh, "mesh_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshName", value)

    @builtins.property
    @jsii.member(jsii_name="spec")
    def spec(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnMesh.MeshSpecProperty"]]:
        '''The service mesh specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html#cfn-appmesh-mesh-spec
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnMesh.MeshSpecProperty"]], jsii.get(self, "spec"))

    @spec.setter
    def spec(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnMesh.MeshSpecProperty"]],
    ) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnMesh, "spec").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "spec", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnMesh.EgressFilterProperty",
        jsii_struct_bases=[],
        name_mapping={"type": "type"},
    )
    class EgressFilterProperty:
        def __init__(self, *, type: builtins.str) -> None:
            '''An object that represents the egress filter rules for a service mesh.

            :param type: The egress filter type. By default, the type is ``DROP_ALL`` , which allows egress only from virtual nodes to other defined resources in the service mesh (and any traffic to ``*.amazonaws.com`` for AWS API calls). You can set the egress filter type to ``ALLOW_ALL`` to allow egress to any endpoint inside or outside of the service mesh.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-egressfilter.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                egress_filter_property = appmesh.CfnMesh.EgressFilterProperty(
                    type="type"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnMesh.EgressFilterProperty.__init__)
                check_type(argname="argument type", value=type, expected_type=type_hints["type"])
            self._values: typing.Dict[str, typing.Any] = {
                "type": type,
            }

        @builtins.property
        def type(self) -> builtins.str:
            '''The egress filter type.

            By default, the type is ``DROP_ALL`` , which allows egress only from virtual nodes to other defined resources in the service mesh (and any traffic to ``*.amazonaws.com`` for AWS API calls). You can set the egress filter type to ``ALLOW_ALL`` to allow egress to any endpoint inside or outside of the service mesh.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-egressfilter.html#cfn-appmesh-mesh-egressfilter-type
            '''
            result = self._values.get("type")
            assert result is not None, "Required property 'type' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EgressFilterProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnMesh.MeshServiceDiscoveryProperty",
        jsii_struct_bases=[],
        name_mapping={"ip_preference": "ipPreference"},
    )
    class MeshServiceDiscoveryProperty:
        def __init__(
            self,
            *,
            ip_preference: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the service discovery information for a service mesh.

            :param ip_preference: The IP version to use to control traffic within the mesh.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-meshservicediscovery.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                mesh_service_discovery_property = appmesh.CfnMesh.MeshServiceDiscoveryProperty(
                    ip_preference="ipPreference"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnMesh.MeshServiceDiscoveryProperty.__init__)
                check_type(argname="argument ip_preference", value=ip_preference, expected_type=type_hints["ip_preference"])
            self._values: typing.Dict[str, typing.Any] = {}
            if ip_preference is not None:
                self._values["ip_preference"] = ip_preference

        @builtins.property
        def ip_preference(self) -> typing.Optional[builtins.str]:
            '''The IP version to use to control traffic within the mesh.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-meshservicediscovery.html#cfn-appmesh-mesh-meshservicediscovery-ippreference
            '''
            result = self._values.get("ip_preference")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "MeshServiceDiscoveryProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnMesh.MeshSpecProperty",
        jsii_struct_bases=[],
        name_mapping={
            "egress_filter": "egressFilter",
            "service_discovery": "serviceDiscovery",
        },
    )
    class MeshSpecProperty:
        def __init__(
            self,
            *,
            egress_filter: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnMesh.EgressFilterProperty", typing.Dict[str, typing.Any]]]] = None,
            service_discovery: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnMesh.MeshServiceDiscoveryProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the specification of a service mesh.

            :param egress_filter: The egress filter rules for the service mesh.
            :param service_discovery: An object that represents the service discovery information for a service mesh.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-meshspec.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                mesh_spec_property = appmesh.CfnMesh.MeshSpecProperty(
                    egress_filter=appmesh.CfnMesh.EgressFilterProperty(
                        type="type"
                    ),
                    service_discovery=appmesh.CfnMesh.MeshServiceDiscoveryProperty(
                        ip_preference="ipPreference"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnMesh.MeshSpecProperty.__init__)
                check_type(argname="argument egress_filter", value=egress_filter, expected_type=type_hints["egress_filter"])
                check_type(argname="argument service_discovery", value=service_discovery, expected_type=type_hints["service_discovery"])
            self._values: typing.Dict[str, typing.Any] = {}
            if egress_filter is not None:
                self._values["egress_filter"] = egress_filter
            if service_discovery is not None:
                self._values["service_discovery"] = service_discovery

        @builtins.property
        def egress_filter(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnMesh.EgressFilterProperty"]]:
            '''The egress filter rules for the service mesh.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-meshspec.html#cfn-appmesh-mesh-meshspec-egressfilter
            '''
            result = self._values.get("egress_filter")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnMesh.EgressFilterProperty"]], result)

        @builtins.property
        def service_discovery(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnMesh.MeshServiceDiscoveryProperty"]]:
            '''An object that represents the service discovery information for a service mesh.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-mesh-meshspec.html#cfn-appmesh-mesh-meshspec-servicediscovery
            '''
            result = self._values.get("service_discovery")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnMesh.MeshServiceDiscoveryProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "MeshSpecProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CfnMeshProps",
    jsii_struct_bases=[],
    name_mapping={"mesh_name": "meshName", "spec": "spec", "tags": "tags"},
)
class CfnMeshProps:
    def __init__(
        self,
        *,
        mesh_name: typing.Optional[builtins.str] = None,
        spec: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union[CfnMesh.MeshSpecProperty, typing.Dict[str, typing.Any]]]] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Properties for defining a ``CfnMesh``.

        :param mesh_name: The name to use for the service mesh.
        :param spec: The service mesh specification to apply.
        :param tags: Optional metadata that you can apply to the service mesh to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html
        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            cfn_mesh_props = appmesh.CfnMeshProps(
                mesh_name="meshName",
                spec=appmesh.CfnMesh.MeshSpecProperty(
                    egress_filter=appmesh.CfnMesh.EgressFilterProperty(
                        type="type"
                    ),
                    service_discovery=appmesh.CfnMesh.MeshServiceDiscoveryProperty(
                        ip_preference="ipPreference"
                    )
                ),
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnMeshProps.__init__)
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument tags", value=tags, expected_type=type_hints["tags"])
        self._values: typing.Dict[str, typing.Any] = {}
        if mesh_name is not None:
            self._values["mesh_name"] = mesh_name
        if spec is not None:
            self._values["spec"] = spec
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def mesh_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the service mesh.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html#cfn-appmesh-mesh-meshname
        '''
        result = self._values.get("mesh_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def spec(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnMesh.MeshSpecProperty]]:
        '''The service mesh specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html#cfn-appmesh-mesh-spec
        '''
        result = self._values.get("spec")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnMesh.MeshSpecProperty]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''Optional metadata that you can apply to the service mesh to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-mesh.html#cfn-appmesh-mesh-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnMeshProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnRoute(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.CfnRoute",
):
    '''A CloudFormation ``AWS::AppMesh::Route``.

    Creates a route that is associated with a virtual router.

    You can route several different protocols and define a retry policy for a route. Traffic can be routed to one or more virtual nodes.

    For more information about routes, see `Routes <https://docs.aws.amazon.com/app-mesh/latest/userguide/routes.html>`_ .

    :cloudformationResource: AWS::AppMesh::Route
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        cfn_route = appmesh.CfnRoute(self, "MyCfnRoute",
            mesh_name="meshName",
            spec=appmesh.CfnRoute.RouteSpecProperty(
                grpc_route=appmesh.CfnRoute.GrpcRouteProperty(
                    action=appmesh.CfnRoute.GrpcRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
        
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.GrpcRouteMatchProperty(
                        metadata=[appmesh.CfnRoute.GrpcRouteMetadataProperty(
                            name="name",
        
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method_name="methodName",
                        port=123,
                        service_name="serviceName"
                    ),
        
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.GrpcRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
        
                        # the properties below are optional
                        grpc_retry_events=["grpcRetryEvents"],
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.GrpcTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                ),
                http2_route=appmesh.CfnRoute.HttpRouteProperty(
                    action=appmesh.CfnRoute.HttpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
        
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.HttpRouteMatchProperty(
                        headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                            name="name",
        
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method="method",
                        path=appmesh.CfnRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                            name="name",
        
                            # the properties below are optional
                            match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )],
                        scheme="scheme"
                    ),
        
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
        
                        # the properties below are optional
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                ),
                http_route=appmesh.CfnRoute.HttpRouteProperty(
                    action=appmesh.CfnRoute.HttpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
        
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.HttpRouteMatchProperty(
                        headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                            name="name",
        
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method="method",
                        path=appmesh.CfnRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                            name="name",
        
                            # the properties below are optional
                            match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )],
                        scheme="scheme"
                    ),
        
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
        
                        # the properties below are optional
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                ),
                priority=123,
                tcp_route=appmesh.CfnRoute.TcpRouteProperty(
                    action=appmesh.CfnRoute.TcpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
        
                            # the properties below are optional
                            port=123
                        )]
                    ),
        
                    # the properties below are optional
                    match=appmesh.CfnRoute.TcpRouteMatchProperty(
                        port=123
                    ),
                    timeout=appmesh.CfnRoute.TcpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                )
            ),
            virtual_router_name="virtualRouterName",
        
            # the properties below are optional
            mesh_owner="meshOwner",
            route_name="routeName",
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.RouteSpecProperty", typing.Dict[str, typing.Any]]],
        virtual_router_name: builtins.str,
        mesh_owner: typing.Optional[builtins.str] = None,
        route_name: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Create a new ``AWS::AppMesh::Route``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param mesh_name: The name of the service mesh to create the route in.
        :param spec: The route specification to apply.
        :param virtual_router_name: The name of the virtual router in which to create the route. If the virtual router is in a shared mesh, then you must be the owner of the virtual router resource.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param route_name: The name to use for the route.
        :param tags: Optional metadata that you can apply to the route to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnRoute.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = CfnRouteProps(
            mesh_name=mesh_name,
            spec=spec,
            virtual_router_name=virtual_router_name,
            mesh_owner=mesh_owner,
            route_name=route_name,
            tags=tags,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnRoute.inspect)
            check_type(argname="argument inspector", value=inspector, expected_type=type_hints["inspector"])
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnRoute._render_properties)
            check_type(argname="argument props", value=props, expected_type=type_hints["props"])
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''The full Amazon Resource Name (ARN) for the route.

        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshName")
    def attr_mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the route resides in.

        :cloudformationAttribute: MeshName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshOwner")
    def attr_mesh_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: MeshOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrResourceOwner")
    def attr_resource_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the resource owner.

        If the account ID is not your own, then it's the ID of the mesh owner or of another account that the mesh is shared with. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: ResourceOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrRouteName")
    def attr_route_name(self) -> builtins.str:
        '''The name of the route.

        :cloudformationAttribute: RouteName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrRouteName"))

    @builtins.property
    @jsii.member(jsii_name="attrUid")
    def attr_uid(self) -> builtins.str:
        '''The unique identifier for the route.

        :cloudformationAttribute: Uid
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrUid"))

    @builtins.property
    @jsii.member(jsii_name="attrVirtualRouterName")
    def attr_virtual_router_name(self) -> builtins.str:
        '''The name of the virtual router that the route is associated with.

        :cloudformationAttribute: VirtualRouterName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVirtualRouterName"))

    @builtins.property
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''Optional metadata that you can apply to the route to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the route in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-meshname
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))

    @mesh_name.setter
    def mesh_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnRoute, "mesh_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshName", value)

    @builtins.property
    @jsii.member(jsii_name="spec")
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.RouteSpecProperty"]:
        '''The route specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-spec
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.RouteSpecProperty"], jsii.get(self, "spec"))

    @spec.setter
    def spec(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnRoute.RouteSpecProperty"],
    ) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnRoute, "spec").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "spec", value)

    @builtins.property
    @jsii.member(jsii_name="virtualRouterName")
    def virtual_router_name(self) -> builtins.str:
        '''The name of the virtual router in which to create the route.

        If the virtual router is in a shared mesh, then you must be the owner of the virtual router resource.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-virtualroutername
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualRouterName"))

    @virtual_router_name.setter
    def virtual_router_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnRoute, "virtual_router_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "virtualRouterName", value)

    @builtins.property
    @jsii.member(jsii_name="meshOwner")
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-meshowner
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "meshOwner"))

    @mesh_owner.setter
    def mesh_owner(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnRoute, "mesh_owner").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshOwner", value)

    @builtins.property
    @jsii.member(jsii_name="routeName")
    def route_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the route.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-routename
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "routeName"))

    @route_name.setter
    def route_name(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnRoute, "route_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "routeName", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.DurationProperty",
        jsii_struct_bases=[],
        name_mapping={"unit": "unit", "value": "value"},
    )
    class DurationProperty:
        def __init__(self, *, unit: builtins.str, value: jsii.Number) -> None:
            '''An object that represents a duration of time.

            :param unit: A unit of time.
            :param value: A number of time units.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-duration.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                duration_property = appmesh.CfnRoute.DurationProperty(
                    unit="unit",
                    value=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.DurationProperty.__init__)
                check_type(argname="argument unit", value=unit, expected_type=type_hints["unit"])
                check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            self._values: typing.Dict[str, typing.Any] = {
                "unit": unit,
                "value": value,
            }

        @builtins.property
        def unit(self) -> builtins.str:
            '''A unit of time.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-duration.html#cfn-appmesh-route-duration-unit
            '''
            result = self._values.get("unit")
            assert result is not None, "Required property 'unit' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def value(self) -> jsii.Number:
            '''A number of time units.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-duration.html#cfn-appmesh-route-duration-value
            '''
            result = self._values.get("value")
            assert result is not None, "Required property 'value' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "DurationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.GrpcRetryPolicyProperty",
        jsii_struct_bases=[],
        name_mapping={
            "max_retries": "maxRetries",
            "per_retry_timeout": "perRetryTimeout",
            "grpc_retry_events": "grpcRetryEvents",
            "http_retry_events": "httpRetryEvents",
            "tcp_retry_events": "tcpRetryEvents",
        },
    )
    class GrpcRetryPolicyProperty:
        def __init__(
            self,
            *,
            max_retries: jsii.Number,
            per_retry_timeout: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.DurationProperty", typing.Dict[str, typing.Any]]],
            grpc_retry_events: typing.Optional[typing.Sequence[builtins.str]] = None,
            http_retry_events: typing.Optional[typing.Sequence[builtins.str]] = None,
            tcp_retry_events: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''An object that represents a retry policy.

            Specify at least one value for at least one of the types of ``RetryEvents`` , a value for ``maxRetries`` , and a value for ``perRetryTimeout`` . Both ``server-error`` and ``gateway-error`` under ``httpRetryEvents`` include the Envoy ``reset`` policy. For more information on the ``reset`` policy, see the `Envoy documentation <https://docs.aws.amazon.com/https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-retry-on>`_ .

            :param max_retries: The maximum number of retry attempts.
            :param per_retry_timeout: The timeout for each retry attempt.
            :param grpc_retry_events: Specify at least one of the valid values.
            :param http_retry_events: Specify at least one of the following values. - *server-error* – HTTP status codes 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, and 511 - *gateway-error* – HTTP status codes 502, 503, and 504 - *client-error* – HTTP status code 409 - *stream-error* – Retry on refused stream
            :param tcp_retry_events: Specify a valid value. The event occurs before any processing of a request has started and is encountered when the upstream is temporarily or permanently unavailable.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcretrypolicy.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_retry_policy_property = appmesh.CfnRoute.GrpcRetryPolicyProperty(
                    max_retries=123,
                    per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                
                    # the properties below are optional
                    grpc_retry_events=["grpcRetryEvents"],
                    http_retry_events=["httpRetryEvents"],
                    tcp_retry_events=["tcpRetryEvents"]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.GrpcRetryPolicyProperty.__init__)
                check_type(argname="argument max_retries", value=max_retries, expected_type=type_hints["max_retries"])
                check_type(argname="argument per_retry_timeout", value=per_retry_timeout, expected_type=type_hints["per_retry_timeout"])
                check_type(argname="argument grpc_retry_events", value=grpc_retry_events, expected_type=type_hints["grpc_retry_events"])
                check_type(argname="argument http_retry_events", value=http_retry_events, expected_type=type_hints["http_retry_events"])
                check_type(argname="argument tcp_retry_events", value=tcp_retry_events, expected_type=type_hints["tcp_retry_events"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_retries": max_retries,
                "per_retry_timeout": per_retry_timeout,
            }
            if grpc_retry_events is not None:
                self._values["grpc_retry_events"] = grpc_retry_events
            if http_retry_events is not None:
                self._values["http_retry_events"] = http_retry_events
            if tcp_retry_events is not None:
                self._values["tcp_retry_events"] = tcp_retry_events

        @builtins.property
        def max_retries(self) -> jsii.Number:
            '''The maximum number of retry attempts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcretrypolicy.html#cfn-appmesh-route-grpcretrypolicy-maxretries
            '''
            result = self._values.get("max_retries")
            assert result is not None, "Required property 'max_retries' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def per_retry_timeout(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]:
            '''The timeout for each retry attempt.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcretrypolicy.html#cfn-appmesh-route-grpcretrypolicy-perretrytimeout
            '''
            result = self._values.get("per_retry_timeout")
            assert result is not None, "Required property 'per_retry_timeout' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"], result)

        @builtins.property
        def grpc_retry_events(self) -> typing.Optional[typing.List[builtins.str]]:
            '''Specify at least one of the valid values.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcretrypolicy.html#cfn-appmesh-route-grpcretrypolicy-grpcretryevents
            '''
            result = self._values.get("grpc_retry_events")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def http_retry_events(self) -> typing.Optional[typing.List[builtins.str]]:
            '''Specify at least one of the following values.

            - *server-error* – HTTP status codes 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, and 511
            - *gateway-error* – HTTP status codes 502, 503, and 504
            - *client-error* – HTTP status code 409
            - *stream-error* – Retry on refused stream

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcretrypolicy.html#cfn-appmesh-route-grpcretrypolicy-httpretryevents
            '''
            result = self._values.get("http_retry_events")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def tcp_retry_events(self) -> typing.Optional[typing.List[builtins.str]]:
            '''Specify a valid value.

            The event occurs before any processing of a request has started and is encountered when the upstream is temporarily or permanently unavailable.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcretrypolicy.html#cfn-appmesh-route-grpcretrypolicy-tcpretryevents
            '''
            result = self._values.get("tcp_retry_events")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcRetryPolicyProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.GrpcRouteActionProperty",
        jsii_struct_bases=[],
        name_mapping={"weighted_targets": "weightedTargets"},
    )
    class GrpcRouteActionProperty:
        def __init__(
            self,
            *,
            weighted_targets: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.WeightedTargetProperty", typing.Dict[str, typing.Any]]]]],
        ) -> None:
            '''An object that represents the action to take if a match is determined.

            :param weighted_targets: An object that represents the targets that traffic is routed to when a request matches the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcrouteaction.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_route_action_property = appmesh.CfnRoute.GrpcRouteActionProperty(
                    weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                        virtual_node="virtualNode",
                        weight=123,
                
                        # the properties below are optional
                        port=123
                    )]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.GrpcRouteActionProperty.__init__)
                check_type(argname="argument weighted_targets", value=weighted_targets, expected_type=type_hints["weighted_targets"])
            self._values: typing.Dict[str, typing.Any] = {
                "weighted_targets": weighted_targets,
            }

        @builtins.property
        def weighted_targets(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.WeightedTargetProperty"]]]:
            '''An object that represents the targets that traffic is routed to when a request matches the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcrouteaction.html#cfn-appmesh-route-grpcrouteaction-weightedtargets
            '''
            result = self._values.get("weighted_targets")
            assert result is not None, "Required property 'weighted_targets' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.WeightedTargetProperty"]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcRouteActionProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.GrpcRouteMatchProperty",
        jsii_struct_bases=[],
        name_mapping={
            "metadata": "metadata",
            "method_name": "methodName",
            "port": "port",
            "service_name": "serviceName",
        },
    )
    class GrpcRouteMatchProperty:
        def __init__(
            self,
            *,
            metadata: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.GrpcRouteMetadataProperty", typing.Dict[str, typing.Any]]]]]] = None,
            method_name: typing.Optional[builtins.str] = None,
            port: typing.Optional[jsii.Number] = None,
            service_name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the criteria for determining a request match.

            :param metadata: An object that represents the data to match from the request.
            :param method_name: The method name to match from the request. If you specify a name, you must also specify a ``serviceName`` .
            :param port: ``CfnRoute.GrpcRouteMatchProperty.Port``.
            :param service_name: The fully qualified domain name for the service to match from the request.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutematch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_route_match_property = appmesh.CfnRoute.GrpcRouteMatchProperty(
                    metadata=[appmesh.CfnRoute.GrpcRouteMetadataProperty(
                        name="name",
                
                        # the properties below are optional
                        invert=False,
                        match=appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                            exact="exact",
                            prefix="prefix",
                            range=appmesh.CfnRoute.MatchRangeProperty(
                                end=123,
                                start=123
                            ),
                            regex="regex",
                            suffix="suffix"
                        )
                    )],
                    method_name="methodName",
                    port=123,
                    service_name="serviceName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.GrpcRouteMatchProperty.__init__)
                check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
                check_type(argname="argument method_name", value=method_name, expected_type=type_hints["method_name"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
                check_type(argname="argument service_name", value=service_name, expected_type=type_hints["service_name"])
            self._values: typing.Dict[str, typing.Any] = {}
            if metadata is not None:
                self._values["metadata"] = metadata
            if method_name is not None:
                self._values["method_name"] = method_name
            if port is not None:
                self._values["port"] = port
            if service_name is not None:
                self._values["service_name"] = service_name

        @builtins.property
        def metadata(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteMetadataProperty"]]]]:
            '''An object that represents the data to match from the request.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutematch.html#cfn-appmesh-route-grpcroutematch-metadata
            '''
            result = self._values.get("metadata")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteMetadataProperty"]]]], result)

        @builtins.property
        def method_name(self) -> typing.Optional[builtins.str]:
            '''The method name to match from the request.

            If you specify a name, you must also specify a ``serviceName`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutematch.html#cfn-appmesh-route-grpcroutematch-methodname
            '''
            result = self._values.get("method_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnRoute.GrpcRouteMatchProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutematch.html#cfn-appmesh-route-grpcroutematch-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def service_name(self) -> typing.Optional[builtins.str]:
            '''The fully qualified domain name for the service to match from the request.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutematch.html#cfn-appmesh-route-grpcroutematch-servicename
            '''
            result = self._values.get("service_name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcRouteMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty",
        jsii_struct_bases=[],
        name_mapping={
            "exact": "exact",
            "prefix": "prefix",
            "range": "range",
            "regex": "regex",
            "suffix": "suffix",
        },
    )
    class GrpcRouteMetadataMatchMethodProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[builtins.str] = None,
            prefix: typing.Optional[builtins.str] = None,
            range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.MatchRangeProperty", typing.Dict[str, typing.Any]]]] = None,
            regex: typing.Optional[builtins.str] = None,
            suffix: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the match method.

            Specify one of the match values.

            :param exact: The value sent by the client must match the specified value exactly.
            :param prefix: The value sent by the client must begin with the specified characters.
            :param range: An object that represents the range of values to match on.
            :param regex: The value sent by the client must include the specified characters.
            :param suffix: The value sent by the client must end with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadatamatchmethod.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_route_metadata_match_method_property = appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                    exact="exact",
                    prefix="prefix",
                    range=appmesh.CfnRoute.MatchRangeProperty(
                        end=123,
                        start=123
                    ),
                    regex="regex",
                    suffix="suffix"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.GrpcRouteMetadataMatchMethodProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
                check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
                check_type(argname="argument range", value=range, expected_type=type_hints["range"])
                check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
                check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact
            if prefix is not None:
                self._values["prefix"] = prefix
            if range is not None:
                self._values["range"] = range
            if regex is not None:
                self._values["regex"] = regex
            if suffix is not None:
                self._values["suffix"] = suffix

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must match the specified value exactly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadatamatchmethod.html#cfn-appmesh-route-grpcroutemetadatamatchmethod-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def prefix(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must begin with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadatamatchmethod.html#cfn-appmesh-route-grpcroutemetadatamatchmethod-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def range(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.MatchRangeProperty"]]:
            '''An object that represents the range of values to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadatamatchmethod.html#cfn-appmesh-route-grpcroutemetadatamatchmethod-range
            '''
            result = self._values.get("range")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.MatchRangeProperty"]], result)

        @builtins.property
        def regex(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must include the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadatamatchmethod.html#cfn-appmesh-route-grpcroutemetadatamatchmethod-regex
            '''
            result = self._values.get("regex")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def suffix(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must end with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadatamatchmethod.html#cfn-appmesh-route-grpcroutemetadatamatchmethod-suffix
            '''
            result = self._values.get("suffix")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcRouteMetadataMatchMethodProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.GrpcRouteMetadataProperty",
        jsii_struct_bases=[],
        name_mapping={"name": "name", "invert": "invert", "match": "match"},
    )
    class GrpcRouteMetadataProperty:
        def __init__(
            self,
            *,
            name: builtins.str,
            invert: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            match: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.GrpcRouteMetadataMatchMethodProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the match metadata for the route.

            :param name: The name of the route.
            :param invert: Specify ``True`` to match anything except the match criteria. The default value is ``False`` .
            :param match: An object that represents the data to match from the request.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadata.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_route_metadata_property = appmesh.CfnRoute.GrpcRouteMetadataProperty(
                    name="name",
                
                    # the properties below are optional
                    invert=False,
                    match=appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                        exact="exact",
                        prefix="prefix",
                        range=appmesh.CfnRoute.MatchRangeProperty(
                            end=123,
                            start=123
                        ),
                        regex="regex",
                        suffix="suffix"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.GrpcRouteMetadataProperty.__init__)
                check_type(argname="argument name", value=name, expected_type=type_hints["name"])
                check_type(argname="argument invert", value=invert, expected_type=type_hints["invert"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "name": name,
            }
            if invert is not None:
                self._values["invert"] = invert
            if match is not None:
                self._values["match"] = match

        @builtins.property
        def name(self) -> builtins.str:
            '''The name of the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadata.html#cfn-appmesh-route-grpcroutemetadata-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def invert(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''Specify ``True`` to match anything except the match criteria.

            The default value is ``False`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadata.html#cfn-appmesh-route-grpcroutemetadata-invert
            '''
            result = self._values.get("invert")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteMetadataMatchMethodProperty"]]:
            '''An object that represents the data to match from the request.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroutemetadata.html#cfn-appmesh-route-grpcroutemetadata-match
            '''
            result = self._values.get("match")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteMetadataMatchMethodProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcRouteMetadataProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.GrpcRouteProperty",
        jsii_struct_bases=[],
        name_mapping={
            "action": "action",
            "match": "match",
            "retry_policy": "retryPolicy",
            "timeout": "timeout",
        },
    )
    class GrpcRouteProperty:
        def __init__(
            self,
            *,
            action: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.GrpcRouteActionProperty", typing.Dict[str, typing.Any]]],
            match: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.GrpcRouteMatchProperty", typing.Dict[str, typing.Any]]],
            retry_policy: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.GrpcRetryPolicyProperty", typing.Dict[str, typing.Any]]]] = None,
            timeout: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.GrpcTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a gRPC route type.

            :param action: An object that represents the action to take if a match is determined.
            :param match: An object that represents the criteria for determining a request match.
            :param retry_policy: An object that represents a retry policy.
            :param timeout: An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroute.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_route_property = appmesh.CfnRoute.GrpcRouteProperty(
                    action=appmesh.CfnRoute.GrpcRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
                
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.GrpcRouteMatchProperty(
                        metadata=[appmesh.CfnRoute.GrpcRouteMetadataProperty(
                            name="name",
                
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method_name="methodName",
                        port=123,
                        service_name="serviceName"
                    ),
                
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.GrpcRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                
                        # the properties below are optional
                        grpc_retry_events=["grpcRetryEvents"],
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.GrpcTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.GrpcRouteProperty.__init__)
                check_type(argname="argument action", value=action, expected_type=type_hints["action"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
                check_type(argname="argument retry_policy", value=retry_policy, expected_type=type_hints["retry_policy"])
                check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            self._values: typing.Dict[str, typing.Any] = {
                "action": action,
                "match": match,
            }
            if retry_policy is not None:
                self._values["retry_policy"] = retry_policy
            if timeout is not None:
                self._values["timeout"] = timeout

        @builtins.property
        def action(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteActionProperty"]:
            '''An object that represents the action to take if a match is determined.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroute.html#cfn-appmesh-route-grpcroute-action
            '''
            result = self._values.get("action")
            assert result is not None, "Required property 'action' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteActionProperty"], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteMatchProperty"]:
            '''An object that represents the criteria for determining a request match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroute.html#cfn-appmesh-route-grpcroute-match
            '''
            result = self._values.get("match")
            assert result is not None, "Required property 'match' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteMatchProperty"], result)

        @builtins.property
        def retry_policy(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRetryPolicyProperty"]]:
            '''An object that represents a retry policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroute.html#cfn-appmesh-route-grpcroute-retrypolicy
            '''
            result = self._values.get("retry_policy")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRetryPolicyProperty"]], result)

        @builtins.property
        def timeout(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcTimeoutProperty"]]:
            '''An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroute.html#cfn-appmesh-route-grpcroute-timeout
            '''
            result = self._values.get("timeout")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcTimeoutProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcRouteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.GrpcTimeoutProperty",
        jsii_struct_bases=[],
        name_mapping={"idle": "idle", "per_request": "perRequest"},
    )
    class GrpcTimeoutProperty:
        def __init__(
            self,
            *,
            idle: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
            per_request: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents types of timeouts.

            :param idle: An object that represents an idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none.
            :param per_request: An object that represents a per request timeout. The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpctimeout.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_timeout_property = appmesh.CfnRoute.GrpcTimeoutProperty(
                    idle=appmesh.CfnRoute.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                    per_request=appmesh.CfnRoute.DurationProperty(
                        unit="unit",
                        value=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.GrpcTimeoutProperty.__init__)
                check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
                check_type(argname="argument per_request", value=per_request, expected_type=type_hints["per_request"])
            self._values: typing.Dict[str, typing.Any] = {}
            if idle is not None:
                self._values["idle"] = idle
            if per_request is not None:
                self._values["per_request"] = per_request

        @builtins.property
        def idle(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]]:
            '''An object that represents an idle timeout.

            An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpctimeout.html#cfn-appmesh-route-grpctimeout-idle
            '''
            result = self._values.get("idle")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]], result)

        @builtins.property
        def per_request(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]]:
            '''An object that represents a per request timeout.

            The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpctimeout.html#cfn-appmesh-route-grpctimeout-perrequest
            '''
            result = self._values.get("per_request")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcTimeoutProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HeaderMatchMethodProperty",
        jsii_struct_bases=[],
        name_mapping={
            "exact": "exact",
            "prefix": "prefix",
            "range": "range",
            "regex": "regex",
            "suffix": "suffix",
        },
    )
    class HeaderMatchMethodProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[builtins.str] = None,
            prefix: typing.Optional[builtins.str] = None,
            range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.MatchRangeProperty", typing.Dict[str, typing.Any]]]] = None,
            regex: typing.Optional[builtins.str] = None,
            suffix: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the method and value to match with the header value sent in a request.

            Specify one match method.

            :param exact: The value sent by the client must match the specified value exactly.
            :param prefix: The value sent by the client must begin with the specified characters.
            :param range: An object that represents the range of values to match on.
            :param regex: The value sent by the client must include the specified characters.
            :param suffix: The value sent by the client must end with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-headermatchmethod.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                header_match_method_property = appmesh.CfnRoute.HeaderMatchMethodProperty(
                    exact="exact",
                    prefix="prefix",
                    range=appmesh.CfnRoute.MatchRangeProperty(
                        end=123,
                        start=123
                    ),
                    regex="regex",
                    suffix="suffix"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HeaderMatchMethodProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
                check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
                check_type(argname="argument range", value=range, expected_type=type_hints["range"])
                check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
                check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact
            if prefix is not None:
                self._values["prefix"] = prefix
            if range is not None:
                self._values["range"] = range
            if regex is not None:
                self._values["regex"] = regex
            if suffix is not None:
                self._values["suffix"] = suffix

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must match the specified value exactly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-headermatchmethod.html#cfn-appmesh-route-headermatchmethod-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def prefix(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must begin with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-headermatchmethod.html#cfn-appmesh-route-headermatchmethod-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def range(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.MatchRangeProperty"]]:
            '''An object that represents the range of values to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-headermatchmethod.html#cfn-appmesh-route-headermatchmethod-range
            '''
            result = self._values.get("range")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.MatchRangeProperty"]], result)

        @builtins.property
        def regex(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must include the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-headermatchmethod.html#cfn-appmesh-route-headermatchmethod-regex
            '''
            result = self._values.get("regex")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def suffix(self) -> typing.Optional[builtins.str]:
            '''The value sent by the client must end with the specified characters.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-headermatchmethod.html#cfn-appmesh-route-headermatchmethod-suffix
            '''
            result = self._values.get("suffix")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HeaderMatchMethodProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpPathMatchProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact", "regex": "regex"},
    )
    class HttpPathMatchProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[builtins.str] = None,
            regex: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object representing the path to match in the request.

            :param exact: The exact path to match on.
            :param regex: The regex used to match the path.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httppathmatch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_path_match_property = appmesh.CfnRoute.HttpPathMatchProperty(
                    exact="exact",
                    regex="regex"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpPathMatchProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
                check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact
            if regex is not None:
                self._values["regex"] = regex

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The exact path to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httppathmatch.html#cfn-appmesh-route-httppathmatch-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def regex(self) -> typing.Optional[builtins.str]:
            '''The regex used to match the path.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httppathmatch.html#cfn-appmesh-route-httppathmatch-regex
            '''
            result = self._values.get("regex")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpPathMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpQueryParameterMatchProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact"},
    )
    class HttpQueryParameterMatchProperty:
        def __init__(self, *, exact: typing.Optional[builtins.str] = None) -> None:
            '''An object representing the query parameter to match.

            :param exact: The exact query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httpqueryparametermatch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_query_parameter_match_property = appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                    exact="exact"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpQueryParameterMatchProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact

        @builtins.property
        def exact(self) -> typing.Optional[builtins.str]:
            '''The exact query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httpqueryparametermatch.html#cfn-appmesh-route-httpqueryparametermatch-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpQueryParameterMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpRetryPolicyProperty",
        jsii_struct_bases=[],
        name_mapping={
            "max_retries": "maxRetries",
            "per_retry_timeout": "perRetryTimeout",
            "http_retry_events": "httpRetryEvents",
            "tcp_retry_events": "tcpRetryEvents",
        },
    )
    class HttpRetryPolicyProperty:
        def __init__(
            self,
            *,
            max_retries: jsii.Number,
            per_retry_timeout: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.DurationProperty", typing.Dict[str, typing.Any]]],
            http_retry_events: typing.Optional[typing.Sequence[builtins.str]] = None,
            tcp_retry_events: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''An object that represents a retry policy.

            Specify at least one value for at least one of the types of ``RetryEvents`` , a value for ``maxRetries`` , and a value for ``perRetryTimeout`` . Both ``server-error`` and ``gateway-error`` under ``httpRetryEvents`` include the Envoy ``reset`` policy. For more information on the ``reset`` policy, see the `Envoy documentation <https://docs.aws.amazon.com/https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-retry-on>`_ .

            :param max_retries: The maximum number of retry attempts.
            :param per_retry_timeout: The timeout for each retry attempt.
            :param http_retry_events: Specify at least one of the following values. - *server-error* – HTTP status codes 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, and 511 - *gateway-error* – HTTP status codes 502, 503, and 504 - *client-error* – HTTP status code 409 - *stream-error* – Retry on refused stream
            :param tcp_retry_events: Specify a valid value. The event occurs before any processing of a request has started and is encountered when the upstream is temporarily or permanently unavailable.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httpretrypolicy.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_retry_policy_property = appmesh.CfnRoute.HttpRetryPolicyProperty(
                    max_retries=123,
                    per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                
                    # the properties below are optional
                    http_retry_events=["httpRetryEvents"],
                    tcp_retry_events=["tcpRetryEvents"]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpRetryPolicyProperty.__init__)
                check_type(argname="argument max_retries", value=max_retries, expected_type=type_hints["max_retries"])
                check_type(argname="argument per_retry_timeout", value=per_retry_timeout, expected_type=type_hints["per_retry_timeout"])
                check_type(argname="argument http_retry_events", value=http_retry_events, expected_type=type_hints["http_retry_events"])
                check_type(argname="argument tcp_retry_events", value=tcp_retry_events, expected_type=type_hints["tcp_retry_events"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_retries": max_retries,
                "per_retry_timeout": per_retry_timeout,
            }
            if http_retry_events is not None:
                self._values["http_retry_events"] = http_retry_events
            if tcp_retry_events is not None:
                self._values["tcp_retry_events"] = tcp_retry_events

        @builtins.property
        def max_retries(self) -> jsii.Number:
            '''The maximum number of retry attempts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httpretrypolicy.html#cfn-appmesh-route-httpretrypolicy-maxretries
            '''
            result = self._values.get("max_retries")
            assert result is not None, "Required property 'max_retries' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def per_retry_timeout(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]:
            '''The timeout for each retry attempt.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httpretrypolicy.html#cfn-appmesh-route-httpretrypolicy-perretrytimeout
            '''
            result = self._values.get("per_retry_timeout")
            assert result is not None, "Required property 'per_retry_timeout' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"], result)

        @builtins.property
        def http_retry_events(self) -> typing.Optional[typing.List[builtins.str]]:
            '''Specify at least one of the following values.

            - *server-error* – HTTP status codes 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, and 511
            - *gateway-error* – HTTP status codes 502, 503, and 504
            - *client-error* – HTTP status code 409
            - *stream-error* – Retry on refused stream

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httpretrypolicy.html#cfn-appmesh-route-httpretrypolicy-httpretryevents
            '''
            result = self._values.get("http_retry_events")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def tcp_retry_events(self) -> typing.Optional[typing.List[builtins.str]]:
            '''Specify a valid value.

            The event occurs before any processing of a request has started and is encountered when the upstream is temporarily or permanently unavailable.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httpretrypolicy.html#cfn-appmesh-route-httpretrypolicy-tcpretryevents
            '''
            result = self._values.get("tcp_retry_events")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpRetryPolicyProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpRouteActionProperty",
        jsii_struct_bases=[],
        name_mapping={"weighted_targets": "weightedTargets"},
    )
    class HttpRouteActionProperty:
        def __init__(
            self,
            *,
            weighted_targets: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.WeightedTargetProperty", typing.Dict[str, typing.Any]]]]],
        ) -> None:
            '''An object that represents the action to take if a match is determined.

            :param weighted_targets: An object that represents the targets that traffic is routed to when a request matches the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httprouteaction.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_route_action_property = appmesh.CfnRoute.HttpRouteActionProperty(
                    weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                        virtual_node="virtualNode",
                        weight=123,
                
                        # the properties below are optional
                        port=123
                    )]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpRouteActionProperty.__init__)
                check_type(argname="argument weighted_targets", value=weighted_targets, expected_type=type_hints["weighted_targets"])
            self._values: typing.Dict[str, typing.Any] = {
                "weighted_targets": weighted_targets,
            }

        @builtins.property
        def weighted_targets(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.WeightedTargetProperty"]]]:
            '''An object that represents the targets that traffic is routed to when a request matches the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httprouteaction.html#cfn-appmesh-route-httprouteaction-weightedtargets
            '''
            result = self._values.get("weighted_targets")
            assert result is not None, "Required property 'weighted_targets' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.WeightedTargetProperty"]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpRouteActionProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpRouteHeaderProperty",
        jsii_struct_bases=[],
        name_mapping={"name": "name", "invert": "invert", "match": "match"},
    )
    class HttpRouteHeaderProperty:
        def __init__(
            self,
            *,
            name: builtins.str,
            invert: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            match: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HeaderMatchMethodProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the HTTP header in the request.

            :param name: A name for the HTTP header in the client request that will be matched on.
            :param invert: Specify ``True`` to match anything except the match criteria. The default value is ``False`` .
            :param match: The ``HeaderMatchMethod`` object.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httprouteheader.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_route_header_property = appmesh.CfnRoute.HttpRouteHeaderProperty(
                    name="name",
                
                    # the properties below are optional
                    invert=False,
                    match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                        exact="exact",
                        prefix="prefix",
                        range=appmesh.CfnRoute.MatchRangeProperty(
                            end=123,
                            start=123
                        ),
                        regex="regex",
                        suffix="suffix"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpRouteHeaderProperty.__init__)
                check_type(argname="argument name", value=name, expected_type=type_hints["name"])
                check_type(argname="argument invert", value=invert, expected_type=type_hints["invert"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "name": name,
            }
            if invert is not None:
                self._values["invert"] = invert
            if match is not None:
                self._values["match"] = match

        @builtins.property
        def name(self) -> builtins.str:
            '''A name for the HTTP header in the client request that will be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httprouteheader.html#cfn-appmesh-route-httprouteheader-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def invert(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''Specify ``True`` to match anything except the match criteria.

            The default value is ``False`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httprouteheader.html#cfn-appmesh-route-httprouteheader-invert
            '''
            result = self._values.get("invert")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HeaderMatchMethodProperty"]]:
            '''The ``HeaderMatchMethod`` object.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httprouteheader.html#cfn-appmesh-route-httprouteheader-match
            '''
            result = self._values.get("match")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HeaderMatchMethodProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpRouteHeaderProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpRouteMatchProperty",
        jsii_struct_bases=[],
        name_mapping={
            "headers": "headers",
            "method": "method",
            "path": "path",
            "port": "port",
            "prefix": "prefix",
            "query_parameters": "queryParameters",
            "scheme": "scheme",
        },
    )
    class HttpRouteMatchProperty:
        def __init__(
            self,
            *,
            headers: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpRouteHeaderProperty", typing.Dict[str, typing.Any]]]]]] = None,
            method: typing.Optional[builtins.str] = None,
            path: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpPathMatchProperty", typing.Dict[str, typing.Any]]]] = None,
            port: typing.Optional[jsii.Number] = None,
            prefix: typing.Optional[builtins.str] = None,
            query_parameters: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.QueryParameterProperty", typing.Dict[str, typing.Any]]]]]] = None,
            scheme: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the requirements for a route to match HTTP requests for a virtual router.

            :param headers: The client request headers to match on.
            :param method: The client request method to match on. Specify only one.
            :param path: The client request path to match on.
            :param port: ``CfnRoute.HttpRouteMatchProperty.Port``.
            :param prefix: Specifies the path to match requests with. This parameter must always start with ``/`` , which by itself matches all requests to the virtual service name. You can also match 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`` .
            :param query_parameters: The client request query parameters to match on.
            :param scheme: The client request scheme to match on. Specify only one. Applicable only for HTTP2 routes.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_route_match_property = appmesh.CfnRoute.HttpRouteMatchProperty(
                    headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                        name="name",
                
                        # the properties below are optional
                        invert=False,
                        match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                            exact="exact",
                            prefix="prefix",
                            range=appmesh.CfnRoute.MatchRangeProperty(
                                end=123,
                                start=123
                            ),
                            regex="regex",
                            suffix="suffix"
                        )
                    )],
                    method="method",
                    path=appmesh.CfnRoute.HttpPathMatchProperty(
                        exact="exact",
                        regex="regex"
                    ),
                    port=123,
                    prefix="prefix",
                    query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                        name="name",
                
                        # the properties below are optional
                        match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                            exact="exact"
                        )
                    )],
                    scheme="scheme"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpRouteMatchProperty.__init__)
                check_type(argname="argument headers", value=headers, expected_type=type_hints["headers"])
                check_type(argname="argument method", value=method, expected_type=type_hints["method"])
                check_type(argname="argument path", value=path, expected_type=type_hints["path"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
                check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
                check_type(argname="argument query_parameters", value=query_parameters, expected_type=type_hints["query_parameters"])
                check_type(argname="argument scheme", value=scheme, expected_type=type_hints["scheme"])
            self._values: typing.Dict[str, typing.Any] = {}
            if headers is not None:
                self._values["headers"] = headers
            if method is not None:
                self._values["method"] = method
            if path is not None:
                self._values["path"] = path
            if port is not None:
                self._values["port"] = port
            if prefix is not None:
                self._values["prefix"] = prefix
            if query_parameters is not None:
                self._values["query_parameters"] = query_parameters
            if scheme is not None:
                self._values["scheme"] = scheme

        @builtins.property
        def headers(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteHeaderProperty"]]]]:
            '''The client request headers to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html#cfn-appmesh-route-httproutematch-headers
            '''
            result = self._values.get("headers")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteHeaderProperty"]]]], result)

        @builtins.property
        def method(self) -> typing.Optional[builtins.str]:
            '''The client request method to match on.

            Specify only one.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html#cfn-appmesh-route-httproutematch-method
            '''
            result = self._values.get("method")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def path(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpPathMatchProperty"]]:
            '''The client request path to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html#cfn-appmesh-route-httproutematch-path
            '''
            result = self._values.get("path")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpPathMatchProperty"]], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnRoute.HttpRouteMatchProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html#cfn-appmesh-route-httproutematch-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def prefix(self) -> typing.Optional[builtins.str]:
            '''Specifies the path to match requests with.

            This parameter must always start with ``/`` , which by itself matches all requests to the virtual service name. You can also match 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`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html#cfn-appmesh-route-httproutematch-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def query_parameters(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.QueryParameterProperty"]]]]:
            '''The client request query parameters to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html#cfn-appmesh-route-httproutematch-queryparameters
            '''
            result = self._values.get("query_parameters")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.QueryParameterProperty"]]]], result)

        @builtins.property
        def scheme(self) -> typing.Optional[builtins.str]:
            '''The client request scheme to match on.

            Specify only one. Applicable only for HTTP2 routes.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproutematch.html#cfn-appmesh-route-httproutematch-scheme
            '''
            result = self._values.get("scheme")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpRouteMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpRouteProperty",
        jsii_struct_bases=[],
        name_mapping={
            "action": "action",
            "match": "match",
            "retry_policy": "retryPolicy",
            "timeout": "timeout",
        },
    )
    class HttpRouteProperty:
        def __init__(
            self,
            *,
            action: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpRouteActionProperty", typing.Dict[str, typing.Any]]],
            match: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpRouteMatchProperty", typing.Dict[str, typing.Any]]],
            retry_policy: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpRetryPolicyProperty", typing.Dict[str, typing.Any]]]] = None,
            timeout: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents an HTTP or HTTP/2 route type.

            :param action: An object that represents the action to take if a match is determined.
            :param match: An object that represents the criteria for determining a request match.
            :param retry_policy: An object that represents a retry policy.
            :param timeout: An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproute.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_route_property = appmesh.CfnRoute.HttpRouteProperty(
                    action=appmesh.CfnRoute.HttpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
                
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.HttpRouteMatchProperty(
                        headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                            name="name",
                
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method="method",
                        path=appmesh.CfnRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                            name="name",
                
                            # the properties below are optional
                            match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )],
                        scheme="scheme"
                    ),
                
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                
                        # the properties below are optional
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpRouteProperty.__init__)
                check_type(argname="argument action", value=action, expected_type=type_hints["action"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
                check_type(argname="argument retry_policy", value=retry_policy, expected_type=type_hints["retry_policy"])
                check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            self._values: typing.Dict[str, typing.Any] = {
                "action": action,
                "match": match,
            }
            if retry_policy is not None:
                self._values["retry_policy"] = retry_policy
            if timeout is not None:
                self._values["timeout"] = timeout

        @builtins.property
        def action(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteActionProperty"]:
            '''An object that represents the action to take if a match is determined.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproute.html#cfn-appmesh-route-httproute-action
            '''
            result = self._values.get("action")
            assert result is not None, "Required property 'action' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteActionProperty"], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteMatchProperty"]:
            '''An object that represents the criteria for determining a request match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproute.html#cfn-appmesh-route-httproute-match
            '''
            result = self._values.get("match")
            assert result is not None, "Required property 'match' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteMatchProperty"], result)

        @builtins.property
        def retry_policy(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRetryPolicyProperty"]]:
            '''An object that represents a retry policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproute.html#cfn-appmesh-route-httproute-retrypolicy
            '''
            result = self._values.get("retry_policy")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRetryPolicyProperty"]], result)

        @builtins.property
        def timeout(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpTimeoutProperty"]]:
            '''An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproute.html#cfn-appmesh-route-httproute-timeout
            '''
            result = self._values.get("timeout")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpTimeoutProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpRouteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.HttpTimeoutProperty",
        jsii_struct_bases=[],
        name_mapping={"idle": "idle", "per_request": "perRequest"},
    )
    class HttpTimeoutProperty:
        def __init__(
            self,
            *,
            idle: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
            per_request: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents types of timeouts.

            :param idle: An object that represents an idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none.
            :param per_request: An object that represents a per request timeout. The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httptimeout.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_timeout_property = appmesh.CfnRoute.HttpTimeoutProperty(
                    idle=appmesh.CfnRoute.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                    per_request=appmesh.CfnRoute.DurationProperty(
                        unit="unit",
                        value=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.HttpTimeoutProperty.__init__)
                check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
                check_type(argname="argument per_request", value=per_request, expected_type=type_hints["per_request"])
            self._values: typing.Dict[str, typing.Any] = {}
            if idle is not None:
                self._values["idle"] = idle
            if per_request is not None:
                self._values["per_request"] = per_request

        @builtins.property
        def idle(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]]:
            '''An object that represents an idle timeout.

            An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httptimeout.html#cfn-appmesh-route-httptimeout-idle
            '''
            result = self._values.get("idle")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]], result)

        @builtins.property
        def per_request(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]]:
            '''An object that represents a per request timeout.

            The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httptimeout.html#cfn-appmesh-route-httptimeout-perrequest
            '''
            result = self._values.get("per_request")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpTimeoutProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.MatchRangeProperty",
        jsii_struct_bases=[],
        name_mapping={"end": "end", "start": "start"},
    )
    class MatchRangeProperty:
        def __init__(self, *, end: jsii.Number, start: jsii.Number) -> None:
            '''An object that represents the range of values to match on.

            The first character of the range is included in the range, though the last character is not. For example, if the range specified were 1-100, only values 1-99 would be matched.

            :param end: The end of the range.
            :param start: The start of the range.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-matchrange.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                match_range_property = appmesh.CfnRoute.MatchRangeProperty(
                    end=123,
                    start=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.MatchRangeProperty.__init__)
                check_type(argname="argument end", value=end, expected_type=type_hints["end"])
                check_type(argname="argument start", value=start, expected_type=type_hints["start"])
            self._values: typing.Dict[str, typing.Any] = {
                "end": end,
                "start": start,
            }

        @builtins.property
        def end(self) -> jsii.Number:
            '''The end of the range.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-matchrange.html#cfn-appmesh-route-matchrange-end
            '''
            result = self._values.get("end")
            assert result is not None, "Required property 'end' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def start(self) -> jsii.Number:
            '''The start of the range.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-matchrange.html#cfn-appmesh-route-matchrange-start
            '''
            result = self._values.get("start")
            assert result is not None, "Required property 'start' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "MatchRangeProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.QueryParameterProperty",
        jsii_struct_bases=[],
        name_mapping={"name": "name", "match": "match"},
    )
    class QueryParameterProperty:
        def __init__(
            self,
            *,
            name: builtins.str,
            match: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpQueryParameterMatchProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the query parameter in the request.

            :param name: A name for the query parameter that will be matched on.
            :param match: The query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-queryparameter.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                query_parameter_property = appmesh.CfnRoute.QueryParameterProperty(
                    name="name",
                
                    # the properties below are optional
                    match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                        exact="exact"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.QueryParameterProperty.__init__)
                check_type(argname="argument name", value=name, expected_type=type_hints["name"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "name": name,
            }
            if match is not None:
                self._values["match"] = match

        @builtins.property
        def name(self) -> builtins.str:
            '''A name for the query parameter that will be matched on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-queryparameter.html#cfn-appmesh-route-queryparameter-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def match(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpQueryParameterMatchProperty"]]:
            '''The query parameter to match on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-queryparameter.html#cfn-appmesh-route-queryparameter-match
            '''
            result = self._values.get("match")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpQueryParameterMatchProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "QueryParameterProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.RouteSpecProperty",
        jsii_struct_bases=[],
        name_mapping={
            "grpc_route": "grpcRoute",
            "http2_route": "http2Route",
            "http_route": "httpRoute",
            "priority": "priority",
            "tcp_route": "tcpRoute",
        },
    )
    class RouteSpecProperty:
        def __init__(
            self,
            *,
            grpc_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.GrpcRouteProperty", typing.Dict[str, typing.Any]]]] = None,
            http2_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpRouteProperty", typing.Dict[str, typing.Any]]]] = None,
            http_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.HttpRouteProperty", typing.Dict[str, typing.Any]]]] = None,
            priority: typing.Optional[jsii.Number] = None,
            tcp_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.TcpRouteProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a route specification.

            Specify one route type.

            :param grpc_route: An object that represents the specification of a gRPC route.
            :param http2_route: An object that represents the specification of an HTTP/2 route.
            :param http_route: An object that represents the specification of an HTTP route.
            :param priority: The priority for the route. Routes are matched based on the specified value, where 0 is the highest priority.
            :param tcp_route: An object that represents the specification of a TCP route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-routespec.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                route_spec_property = appmesh.CfnRoute.RouteSpecProperty(
                    grpc_route=appmesh.CfnRoute.GrpcRouteProperty(
                        action=appmesh.CfnRoute.GrpcRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
                
                                # the properties below are optional
                                port=123
                            )]
                        ),
                        match=appmesh.CfnRoute.GrpcRouteMatchProperty(
                            metadata=[appmesh.CfnRoute.GrpcRouteMetadataProperty(
                                name="name",
                
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnRoute.MatchRangeProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            method_name="methodName",
                            port=123,
                            service_name="serviceName"
                        ),
                
                        # the properties below are optional
                        retry_policy=appmesh.CfnRoute.GrpcRetryPolicyProperty(
                            max_retries=123,
                            per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                
                            # the properties below are optional
                            grpc_retry_events=["grpcRetryEvents"],
                            http_retry_events=["httpRetryEvents"],
                            tcp_retry_events=["tcpRetryEvents"]
                        ),
                        timeout=appmesh.CfnRoute.GrpcTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    http2_route=appmesh.CfnRoute.HttpRouteProperty(
                        action=appmesh.CfnRoute.HttpRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
                
                                # the properties below are optional
                                port=123
                            )]
                        ),
                        match=appmesh.CfnRoute.HttpRouteMatchProperty(
                            headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                                name="name",
                
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnRoute.MatchRangeProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            method="method",
                            path=appmesh.CfnRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                                name="name",
                
                                # the properties below are optional
                                match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )],
                            scheme="scheme"
                        ),
                
                        # the properties below are optional
                        retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                            max_retries=123,
                            per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                
                            # the properties below are optional
                            http_retry_events=["httpRetryEvents"],
                            tcp_retry_events=["tcpRetryEvents"]
                        ),
                        timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    http_route=appmesh.CfnRoute.HttpRouteProperty(
                        action=appmesh.CfnRoute.HttpRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
                
                                # the properties below are optional
                                port=123
                            )]
                        ),
                        match=appmesh.CfnRoute.HttpRouteMatchProperty(
                            headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                                name="name",
                
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnRoute.MatchRangeProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            method="method",
                            path=appmesh.CfnRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                                name="name",
                
                                # the properties below are optional
                                match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )],
                            scheme="scheme"
                        ),
                
                        # the properties below are optional
                        retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                            max_retries=123,
                            per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                
                            # the properties below are optional
                            http_retry_events=["httpRetryEvents"],
                            tcp_retry_events=["tcpRetryEvents"]
                        ),
                        timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    priority=123,
                    tcp_route=appmesh.CfnRoute.TcpRouteProperty(
                        action=appmesh.CfnRoute.TcpRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
                
                                # the properties below are optional
                                port=123
                            )]
                        ),
                
                        # the properties below are optional
                        match=appmesh.CfnRoute.TcpRouteMatchProperty(
                            port=123
                        ),
                        timeout=appmesh.CfnRoute.TcpTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.RouteSpecProperty.__init__)
                check_type(argname="argument grpc_route", value=grpc_route, expected_type=type_hints["grpc_route"])
                check_type(argname="argument http2_route", value=http2_route, expected_type=type_hints["http2_route"])
                check_type(argname="argument http_route", value=http_route, expected_type=type_hints["http_route"])
                check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
                check_type(argname="argument tcp_route", value=tcp_route, expected_type=type_hints["tcp_route"])
            self._values: typing.Dict[str, typing.Any] = {}
            if grpc_route is not None:
                self._values["grpc_route"] = grpc_route
            if http2_route is not None:
                self._values["http2_route"] = http2_route
            if http_route is not None:
                self._values["http_route"] = http_route
            if priority is not None:
                self._values["priority"] = priority
            if tcp_route is not None:
                self._values["tcp_route"] = tcp_route

        @builtins.property
        def grpc_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteProperty"]]:
            '''An object that represents the specification of a gRPC route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-routespec.html#cfn-appmesh-route-routespec-grpcroute
            '''
            result = self._values.get("grpc_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.GrpcRouteProperty"]], result)

        @builtins.property
        def http2_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteProperty"]]:
            '''An object that represents the specification of an HTTP/2 route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-routespec.html#cfn-appmesh-route-routespec-http2route
            '''
            result = self._values.get("http2_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteProperty"]], result)

        @builtins.property
        def http_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteProperty"]]:
            '''An object that represents the specification of an HTTP route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-routespec.html#cfn-appmesh-route-routespec-httproute
            '''
            result = self._values.get("http_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.HttpRouteProperty"]], result)

        @builtins.property
        def priority(self) -> typing.Optional[jsii.Number]:
            '''The priority for the route.

            Routes are matched based on the specified value, where 0 is the highest priority.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-routespec.html#cfn-appmesh-route-routespec-priority
            '''
            result = self._values.get("priority")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def tcp_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpRouteProperty"]]:
            '''An object that represents the specification of a TCP route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-routespec.html#cfn-appmesh-route-routespec-tcproute
            '''
            result = self._values.get("tcp_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpRouteProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "RouteSpecProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.TcpRouteActionProperty",
        jsii_struct_bases=[],
        name_mapping={"weighted_targets": "weightedTargets"},
    )
    class TcpRouteActionProperty:
        def __init__(
            self,
            *,
            weighted_targets: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.WeightedTargetProperty", typing.Dict[str, typing.Any]]]]],
        ) -> None:
            '''An object that represents the action to take if a match is determined.

            :param weighted_targets: An object that represents the targets that traffic is routed to when a request matches the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcprouteaction.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tcp_route_action_property = appmesh.CfnRoute.TcpRouteActionProperty(
                    weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                        virtual_node="virtualNode",
                        weight=123,
                
                        # the properties below are optional
                        port=123
                    )]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.TcpRouteActionProperty.__init__)
                check_type(argname="argument weighted_targets", value=weighted_targets, expected_type=type_hints["weighted_targets"])
            self._values: typing.Dict[str, typing.Any] = {
                "weighted_targets": weighted_targets,
            }

        @builtins.property
        def weighted_targets(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.WeightedTargetProperty"]]]:
            '''An object that represents the targets that traffic is routed to when a request matches the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcprouteaction.html#cfn-appmesh-route-tcprouteaction-weightedtargets
            '''
            result = self._values.get("weighted_targets")
            assert result is not None, "Required property 'weighted_targets' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.WeightedTargetProperty"]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TcpRouteActionProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.TcpRouteMatchProperty",
        jsii_struct_bases=[],
        name_mapping={"port": "port"},
    )
    class TcpRouteMatchProperty:
        def __init__(self, *, port: typing.Optional[jsii.Number] = None) -> None:
            '''
            :param port: ``CfnRoute.TcpRouteMatchProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcproutematch.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tcp_route_match_property = appmesh.CfnRoute.TcpRouteMatchProperty(
                    port=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.TcpRouteMatchProperty.__init__)
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            self._values: typing.Dict[str, typing.Any] = {}
            if port is not None:
                self._values["port"] = port

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnRoute.TcpRouteMatchProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcproutematch.html#cfn-appmesh-route-tcproutematch-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TcpRouteMatchProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.TcpRouteProperty",
        jsii_struct_bases=[],
        name_mapping={"action": "action", "match": "match", "timeout": "timeout"},
    )
    class TcpRouteProperty:
        def __init__(
            self,
            *,
            action: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.TcpRouteActionProperty", typing.Dict[str, typing.Any]]],
            match: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.TcpRouteMatchProperty", typing.Dict[str, typing.Any]]]] = None,
            timeout: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.TcpTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a TCP route type.

            :param action: The action to take if a match is determined.
            :param match: ``CfnRoute.TcpRouteProperty.Match``.
            :param timeout: An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcproute.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tcp_route_property = appmesh.CfnRoute.TcpRouteProperty(
                    action=appmesh.CfnRoute.TcpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
                
                            # the properties below are optional
                            port=123
                        )]
                    ),
                
                    # the properties below are optional
                    match=appmesh.CfnRoute.TcpRouteMatchProperty(
                        port=123
                    ),
                    timeout=appmesh.CfnRoute.TcpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.TcpRouteProperty.__init__)
                check_type(argname="argument action", value=action, expected_type=type_hints["action"])
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
                check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            self._values: typing.Dict[str, typing.Any] = {
                "action": action,
            }
            if match is not None:
                self._values["match"] = match
            if timeout is not None:
                self._values["timeout"] = timeout

        @builtins.property
        def action(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpRouteActionProperty"]:
            '''The action to take if a match is determined.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcproute.html#cfn-appmesh-route-tcproute-action
            '''
            result = self._values.get("action")
            assert result is not None, "Required property 'action' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpRouteActionProperty"], result)

        @builtins.property
        def match(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpRouteMatchProperty"]]:
            '''``CfnRoute.TcpRouteProperty.Match``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcproute.html#cfn-appmesh-route-tcproute-match
            '''
            result = self._values.get("match")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpRouteMatchProperty"]], result)

        @builtins.property
        def timeout(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpTimeoutProperty"]]:
            '''An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcproute.html#cfn-appmesh-route-tcproute-timeout
            '''
            result = self._values.get("timeout")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.TcpTimeoutProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TcpRouteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.TcpTimeoutProperty",
        jsii_struct_bases=[],
        name_mapping={"idle": "idle"},
    )
    class TcpTimeoutProperty:
        def __init__(
            self,
            *,
            idle: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnRoute.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents types of timeouts.

            :param idle: An object that represents an idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcptimeout.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tcp_timeout_property = appmesh.CfnRoute.TcpTimeoutProperty(
                    idle=appmesh.CfnRoute.DurationProperty(
                        unit="unit",
                        value=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.TcpTimeoutProperty.__init__)
                check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
            self._values: typing.Dict[str, typing.Any] = {}
            if idle is not None:
                self._values["idle"] = idle

        @builtins.property
        def idle(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]]:
            '''An object that represents an idle timeout.

            An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcptimeout.html#cfn-appmesh-route-tcptimeout-idle
            '''
            result = self._values.get("idle")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnRoute.DurationProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TcpTimeoutProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnRoute.WeightedTargetProperty",
        jsii_struct_bases=[],
        name_mapping={
            "virtual_node": "virtualNode",
            "weight": "weight",
            "port": "port",
        },
    )
    class WeightedTargetProperty:
        def __init__(
            self,
            *,
            virtual_node: builtins.str,
            weight: jsii.Number,
            port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''An object that represents a target and its relative weight.

            Traffic is distributed across targets according to their relative weight. For example, a weighted target with a relative weight of 50 receives five times as much traffic as one with a relative weight of 10. The total weight for all targets combined must be less than or equal to 100.

            :param virtual_node: The virtual node to associate with the weighted target.
            :param weight: The relative weight of the weighted target.
            :param port: ``CfnRoute.WeightedTargetProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-weightedtarget.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                weighted_target_property = appmesh.CfnRoute.WeightedTargetProperty(
                    virtual_node="virtualNode",
                    weight=123,
                
                    # the properties below are optional
                    port=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnRoute.WeightedTargetProperty.__init__)
                check_type(argname="argument virtual_node", value=virtual_node, expected_type=type_hints["virtual_node"])
                check_type(argname="argument weight", value=weight, expected_type=type_hints["weight"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            self._values: typing.Dict[str, typing.Any] = {
                "virtual_node": virtual_node,
                "weight": weight,
            }
            if port is not None:
                self._values["port"] = port

        @builtins.property
        def virtual_node(self) -> builtins.str:
            '''The virtual node to associate with the weighted target.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-weightedtarget.html#cfn-appmesh-route-weightedtarget-virtualnode
            '''
            result = self._values.get("virtual_node")
            assert result is not None, "Required property 'virtual_node' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def weight(self) -> jsii.Number:
            '''The relative weight of the weighted target.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-weightedtarget.html#cfn-appmesh-route-weightedtarget-weight
            '''
            result = self._values.get("weight")
            assert result is not None, "Required property 'weight' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnRoute.WeightedTargetProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-weightedtarget.html#cfn-appmesh-route-weightedtarget-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "WeightedTargetProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CfnRouteProps",
    jsii_struct_bases=[],
    name_mapping={
        "mesh_name": "meshName",
        "spec": "spec",
        "virtual_router_name": "virtualRouterName",
        "mesh_owner": "meshOwner",
        "route_name": "routeName",
        "tags": "tags",
    },
)
class CfnRouteProps:
    def __init__(
        self,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union[CfnRoute.RouteSpecProperty, typing.Dict[str, typing.Any]]],
        virtual_router_name: builtins.str,
        mesh_owner: typing.Optional[builtins.str] = None,
        route_name: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Properties for defining a ``CfnRoute``.

        :param mesh_name: The name of the service mesh to create the route in.
        :param spec: The route specification to apply.
        :param virtual_router_name: The name of the virtual router in which to create the route. If the virtual router is in a shared mesh, then you must be the owner of the virtual router resource.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param route_name: The name to use for the route.
        :param tags: Optional metadata that you can apply to the route to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html
        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            cfn_route_props = appmesh.CfnRouteProps(
                mesh_name="meshName",
                spec=appmesh.CfnRoute.RouteSpecProperty(
                    grpc_route=appmesh.CfnRoute.GrpcRouteProperty(
                        action=appmesh.CfnRoute.GrpcRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
            
                                # the properties below are optional
                                port=123
                            )]
                        ),
                        match=appmesh.CfnRoute.GrpcRouteMatchProperty(
                            metadata=[appmesh.CfnRoute.GrpcRouteMetadataProperty(
                                name="name",
            
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnRoute.MatchRangeProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            method_name="methodName",
                            port=123,
                            service_name="serviceName"
                        ),
            
                        # the properties below are optional
                        retry_policy=appmesh.CfnRoute.GrpcRetryPolicyProperty(
                            max_retries=123,
                            per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
            
                            # the properties below are optional
                            grpc_retry_events=["grpcRetryEvents"],
                            http_retry_events=["httpRetryEvents"],
                            tcp_retry_events=["tcpRetryEvents"]
                        ),
                        timeout=appmesh.CfnRoute.GrpcTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    http2_route=appmesh.CfnRoute.HttpRouteProperty(
                        action=appmesh.CfnRoute.HttpRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
            
                                # the properties below are optional
                                port=123
                            )]
                        ),
                        match=appmesh.CfnRoute.HttpRouteMatchProperty(
                            headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                                name="name",
            
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnRoute.MatchRangeProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            method="method",
                            path=appmesh.CfnRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                                name="name",
            
                                # the properties below are optional
                                match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )],
                            scheme="scheme"
                        ),
            
                        # the properties below are optional
                        retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                            max_retries=123,
                            per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
            
                            # the properties below are optional
                            http_retry_events=["httpRetryEvents"],
                            tcp_retry_events=["tcpRetryEvents"]
                        ),
                        timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    http_route=appmesh.CfnRoute.HttpRouteProperty(
                        action=appmesh.CfnRoute.HttpRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
            
                                # the properties below are optional
                                port=123
                            )]
                        ),
                        match=appmesh.CfnRoute.HttpRouteMatchProperty(
                            headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                                name="name",
            
                                # the properties below are optional
                                invert=False,
                                match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                    exact="exact",
                                    prefix="prefix",
                                    range=appmesh.CfnRoute.MatchRangeProperty(
                                        end=123,
                                        start=123
                                    ),
                                    regex="regex",
                                    suffix="suffix"
                                )
                            )],
                            method="method",
                            path=appmesh.CfnRoute.HttpPathMatchProperty(
                                exact="exact",
                                regex="regex"
                            ),
                            port=123,
                            prefix="prefix",
                            query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                                name="name",
            
                                # the properties below are optional
                                match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                    exact="exact"
                                )
                            )],
                            scheme="scheme"
                        ),
            
                        # the properties below are optional
                        retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                            max_retries=123,
                            per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
            
                            # the properties below are optional
                            http_retry_events=["httpRetryEvents"],
                            tcp_retry_events=["tcpRetryEvents"]
                        ),
                        timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    priority=123,
                    tcp_route=appmesh.CfnRoute.TcpRouteProperty(
                        action=appmesh.CfnRoute.TcpRouteActionProperty(
                            weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                                virtual_node="virtualNode",
                                weight=123,
            
                                # the properties below are optional
                                port=123
                            )]
                        ),
            
                        # the properties below are optional
                        match=appmesh.CfnRoute.TcpRouteMatchProperty(
                            port=123
                        ),
                        timeout=appmesh.CfnRoute.TcpTimeoutProperty(
                            idle=appmesh.CfnRoute.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    )
                ),
                virtual_router_name="virtualRouterName",
            
                # the properties below are optional
                mesh_owner="meshOwner",
                route_name="routeName",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnRouteProps.__init__)
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument virtual_router_name", value=virtual_router_name, expected_type=type_hints["virtual_router_name"])
            check_type(argname="argument mesh_owner", value=mesh_owner, expected_type=type_hints["mesh_owner"])
            check_type(argname="argument route_name", value=route_name, expected_type=type_hints["route_name"])
            check_type(argname="argument tags", value=tags, expected_type=type_hints["tags"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh_name": mesh_name,
            "spec": spec,
            "virtual_router_name": virtual_router_name,
        }
        if mesh_owner is not None:
            self._values["mesh_owner"] = mesh_owner
        if route_name is not None:
            self._values["route_name"] = route_name
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the route in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-meshname
        '''
        result = self._values.get("mesh_name")
        assert result is not None, "Required property 'mesh_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnRoute.RouteSpecProperty]:
        '''The route specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnRoute.RouteSpecProperty], result)

    @builtins.property
    def virtual_router_name(self) -> builtins.str:
        '''The name of the virtual router in which to create the route.

        If the virtual router is in a shared mesh, then you must be the owner of the virtual router resource.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-virtualroutername
        '''
        result = self._values.get("virtual_router_name")
        assert result is not None, "Required property 'virtual_router_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-meshowner
        '''
        result = self._values.get("mesh_owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def route_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the route.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-routename
        '''
        result = self._values.get("route_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''Optional metadata that you can apply to the route to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-route.html#cfn-appmesh-route-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVirtualGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway",
):
    '''A CloudFormation ``AWS::AppMesh::VirtualGateway``.

    Creates a virtual gateway.

    A virtual gateway allows resources outside your mesh to communicate to resources that are inside your mesh. The virtual gateway represents an Envoy proxy running in an Amazon ECS task, in a Kubernetes service, or on an Amazon EC2 instance. Unlike a virtual node, which represents an Envoy running with an application, a virtual gateway represents Envoy deployed by itself.

    For more information about virtual gateways, see `Virtual gateways <https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_gateways.html>`_ .

    :cloudformationResource: AWS::AppMesh::VirtualGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        cfn_virtual_gateway = appmesh.CfnVirtualGateway(self, "MyCfnVirtualGateway",
            mesh_name="meshName",
            spec=appmesh.CfnVirtualGateway.VirtualGatewaySpecProperty(
                listeners=[appmesh.CfnVirtualGateway.VirtualGatewayListenerProperty(
                    port_mapping=appmesh.CfnVirtualGateway.VirtualGatewayPortMappingProperty(
                        port=123,
                        protocol="protocol"
                    ),
        
                    # the properties below are optional
                    connection_pool=appmesh.CfnVirtualGateway.VirtualGatewayConnectionPoolProperty(
                        grpc=appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty(
                            max_requests=123
                        ),
                        http=appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty(
                            max_connections=123,
        
                            # the properties below are optional
                            max_pending_requests=123
                        ),
                        http2=appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty(
                            max_requests=123
                        )
                    ),
                    health_check=appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(
                        healthy_threshold=123,
                        interval_millis=123,
                        protocol="protocol",
                        timeout_millis=123,
                        unhealthy_threshold=123,
        
                        # the properties below are optional
                        path="path",
                        port=123
                    ),
                    tls=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsProperty(
                        certificate=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty(
                            acm=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                                certificate_arn="certificateArn"
                            ),
                            file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        mode="mode",
        
                        # the properties below are optional
                        validation=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty(
                            trust=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                                file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
        
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        )
                    )
                )],
        
                # the properties below are optional
                backend_defaults=appmesh.CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty(
                    client_policy=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyProperty(
                        tls=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty(
                            validation=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty(
                                trust=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                                    acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                                        certificate_authority_arns=["certificateAuthorityArns"]
                                    ),
                                    file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
        
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            ),
        
                            # the properties below are optional
                            certificate=appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty(
                                file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            enforce=False,
                            ports=[123]
                        )
                    )
                ),
                logging=appmesh.CfnVirtualGateway.VirtualGatewayLoggingProperty(
                    access_log=appmesh.CfnVirtualGateway.VirtualGatewayAccessLogProperty(
                        file=appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty(
                            path="path",
        
                            # the properties below are optional
                            format=appmesh.CfnVirtualGateway.LoggingFormatProperty(
                                json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                                    key="key",
                                    value="value"
                                )],
                                text="text"
                            )
                        )
                    )
                )
            ),
        
            # the properties below are optional
            mesh_owner="meshOwner",
            tags=[CfnTag(
                key="key",
                value="value"
            )],
            virtual_gateway_name="virtualGatewayName"
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewaySpecProperty", typing.Dict[str, typing.Any]]],
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::AppMesh::VirtualGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param mesh_name: The name of the service mesh that the virtual gateway resides in.
        :param spec: The specifications of the virtual gateway.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual gateway to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        :param virtual_gateway_name: The name of the virtual gateway.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualGateway.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = CfnVirtualGatewayProps(
            mesh_name=mesh_name,
            spec=spec,
            mesh_owner=mesh_owner,
            tags=tags,
            virtual_gateway_name=virtual_gateway_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualGateway.inspect)
            check_type(argname="argument inspector", value=inspector, expected_type=type_hints["inspector"])
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualGateway._render_properties)
            check_type(argname="argument props", value=props, expected_type=type_hints["props"])
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''The full Amazon Resource Name (ARN) for the virtual gateway.

        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshName")
    def attr_mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the virtual gateway resides in.

        :cloudformationAttribute: MeshName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshOwner")
    def attr_mesh_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: MeshOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrResourceOwner")
    def attr_resource_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the resource owner.

        If the account ID is not your own, then it's the ID of the mesh owner or of another account that the mesh is shared with. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: ResourceOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrUid")
    def attr_uid(self) -> builtins.str:
        '''The unique identifier for the virtual gateway.

        :cloudformationAttribute: Uid
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrUid"))

    @builtins.property
    @jsii.member(jsii_name="attrVirtualGatewayName")
    def attr_virtual_gateway_name(self) -> builtins.str:
        '''The name of the virtual gateway.

        :cloudformationAttribute: VirtualGatewayName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVirtualGatewayName"))

    @builtins.property
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''Optional metadata that you can apply to the virtual gateway to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the virtual gateway resides in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-meshname
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))

    @mesh_name.setter
    def mesh_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualGateway, "mesh_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshName", value)

    @builtins.property
    @jsii.member(jsii_name="spec")
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewaySpecProperty"]:
        '''The specifications of the virtual gateway.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-spec
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewaySpecProperty"], jsii.get(self, "spec"))

    @spec.setter
    def spec(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewaySpecProperty"],
    ) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualGateway, "spec").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "spec", value)

    @builtins.property
    @jsii.member(jsii_name="meshOwner")
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-meshowner
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "meshOwner"))

    @mesh_owner.setter
    def mesh_owner(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualGateway, "mesh_owner").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshOwner", value)

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayName")
    def virtual_gateway_name(self) -> typing.Optional[builtins.str]:
        '''The name of the virtual gateway.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-virtualgatewayname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "virtualGatewayName"))

    @virtual_gateway_name.setter
    def virtual_gateway_name(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualGateway, "virtual_gateway_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "virtualGatewayName", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.JsonFormatRefProperty",
        jsii_struct_bases=[],
        name_mapping={"key": "key", "value": "value"},
    )
    class JsonFormatRefProperty:
        def __init__(self, *, key: builtins.str, value: builtins.str) -> None:
            '''
            :param key: ``CfnVirtualGateway.JsonFormatRefProperty.Key``.
            :param value: ``CfnVirtualGateway.JsonFormatRefProperty.Value``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-jsonformatref.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                json_format_ref_property = appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                    key="key",
                    value="value"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.JsonFormatRefProperty.__init__)
                check_type(argname="argument key", value=key, expected_type=type_hints["key"])
                check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            self._values: typing.Dict[str, typing.Any] = {
                "key": key,
                "value": value,
            }

        @builtins.property
        def key(self) -> builtins.str:
            '''``CfnVirtualGateway.JsonFormatRefProperty.Key``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-jsonformatref.html#cfn-appmesh-virtualgateway-jsonformatref-key
            '''
            result = self._values.get("key")
            assert result is not None, "Required property 'key' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def value(self) -> builtins.str:
            '''``CfnVirtualGateway.JsonFormatRefProperty.Value``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-jsonformatref.html#cfn-appmesh-virtualgateway-jsonformatref-value
            '''
            result = self._values.get("value")
            assert result is not None, "Required property 'value' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "JsonFormatRefProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.LoggingFormatProperty",
        jsii_struct_bases=[],
        name_mapping={"json": "json", "text": "text"},
    )
    class LoggingFormatProperty:
        def __init__(
            self,
            *,
            json: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.JsonFormatRefProperty", typing.Dict[str, typing.Any]]]]]] = None,
            text: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param json: ``CfnVirtualGateway.LoggingFormatProperty.Json``.
            :param text: ``CfnVirtualGateway.LoggingFormatProperty.Text``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-loggingformat.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                logging_format_property = appmesh.CfnVirtualGateway.LoggingFormatProperty(
                    json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                        key="key",
                        value="value"
                    )],
                    text="text"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.LoggingFormatProperty.__init__)
                check_type(argname="argument json", value=json, expected_type=type_hints["json"])
                check_type(argname="argument text", value=text, expected_type=type_hints["text"])
            self._values: typing.Dict[str, typing.Any] = {}
            if json is not None:
                self._values["json"] = json
            if text is not None:
                self._values["text"] = text

        @builtins.property
        def json(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.JsonFormatRefProperty"]]]]:
            '''``CfnVirtualGateway.LoggingFormatProperty.Json``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-loggingformat.html#cfn-appmesh-virtualgateway-loggingformat-json
            '''
            result = self._values.get("json")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.JsonFormatRefProperty"]]]], result)

        @builtins.property
        def text(self) -> typing.Optional[builtins.str]:
            '''``CfnVirtualGateway.LoggingFormatProperty.Text``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-loggingformat.html#cfn-appmesh-virtualgateway-loggingformat-text
            '''
            result = self._values.get("text")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LoggingFormatProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact"},
    )
    class SubjectAlternativeNameMatchersProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''An object that represents the methods by which a subject alternative name on a peer Transport Layer Security (TLS) certificate can be matched.

            :param exact: The values sent must match the specified values exactly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-subjectalternativenamematchers.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                subject_alternative_name_matchers_property = appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                    exact=["exact"]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.SubjectAlternativeNameMatchersProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact

        @builtins.property
        def exact(self) -> typing.Optional[typing.List[builtins.str]]:
            '''The values sent must match the specified values exactly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-subjectalternativenamematchers.html#cfn-appmesh-virtualgateway-subjectalternativenamematchers-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SubjectAlternativeNameMatchersProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty",
        jsii_struct_bases=[],
        name_mapping={"match": "match"},
    )
    class SubjectAlternativeNamesProperty:
        def __init__(
            self,
            *,
            match: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.SubjectAlternativeNameMatchersProperty", typing.Dict[str, typing.Any]]],
        ) -> None:
            '''An object that represents the subject alternative names secured by the certificate.

            :param match: An object that represents the criteria for determining a SANs match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-subjectalternativenames.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                subject_alternative_names_property = appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                    match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                        exact=["exact"]
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.SubjectAlternativeNamesProperty.__init__)
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "match": match,
            }

        @builtins.property
        def match(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.SubjectAlternativeNameMatchersProperty"]:
            '''An object that represents the criteria for determining a SANs match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-subjectalternativenames.html#cfn-appmesh-virtualgateway-subjectalternativenames-match
            '''
            result = self._values.get("match")
            assert result is not None, "Required property 'match' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.SubjectAlternativeNameMatchersProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SubjectAlternativeNamesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayAccessLogProperty",
        jsii_struct_bases=[],
        name_mapping={"file": "file"},
    )
    class VirtualGatewayAccessLogProperty:
        def __init__(
            self,
            *,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayFileAccessLogProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''The access log configuration for a virtual gateway.

            :param file: The file object to send virtual gateway access logs to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayaccesslog.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_access_log_property = appmesh.CfnVirtualGateway.VirtualGatewayAccessLogProperty(
                    file=appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty(
                        path="path",
                
                        # the properties below are optional
                        format=appmesh.CfnVirtualGateway.LoggingFormatProperty(
                            json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                                key="key",
                                value="value"
                            )],
                            text="text"
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayAccessLogProperty.__init__)
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
            self._values: typing.Dict[str, typing.Any] = {}
            if file is not None:
                self._values["file"] = file

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayFileAccessLogProperty"]]:
            '''The file object to send virtual gateway access logs to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayaccesslog.html#cfn-appmesh-virtualgateway-virtualgatewayaccesslog-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayFileAccessLogProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayAccessLogProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty",
        jsii_struct_bases=[],
        name_mapping={"client_policy": "clientPolicy"},
    )
    class VirtualGatewayBackendDefaultsProperty:
        def __init__(
            self,
            *,
            client_policy: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayClientPolicyProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the default properties for a backend.

            :param client_policy: A reference to an object that represents a client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaybackenddefaults.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_backend_defaults_property = appmesh.CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty(
                    client_policy=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyProperty(
                        tls=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty(
                            validation=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty(
                                trust=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                                    acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                                        certificate_authority_arns=["certificateAuthorityArns"]
                                    ),
                                    file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
                
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            ),
                
                            # the properties below are optional
                            certificate=appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty(
                                file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            enforce=False,
                            ports=[123]
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty.__init__)
                check_type(argname="argument client_policy", value=client_policy, expected_type=type_hints["client_policy"])
            self._values: typing.Dict[str, typing.Any] = {}
            if client_policy is not None:
                self._values["client_policy"] = client_policy

        @builtins.property
        def client_policy(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayClientPolicyProperty"]]:
            '''A reference to an object that represents a client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaybackenddefaults.html#cfn-appmesh-virtualgateway-virtualgatewaybackenddefaults-clientpolicy
            '''
            result = self._values.get("client_policy")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayClientPolicyProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayBackendDefaultsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyProperty",
        jsii_struct_bases=[],
        name_mapping={"tls": "tls"},
    )
    class VirtualGatewayClientPolicyProperty:
        def __init__(
            self,
            *,
            tls: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a client policy.

            :param tls: A reference to an object that represents a Transport Layer Security (TLS) client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclientpolicy.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_client_policy_property = appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyProperty(
                    tls=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty(
                        validation=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty(
                            trust=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                                acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                                    certificate_authority_arns=["certificateAuthorityArns"]
                                ),
                                file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
                
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        ),
                
                        # the properties below are optional
                        certificate=appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty(
                            file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        enforce=False,
                        ports=[123]
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayClientPolicyProperty.__init__)
                check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
            self._values: typing.Dict[str, typing.Any] = {}
            if tls is not None:
                self._values["tls"] = tls

        @builtins.property
        def tls(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty"]]:
            '''A reference to an object that represents a Transport Layer Security (TLS) client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclientpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayclientpolicy-tls
            '''
            result = self._values.get("tls")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayClientPolicyProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "validation": "validation",
            "certificate": "certificate",
            "enforce": "enforce",
            "ports": "ports",
        },
    )
    class VirtualGatewayClientPolicyTlsProperty:
        def __init__(
            self,
            *,
            validation: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty", typing.Dict[str, typing.Any]]],
            certificate: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            enforce: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            ports: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[jsii.Number]]] = None,
        ) -> None:
            '''An object that represents a Transport Layer Security (TLS) client policy.

            :param validation: A reference to an object that represents a Transport Layer Security (TLS) validation context.
            :param certificate: A reference to an object that represents a virtual gateway's client's Transport Layer Security (TLS) certificate.
            :param enforce: Whether the policy is enforced. The default is ``True`` , if a value isn't specified.
            :param ports: One or more ports that the policy is enforced for.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclientpolicytls.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_client_policy_tls_property = appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty(
                    validation=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty(
                        trust=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                            acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                                certificate_authority_arns=["certificateAuthorityArns"]
                            ),
                            file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                certificate_chain="certificateChain"
                            ),
                            sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                secret_name="secretName"
                            )
                        ),
                
                        # the properties below are optional
                        subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                            match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                exact=["exact"]
                            )
                        )
                    ),
                
                    # the properties below are optional
                    certificate=appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty(
                        file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                            certificate_chain="certificateChain",
                            private_key="privateKey"
                        ),
                        sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                            secret_name="secretName"
                        )
                    ),
                    enforce=False,
                    ports=[123]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty.__init__)
                check_type(argname="argument validation", value=validation, expected_type=type_hints["validation"])
                check_type(argname="argument certificate", value=certificate, expected_type=type_hints["certificate"])
                check_type(argname="argument enforce", value=enforce, expected_type=type_hints["enforce"])
                check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
            self._values: typing.Dict[str, typing.Any] = {
                "validation": validation,
            }
            if certificate is not None:
                self._values["certificate"] = certificate
            if enforce is not None:
                self._values["enforce"] = enforce
            if ports is not None:
                self._values["ports"] = ports

        @builtins.property
        def validation(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty"]:
            '''A reference to an object that represents a Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclientpolicytls.html#cfn-appmesh-virtualgateway-virtualgatewayclientpolicytls-validation
            '''
            result = self._values.get("validation")
            assert result is not None, "Required property 'validation' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty"], result)

        @builtins.property
        def certificate(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty"]]:
            '''A reference to an object that represents a virtual gateway's client's Transport Layer Security (TLS) certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclientpolicytls.html#cfn-appmesh-virtualgateway-virtualgatewayclientpolicytls-certificate
            '''
            result = self._values.get("certificate")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty"]], result)

        @builtins.property
        def enforce(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''Whether the policy is enforced.

            The default is ``True`` , if a value isn't specified.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclientpolicytls.html#cfn-appmesh-virtualgateway-virtualgatewayclientpolicytls-enforce
            '''
            result = self._values.get("enforce")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def ports(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[jsii.Number]]]:
            '''One or more ports that the policy is enforced for.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclientpolicytls.html#cfn-appmesh-virtualgateway-virtualgatewayclientpolicytls-ports
            '''
            result = self._values.get("ports")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[jsii.Number]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayClientPolicyTlsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"file": "file", "sds": "sds"},
    )
    class VirtualGatewayClientTlsCertificateProperty:
        def __init__(
            self,
            *,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the virtual gateway's client's Transport Layer Security (TLS) certificate.

            :param file: An object that represents a local file certificate. The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ .
            :param sds: A reference to an object that represents a virtual gateway's client's Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclienttlscertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_client_tls_certificate_property = appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty(
                    file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                        certificate_chain="certificateChain",
                        private_key="privateKey"
                    ),
                    sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty.__init__)
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty"]]:
            '''An object that represents a local file certificate.

            The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclienttlscertificate.html#cfn-appmesh-virtualgateway-virtualgatewayclienttlscertificate-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty"]]:
            '''A reference to an object that represents a virtual gateway's client's Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayclienttlscertificate.html#cfn-appmesh-virtualgateway-virtualgatewayclienttlscertificate-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayClientTlsCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={"grpc": "grpc", "http": "http", "http2": "http2"},
    )
    class VirtualGatewayConnectionPoolProperty:
        def __init__(
            self,
            *,
            grpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
            http: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
            http2: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the type of virtual gateway connection pool.

            Only one protocol is used at a time and should be the same protocol as the one chosen under port mapping.

            If not present the default value for ``maxPendingRequests`` is ``2147483647`` .

            :param grpc: An object that represents a type of connection pool.
            :param http: An object that represents a type of connection pool.
            :param http2: An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayconnectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_connection_pool_property = appmesh.CfnVirtualGateway.VirtualGatewayConnectionPoolProperty(
                    grpc=appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty(
                        max_requests=123
                    ),
                    http=appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty(
                        max_connections=123,
                
                        # the properties below are optional
                        max_pending_requests=123
                    ),
                    http2=appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty(
                        max_requests=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayConnectionPoolProperty.__init__)
                check_type(argname="argument grpc", value=grpc, expected_type=type_hints["grpc"])
                check_type(argname="argument http", value=http, expected_type=type_hints["http"])
                check_type(argname="argument http2", value=http2, expected_type=type_hints["http2"])
            self._values: typing.Dict[str, typing.Any] = {}
            if grpc is not None:
                self._values["grpc"] = grpc
            if http is not None:
                self._values["http"] = http
            if http2 is not None:
                self._values["http2"] = http2

        @builtins.property
        def grpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty"]]:
            '''An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayconnectionpool.html#cfn-appmesh-virtualgateway-virtualgatewayconnectionpool-grpc
            '''
            result = self._values.get("grpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty"]], result)

        @builtins.property
        def http(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty"]]:
            '''An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayconnectionpool.html#cfn-appmesh-virtualgateway-virtualgatewayconnectionpool-http
            '''
            result = self._values.get("http")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty"]], result)

        @builtins.property
        def http2(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty"]]:
            '''An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayconnectionpool.html#cfn-appmesh-virtualgateway-virtualgatewayconnectionpool-http2
            '''
            result = self._values.get("http2")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty",
        jsii_struct_bases=[],
        name_mapping={"path": "path", "format": "format"},
    )
    class VirtualGatewayFileAccessLogProperty:
        def __init__(
            self,
            *,
            path: builtins.str,
            format: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.LoggingFormatProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents an access log file.

            :param path: The file path to write access logs to. You can use ``/dev/stdout`` to send access logs to standard out and configure your Envoy container to use a log driver, such as ``awslogs`` , to export the access logs to a log storage service such as Amazon CloudWatch Logs. You can also specify a path in the Envoy container's file system to write the files to disk.
            :param format: ``CfnVirtualGateway.VirtualGatewayFileAccessLogProperty.Format``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayfileaccesslog.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_file_access_log_property = appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty(
                    path="path",
                
                    # the properties below are optional
                    format=appmesh.CfnVirtualGateway.LoggingFormatProperty(
                        json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                            key="key",
                            value="value"
                        )],
                        text="text"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayFileAccessLogProperty.__init__)
                check_type(argname="argument path", value=path, expected_type=type_hints["path"])
                check_type(argname="argument format", value=format, expected_type=type_hints["format"])
            self._values: typing.Dict[str, typing.Any] = {
                "path": path,
            }
            if format is not None:
                self._values["format"] = format

        @builtins.property
        def path(self) -> builtins.str:
            '''The file path to write access logs to.

            You can use ``/dev/stdout`` to send access logs to standard out and configure your Envoy container to use a log driver, such as ``awslogs`` , to export the access logs to a log storage service such as Amazon CloudWatch Logs. You can also specify a path in the Envoy container's file system to write the files to disk.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayfileaccesslog.html#cfn-appmesh-virtualgateway-virtualgatewayfileaccesslog-path
            '''
            result = self._values.get("path")
            assert result is not None, "Required property 'path' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def format(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.LoggingFormatProperty"]]:
            '''``CfnVirtualGateway.VirtualGatewayFileAccessLogProperty.Format``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayfileaccesslog.html#cfn-appmesh-virtualgateway-virtualgatewayfileaccesslog-format
            '''
            result = self._values.get("format")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.LoggingFormatProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayFileAccessLogProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={"max_requests": "maxRequests"},
    )
    class VirtualGatewayGrpcConnectionPoolProperty:
        def __init__(self, *, max_requests: jsii.Number) -> None:
            '''An object that represents a type of connection pool.

            :param max_requests: Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaygrpcconnectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_grpc_connection_pool_property = appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty(
                    max_requests=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty.__init__)
                check_type(argname="argument max_requests", value=max_requests, expected_type=type_hints["max_requests"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_requests": max_requests,
            }

        @builtins.property
        def max_requests(self) -> jsii.Number:
            '''Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaygrpcconnectionpool.html#cfn-appmesh-virtualgateway-virtualgatewaygrpcconnectionpool-maxrequests
            '''
            result = self._values.get("max_requests")
            assert result is not None, "Required property 'max_requests' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayGrpcConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty",
        jsii_struct_bases=[],
        name_mapping={
            "healthy_threshold": "healthyThreshold",
            "interval_millis": "intervalMillis",
            "protocol": "protocol",
            "timeout_millis": "timeoutMillis",
            "unhealthy_threshold": "unhealthyThreshold",
            "path": "path",
            "port": "port",
        },
    )
    class VirtualGatewayHealthCheckPolicyProperty:
        def __init__(
            self,
            *,
            healthy_threshold: jsii.Number,
            interval_millis: jsii.Number,
            protocol: builtins.str,
            timeout_millis: jsii.Number,
            unhealthy_threshold: jsii.Number,
            path: typing.Optional[builtins.str] = None,
            port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''An object that represents the health check policy for a virtual gateway's listener.

            :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring the listener healthy.
            :param interval_millis: The time period in milliseconds between each health check execution.
            :param protocol: The protocol for the health check request. If you specify ``grpc`` , then your service must conform to the `GRPC Health Checking Protocol <https://docs.aws.amazon.com/https://github.com/grpc/grpc/blob/master/doc/health-checking.md>`_ .
            :param timeout_millis: The amount of time to wait when receiving a response from the health check, in milliseconds.
            :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a virtual gateway unhealthy.
            :param path: The destination path for the health check request. This value is only used if the specified protocol is HTTP or HTTP/2. For any other protocol, this value is ignored.
            :param port: The destination port for the health check request. This port must match the port defined in the ``PortMapping`` for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_health_check_policy_property = appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(
                    healthy_threshold=123,
                    interval_millis=123,
                    protocol="protocol",
                    timeout_millis=123,
                    unhealthy_threshold=123,
                
                    # the properties below are optional
                    path="path",
                    port=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty.__init__)
                check_type(argname="argument healthy_threshold", value=healthy_threshold, expected_type=type_hints["healthy_threshold"])
                check_type(argname="argument interval_millis", value=interval_millis, expected_type=type_hints["interval_millis"])
                check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
                check_type(argname="argument timeout_millis", value=timeout_millis, expected_type=type_hints["timeout_millis"])
                check_type(argname="argument unhealthy_threshold", value=unhealthy_threshold, expected_type=type_hints["unhealthy_threshold"])
                check_type(argname="argument path", value=path, expected_type=type_hints["path"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            self._values: typing.Dict[str, typing.Any] = {
                "healthy_threshold": healthy_threshold,
                "interval_millis": interval_millis,
                "protocol": protocol,
                "timeout_millis": timeout_millis,
                "unhealthy_threshold": unhealthy_threshold,
            }
            if path is not None:
                self._values["path"] = path
            if port is not None:
                self._values["port"] = port

        @builtins.property
        def healthy_threshold(self) -> jsii.Number:
            '''The number of consecutive successful health checks that must occur before declaring the listener healthy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy-healthythreshold
            '''
            result = self._values.get("healthy_threshold")
            assert result is not None, "Required property 'healthy_threshold' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def interval_millis(self) -> jsii.Number:
            '''The time period in milliseconds between each health check execution.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy-intervalmillis
            '''
            result = self._values.get("interval_millis")
            assert result is not None, "Required property 'interval_millis' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def protocol(self) -> builtins.str:
            '''The protocol for the health check request.

            If you specify ``grpc`` , then your service must conform to the `GRPC Health Checking Protocol <https://docs.aws.amazon.com/https://github.com/grpc/grpc/blob/master/doc/health-checking.md>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy-protocol
            '''
            result = self._values.get("protocol")
            assert result is not None, "Required property 'protocol' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def timeout_millis(self) -> jsii.Number:
            '''The amount of time to wait when receiving a response from the health check, in milliseconds.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy-timeoutmillis
            '''
            result = self._values.get("timeout_millis")
            assert result is not None, "Required property 'timeout_millis' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def unhealthy_threshold(self) -> jsii.Number:
            '''The number of consecutive failed health checks that must occur before declaring a virtual gateway unhealthy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy-unhealthythreshold
            '''
            result = self._values.get("unhealthy_threshold")
            assert result is not None, "Required property 'unhealthy_threshold' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def path(self) -> typing.Optional[builtins.str]:
            '''The destination path for the health check request.

            This value is only used if the specified protocol is HTTP or HTTP/2. For any other protocol, this value is ignored.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy-path
            '''
            result = self._values.get("path")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''The destination port for the health check request.

            This port must match the port defined in the ``PortMapping`` for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy.html#cfn-appmesh-virtualgateway-virtualgatewayhealthcheckpolicy-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayHealthCheckPolicyProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={"max_requests": "maxRequests"},
    )
    class VirtualGatewayHttp2ConnectionPoolProperty:
        def __init__(self, *, max_requests: jsii.Number) -> None:
            '''An object that represents a type of connection pool.

            :param max_requests: Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhttp2connectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_http2_connection_pool_property = appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty(
                    max_requests=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty.__init__)
                check_type(argname="argument max_requests", value=max_requests, expected_type=type_hints["max_requests"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_requests": max_requests,
            }

        @builtins.property
        def max_requests(self) -> jsii.Number:
            '''Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhttp2connectionpool.html#cfn-appmesh-virtualgateway-virtualgatewayhttp2connectionpool-maxrequests
            '''
            result = self._values.get("max_requests")
            assert result is not None, "Required property 'max_requests' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayHttp2ConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={
            "max_connections": "maxConnections",
            "max_pending_requests": "maxPendingRequests",
        },
    )
    class VirtualGatewayHttpConnectionPoolProperty:
        def __init__(
            self,
            *,
            max_connections: jsii.Number,
            max_pending_requests: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''An object that represents a type of connection pool.

            :param max_connections: Maximum number of outbound TCP connections Envoy can establish concurrently with all hosts in upstream cluster.
            :param max_pending_requests: Number of overflowing requests after ``max_connections`` Envoy will queue to upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhttpconnectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_http_connection_pool_property = appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty(
                    max_connections=123,
                
                    # the properties below are optional
                    max_pending_requests=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty.__init__)
                check_type(argname="argument max_connections", value=max_connections, expected_type=type_hints["max_connections"])
                check_type(argname="argument max_pending_requests", value=max_pending_requests, expected_type=type_hints["max_pending_requests"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_connections": max_connections,
            }
            if max_pending_requests is not None:
                self._values["max_pending_requests"] = max_pending_requests

        @builtins.property
        def max_connections(self) -> jsii.Number:
            '''Maximum number of outbound TCP connections Envoy can establish concurrently with all hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhttpconnectionpool.html#cfn-appmesh-virtualgateway-virtualgatewayhttpconnectionpool-maxconnections
            '''
            result = self._values.get("max_connections")
            assert result is not None, "Required property 'max_connections' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def max_pending_requests(self) -> typing.Optional[jsii.Number]:
            '''Number of overflowing requests after ``max_connections`` Envoy will queue to upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayhttpconnectionpool.html#cfn-appmesh-virtualgateway-virtualgatewayhttpconnectionpool-maxpendingrequests
            '''
            result = self._values.get("max_pending_requests")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayHttpConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerProperty",
        jsii_struct_bases=[],
        name_mapping={
            "port_mapping": "portMapping",
            "connection_pool": "connectionPool",
            "health_check": "healthCheck",
            "tls": "tls",
        },
    )
    class VirtualGatewayListenerProperty:
        def __init__(
            self,
            *,
            port_mapping: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayPortMappingProperty", typing.Dict[str, typing.Any]]],
            connection_pool: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
            health_check: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty", typing.Dict[str, typing.Any]]]] = None,
            tls: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a listener for a virtual gateway.

            :param port_mapping: The port mapping information for the listener.
            :param connection_pool: The connection pool information for the listener.
            :param health_check: The health check information for the listener.
            :param tls: A reference to an object that represents the Transport Layer Security (TLS) properties for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistener.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerProperty(
                    port_mapping=appmesh.CfnVirtualGateway.VirtualGatewayPortMappingProperty(
                        port=123,
                        protocol="protocol"
                    ),
                
                    # the properties below are optional
                    connection_pool=appmesh.CfnVirtualGateway.VirtualGatewayConnectionPoolProperty(
                        grpc=appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty(
                            max_requests=123
                        ),
                        http=appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty(
                            max_connections=123,
                
                            # the properties below are optional
                            max_pending_requests=123
                        ),
                        http2=appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty(
                            max_requests=123
                        )
                    ),
                    health_check=appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(
                        healthy_threshold=123,
                        interval_millis=123,
                        protocol="protocol",
                        timeout_millis=123,
                        unhealthy_threshold=123,
                
                        # the properties below are optional
                        path="path",
                        port=123
                    ),
                    tls=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsProperty(
                        certificate=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty(
                            acm=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                                certificate_arn="certificateArn"
                            ),
                            file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        mode="mode",
                
                        # the properties below are optional
                        validation=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty(
                            trust=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                                file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
                
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerProperty.__init__)
                check_type(argname="argument port_mapping", value=port_mapping, expected_type=type_hints["port_mapping"])
                check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
                check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
                check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
            self._values: typing.Dict[str, typing.Any] = {
                "port_mapping": port_mapping,
            }
            if connection_pool is not None:
                self._values["connection_pool"] = connection_pool
            if health_check is not None:
                self._values["health_check"] = health_check
            if tls is not None:
                self._values["tls"] = tls

        @builtins.property
        def port_mapping(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayPortMappingProperty"]:
            '''The port mapping information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistener.html#cfn-appmesh-virtualgateway-virtualgatewaylistener-portmapping
            '''
            result = self._values.get("port_mapping")
            assert result is not None, "Required property 'port_mapping' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayPortMappingProperty"], result)

        @builtins.property
        def connection_pool(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayConnectionPoolProperty"]]:
            '''The connection pool information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistener.html#cfn-appmesh-virtualgateway-virtualgatewaylistener-connectionpool
            '''
            result = self._values.get("connection_pool")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayConnectionPoolProperty"]], result)

        @builtins.property
        def health_check(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty"]]:
            '''The health check information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistener.html#cfn-appmesh-virtualgateway-virtualgatewaylistener-healthcheck
            '''
            result = self._values.get("health_check")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty"]], result)

        @builtins.property
        def tls(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsProperty"]]:
            '''A reference to an object that represents the Transport Layer Security (TLS) properties for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistener.html#cfn-appmesh-virtualgateway-virtualgatewaylistener-tls
            '''
            result = self._values.get("tls")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"certificate_arn": "certificateArn"},
    )
    class VirtualGatewayListenerTlsAcmCertificateProperty:
        def __init__(self, *, certificate_arn: builtins.str) -> None:
            '''An object that represents an AWS Certificate Manager certificate.

            :param certificate_arn: The Amazon Resource Name (ARN) for the certificate. The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html#virtual-node-tls-prerequisites>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsacmcertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_tls_acm_certificate_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                    certificate_arn="certificateArn"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty.__init__)
                check_type(argname="argument certificate_arn", value=certificate_arn, expected_type=type_hints["certificate_arn"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_arn": certificate_arn,
            }

        @builtins.property
        def certificate_arn(self) -> builtins.str:
            '''The Amazon Resource Name (ARN) for the certificate.

            The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html#virtual-node-tls-prerequisites>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsacmcertificate.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlsacmcertificate-certificatearn
            '''
            result = self._values.get("certificate_arn")
            assert result is not None, "Required property 'certificate_arn' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerTlsAcmCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"acm": "acm", "file": "file", "sds": "sds"},
    )
    class VirtualGatewayListenerTlsCertificateProperty:
        def __init__(
            self,
            *,
            acm: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a listener's Transport Layer Security (TLS) certificate.

            :param acm: A reference to an object that represents an AWS Certificate Manager certificate.
            :param file: A reference to an object that represents a local file certificate.
            :param sds: A reference to an object that represents a virtual gateway's listener's Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlscertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_tls_certificate_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty(
                    acm=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                        certificate_arn="certificateArn"
                    ),
                    file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                        certificate_chain="certificateChain",
                        private_key="privateKey"
                    ),
                    sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty.__init__)
                check_type(argname="argument acm", value=acm, expected_type=type_hints["acm"])
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if acm is not None:
                self._values["acm"] = acm
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def acm(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty"]]:
            '''A reference to an object that represents an AWS Certificate Manager certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlscertificate.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlscertificate-acm
            '''
            result = self._values.get("acm")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty"]], result)

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty"]]:
            '''A reference to an object that represents a local file certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlscertificate.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlscertificate-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty"]]:
            '''A reference to an object that represents a virtual gateway's listener's Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlscertificate.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlscertificate-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerTlsCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={
            "certificate_chain": "certificateChain",
            "private_key": "privateKey",
        },
    )
    class VirtualGatewayListenerTlsFileCertificateProperty:
        def __init__(
            self,
            *,
            certificate_chain: builtins.str,
            private_key: builtins.str,
        ) -> None:
            '''An object that represents a local file certificate.

            The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html#virtual-node-tls-prerequisites>`_ .

            :param certificate_chain: The certificate chain for the certificate.
            :param private_key: The private key for a certificate stored on the file system of the mesh endpoint that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsfilecertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_tls_file_certificate_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                    certificate_chain="certificateChain",
                    private_key="privateKey"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty.__init__)
                check_type(argname="argument certificate_chain", value=certificate_chain, expected_type=type_hints["certificate_chain"])
                check_type(argname="argument private_key", value=private_key, expected_type=type_hints["private_key"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_chain": certificate_chain,
                "private_key": private_key,
            }

        @builtins.property
        def certificate_chain(self) -> builtins.str:
            '''The certificate chain for the certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsfilecertificate.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlsfilecertificate-certificatechain
            '''
            result = self._values.get("certificate_chain")
            assert result is not None, "Required property 'certificate_chain' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def private_key(self) -> builtins.str:
            '''The private key for a certificate stored on the file system of the mesh endpoint that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsfilecertificate.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlsfilecertificate-privatekey
            '''
            result = self._values.get("private_key")
            assert result is not None, "Required property 'private_key' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerTlsFileCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "certificate": "certificate",
            "mode": "mode",
            "validation": "validation",
        },
    )
    class VirtualGatewayListenerTlsProperty:
        def __init__(
            self,
            *,
            certificate: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty", typing.Dict[str, typing.Any]]],
            mode: builtins.str,
            validation: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the Transport Layer Security (TLS) properties for a listener.

            :param certificate: An object that represents a Transport Layer Security (TLS) certificate.
            :param mode: Specify one of the following modes. - ** STRICT – Listener only accepts connections with TLS enabled. - ** PERMISSIVE – Listener accepts connections with or without TLS enabled. - ** DISABLED – Listener only accepts connections without TLS.
            :param validation: A reference to an object that represents a virtual gateway's listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertls.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_tls_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsProperty(
                    certificate=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty(
                        acm=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                            certificate_arn="certificateArn"
                        ),
                        file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                            certificate_chain="certificateChain",
                            private_key="privateKey"
                        ),
                        sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                            secret_name="secretName"
                        )
                    ),
                    mode="mode",
                
                    # the properties below are optional
                    validation=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty(
                        trust=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                            file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                certificate_chain="certificateChain"
                            ),
                            sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                secret_name="secretName"
                            )
                        ),
                
                        # the properties below are optional
                        subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                            match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                exact=["exact"]
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerTlsProperty.__init__)
                check_type(argname="argument certificate", value=certificate, expected_type=type_hints["certificate"])
                check_type(argname="argument mode", value=mode, expected_type=type_hints["mode"])
                check_type(argname="argument validation", value=validation, expected_type=type_hints["validation"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate": certificate,
                "mode": mode,
            }
            if validation is not None:
                self._values["validation"] = validation

        @builtins.property
        def certificate(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty"]:
            '''An object that represents a Transport Layer Security (TLS) certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertls.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertls-certificate
            '''
            result = self._values.get("certificate")
            assert result is not None, "Required property 'certificate' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty"], result)

        @builtins.property
        def mode(self) -> builtins.str:
            '''Specify one of the following modes.

            - ** STRICT – Listener only accepts connections with TLS enabled.
            - ** PERMISSIVE – Listener accepts connections with or without TLS enabled.
            - ** DISABLED – Listener only accepts connections without TLS.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertls.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertls-mode
            '''
            result = self._values.get("mode")
            assert result is not None, "Required property 'mode' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def validation(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty"]]:
            '''A reference to an object that represents a virtual gateway's listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertls.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertls-validation
            '''
            result = self._values.get("validation")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerTlsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"secret_name": "secretName"},
    )
    class VirtualGatewayListenerTlsSdsCertificateProperty:
        def __init__(self, *, secret_name: builtins.str) -> None:
            '''An object that represents the virtual gateway's listener's Secret Discovery Service certificate.The proxy must be configured with a local SDS provider via a Unix Domain Socket. See App Mesh `TLS documentation <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ for more info.

            :param secret_name: A reference to an object that represents the name of the secret secret requested from the Secret Discovery Service provider representing Transport Layer Security (TLS) materials like a certificate or certificate chain.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlssdscertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_tls_sds_certificate_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                    secret_name="secretName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty.__init__)
                check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
            self._values: typing.Dict[str, typing.Any] = {
                "secret_name": secret_name,
            }

        @builtins.property
        def secret_name(self) -> builtins.str:
            '''A reference to an object that represents the name of the secret secret requested from the Secret Discovery Service provider representing Transport Layer Security (TLS) materials like a certificate or certificate chain.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlssdscertificate.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlssdscertificate-secretname
            '''
            result = self._values.get("secret_name")
            assert result is not None, "Required property 'secret_name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerTlsSdsCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty",
        jsii_struct_bases=[],
        name_mapping={
            "trust": "trust",
            "subject_alternative_names": "subjectAlternativeNames",
        },
    )
    class VirtualGatewayListenerTlsValidationContextProperty:
        def __init__(
            self,
            *,
            trust: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty", typing.Dict[str, typing.Any]]],
            subject_alternative_names: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.SubjectAlternativeNamesProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a virtual gateway's listener's Transport Layer Security (TLS) validation context.

            :param trust: A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.
            :param subject_alternative_names: A reference to an object that represents the SANs for a virtual gateway listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontext.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_tls_validation_context_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty(
                    trust=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                        file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                            certificate_chain="certificateChain"
                        ),
                        sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                            secret_name="secretName"
                        )
                    ),
                
                    # the properties below are optional
                    subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                        match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                            exact=["exact"]
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty.__init__)
                check_type(argname="argument trust", value=trust, expected_type=type_hints["trust"])
                check_type(argname="argument subject_alternative_names", value=subject_alternative_names, expected_type=type_hints["subject_alternative_names"])
            self._values: typing.Dict[str, typing.Any] = {
                "trust": trust,
            }
            if subject_alternative_names is not None:
                self._values["subject_alternative_names"] = subject_alternative_names

        @builtins.property
        def trust(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty"]:
            '''A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontext.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontext-trust
            '''
            result = self._values.get("trust")
            assert result is not None, "Required property 'trust' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty"], result)

        @builtins.property
        def subject_alternative_names(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.SubjectAlternativeNamesProperty"]]:
            '''A reference to an object that represents the SANs for a virtual gateway listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontext.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontext-subjectalternativenames
            '''
            result = self._values.get("subject_alternative_names")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.SubjectAlternativeNamesProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerTlsValidationContextProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"file": "file", "sds": "sds"},
    )
    class VirtualGatewayListenerTlsValidationContextTrustProperty:
        def __init__(
            self,
            *,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a virtual gateway's listener's Transport Layer Security (TLS) validation context trust.

            :param file: An object that represents a Transport Layer Security (TLS) validation context trust for a local file.
            :param sds: A reference to an object that represents a virtual gateway's listener's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontexttrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_listener_tls_validation_context_trust_property = appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                    file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                        certificate_chain="certificateChain"
                    ),
                    sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty.__init__)
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty"]]:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for a local file.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontexttrust.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontexttrust-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty"]]:
            '''A reference to an object that represents a virtual gateway's listener's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontexttrust.html#cfn-appmesh-virtualgateway-virtualgatewaylistenertlsvalidationcontexttrust-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayListenerTlsValidationContextTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayLoggingProperty",
        jsii_struct_bases=[],
        name_mapping={"access_log": "accessLog"},
    )
    class VirtualGatewayLoggingProperty:
        def __init__(
            self,
            *,
            access_log: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayAccessLogProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents logging information.

            :param access_log: The access log configuration.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylogging.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_logging_property = appmesh.CfnVirtualGateway.VirtualGatewayLoggingProperty(
                    access_log=appmesh.CfnVirtualGateway.VirtualGatewayAccessLogProperty(
                        file=appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty(
                            path="path",
                
                            # the properties below are optional
                            format=appmesh.CfnVirtualGateway.LoggingFormatProperty(
                                json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                                    key="key",
                                    value="value"
                                )],
                                text="text"
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayLoggingProperty.__init__)
                check_type(argname="argument access_log", value=access_log, expected_type=type_hints["access_log"])
            self._values: typing.Dict[str, typing.Any] = {}
            if access_log is not None:
                self._values["access_log"] = access_log

        @builtins.property
        def access_log(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayAccessLogProperty"]]:
            '''The access log configuration.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaylogging.html#cfn-appmesh-virtualgateway-virtualgatewaylogging-accesslog
            '''
            result = self._values.get("access_log")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayAccessLogProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayLoggingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayPortMappingProperty",
        jsii_struct_bases=[],
        name_mapping={"port": "port", "protocol": "protocol"},
    )
    class VirtualGatewayPortMappingProperty:
        def __init__(self, *, port: jsii.Number, protocol: builtins.str) -> None:
            '''An object that represents a port mapping.

            :param port: The port used for the port mapping. Specify one protocol.
            :param protocol: The protocol used for the port mapping.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayportmapping.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_port_mapping_property = appmesh.CfnVirtualGateway.VirtualGatewayPortMappingProperty(
                    port=123,
                    protocol="protocol"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayPortMappingProperty.__init__)
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
                check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
            self._values: typing.Dict[str, typing.Any] = {
                "port": port,
                "protocol": protocol,
            }

        @builtins.property
        def port(self) -> jsii.Number:
            '''The port used for the port mapping.

            Specify one protocol.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayportmapping.html#cfn-appmesh-virtualgateway-virtualgatewayportmapping-port
            '''
            result = self._values.get("port")
            assert result is not None, "Required property 'port' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def protocol(self) -> builtins.str:
            '''The protocol used for the port mapping.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayportmapping.html#cfn-appmesh-virtualgateway-virtualgatewayportmapping-protocol
            '''
            result = self._values.get("protocol")
            assert result is not None, "Required property 'protocol' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayPortMappingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewaySpecProperty",
        jsii_struct_bases=[],
        name_mapping={
            "listeners": "listeners",
            "backend_defaults": "backendDefaults",
            "logging": "logging",
        },
    )
    class VirtualGatewaySpecProperty:
        def __init__(
            self,
            *,
            listeners: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayListenerProperty", typing.Dict[str, typing.Any]]]]],
            backend_defaults: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty", typing.Dict[str, typing.Any]]]] = None,
            logging: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayLoggingProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the specification of a service mesh resource.

            :param listeners: The listeners that the mesh endpoint is expected to receive inbound traffic from. You can specify one listener.
            :param backend_defaults: A reference to an object that represents the defaults for backends.
            :param logging: An object that represents logging information.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayspec.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_spec_property = appmesh.CfnVirtualGateway.VirtualGatewaySpecProperty(
                    listeners=[appmesh.CfnVirtualGateway.VirtualGatewayListenerProperty(
                        port_mapping=appmesh.CfnVirtualGateway.VirtualGatewayPortMappingProperty(
                            port=123,
                            protocol="protocol"
                        ),
                
                        # the properties below are optional
                        connection_pool=appmesh.CfnVirtualGateway.VirtualGatewayConnectionPoolProperty(
                            grpc=appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty(
                                max_requests=123
                            ),
                            http=appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty(
                                max_connections=123,
                
                                # the properties below are optional
                                max_pending_requests=123
                            ),
                            http2=appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty(
                                max_requests=123
                            )
                        ),
                        health_check=appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(
                            healthy_threshold=123,
                            interval_millis=123,
                            protocol="protocol",
                            timeout_millis=123,
                            unhealthy_threshold=123,
                
                            # the properties below are optional
                            path="path",
                            port=123
                        ),
                        tls=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsProperty(
                            certificate=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty(
                                acm=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                                    certificate_arn="certificateArn"
                                ),
                                file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            mode="mode",
                
                            # the properties below are optional
                            validation=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty(
                                trust=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                                    file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
                
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            )
                        )
                    )],
                
                    # the properties below are optional
                    backend_defaults=appmesh.CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty(
                        client_policy=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyProperty(
                            tls=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty(
                                validation=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty(
                                    trust=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                                        acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                                            certificate_authority_arns=["certificateAuthorityArns"]
                                        ),
                                        file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                            certificate_chain="certificateChain"
                                        ),
                                        sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                            secret_name="secretName"
                                        )
                                    ),
                
                                    # the properties below are optional
                                    subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                        match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                            exact=["exact"]
                                        )
                                    )
                                ),
                
                                # the properties below are optional
                                certificate=appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty(
                                    file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                        certificate_chain="certificateChain",
                                        private_key="privateKey"
                                    ),
                                    sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                        secret_name="secretName"
                                    )
                                ),
                                enforce=False,
                                ports=[123]
                            )
                        )
                    ),
                    logging=appmesh.CfnVirtualGateway.VirtualGatewayLoggingProperty(
                        access_log=appmesh.CfnVirtualGateway.VirtualGatewayAccessLogProperty(
                            file=appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty(
                                path="path",
                
                                # the properties below are optional
                                format=appmesh.CfnVirtualGateway.LoggingFormatProperty(
                                    json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                                        key="key",
                                        value="value"
                                    )],
                                    text="text"
                                )
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewaySpecProperty.__init__)
                check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
                check_type(argname="argument backend_defaults", value=backend_defaults, expected_type=type_hints["backend_defaults"])
                check_type(argname="argument logging", value=logging, expected_type=type_hints["logging"])
            self._values: typing.Dict[str, typing.Any] = {
                "listeners": listeners,
            }
            if backend_defaults is not None:
                self._values["backend_defaults"] = backend_defaults
            if logging is not None:
                self._values["logging"] = logging

        @builtins.property
        def listeners(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerProperty"]]]:
            '''The listeners that the mesh endpoint is expected to receive inbound traffic from.

            You can specify one listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayspec.html#cfn-appmesh-virtualgateway-virtualgatewayspec-listeners
            '''
            result = self._values.get("listeners")
            assert result is not None, "Required property 'listeners' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayListenerProperty"]]], result)

        @builtins.property
        def backend_defaults(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty"]]:
            '''A reference to an object that represents the defaults for backends.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayspec.html#cfn-appmesh-virtualgateway-virtualgatewayspec-backenddefaults
            '''
            result = self._values.get("backend_defaults")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty"]], result)

        @builtins.property
        def logging(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayLoggingProperty"]]:
            '''An object that represents logging information.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewayspec.html#cfn-appmesh-virtualgateway-virtualgatewayspec-logging
            '''
            result = self._values.get("logging")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayLoggingProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewaySpecProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"certificate_authority_arns": "certificateAuthorityArns"},
    )
    class VirtualGatewayTlsValidationContextAcmTrustProperty:
        def __init__(
            self,
            *,
            certificate_authority_arns: typing.Sequence[builtins.str],
        ) -> None:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for an AWS Certificate Manager certificate.

            :param certificate_authority_arns: One or more ACM Amazon Resource Name (ARN)s.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextacmtrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_tls_validation_context_acm_trust_property = appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                    certificate_authority_arns=["certificateAuthorityArns"]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty.__init__)
                check_type(argname="argument certificate_authority_arns", value=certificate_authority_arns, expected_type=type_hints["certificate_authority_arns"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_authority_arns": certificate_authority_arns,
            }

        @builtins.property
        def certificate_authority_arns(self) -> typing.List[builtins.str]:
            '''One or more ACM Amazon Resource Name (ARN)s.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextacmtrust.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextacmtrust-certificateauthorityarns
            '''
            result = self._values.get("certificate_authority_arns")
            assert result is not None, "Required property 'certificate_authority_arns' is missing"
            return typing.cast(typing.List[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayTlsValidationContextAcmTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"certificate_chain": "certificateChain"},
    )
    class VirtualGatewayTlsValidationContextFileTrustProperty:
        def __init__(self, *, certificate_chain: builtins.str) -> None:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for a local file.

            :param certificate_chain: The certificate trust chain for a certificate stored on the file system of the virtual node that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextfiletrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_tls_validation_context_file_trust_property = appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                    certificate_chain="certificateChain"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty.__init__)
                check_type(argname="argument certificate_chain", value=certificate_chain, expected_type=type_hints["certificate_chain"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_chain": certificate_chain,
            }

        @builtins.property
        def certificate_chain(self) -> builtins.str:
            '''The certificate trust chain for a certificate stored on the file system of the virtual node that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextfiletrust.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextfiletrust-certificatechain
            '''
            result = self._values.get("certificate_chain")
            assert result is not None, "Required property 'certificate_chain' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayTlsValidationContextFileTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty",
        jsii_struct_bases=[],
        name_mapping={
            "trust": "trust",
            "subject_alternative_names": "subjectAlternativeNames",
        },
    )
    class VirtualGatewayTlsValidationContextProperty:
        def __init__(
            self,
            *,
            trust: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty", typing.Dict[str, typing.Any]]],
            subject_alternative_names: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.SubjectAlternativeNamesProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a Transport Layer Security (TLS) validation context.

            :param trust: A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.
            :param subject_alternative_names: A reference to an object that represents the SANs for a virtual gateway's listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontext.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_tls_validation_context_property = appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty(
                    trust=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                        acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                            certificate_authority_arns=["certificateAuthorityArns"]
                        ),
                        file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                            certificate_chain="certificateChain"
                        ),
                        sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                            secret_name="secretName"
                        )
                    ),
                
                    # the properties below are optional
                    subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                        match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                            exact=["exact"]
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty.__init__)
                check_type(argname="argument trust", value=trust, expected_type=type_hints["trust"])
                check_type(argname="argument subject_alternative_names", value=subject_alternative_names, expected_type=type_hints["subject_alternative_names"])
            self._values: typing.Dict[str, typing.Any] = {
                "trust": trust,
            }
            if subject_alternative_names is not None:
                self._values["subject_alternative_names"] = subject_alternative_names

        @builtins.property
        def trust(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty"]:
            '''A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontext.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontext-trust
            '''
            result = self._values.get("trust")
            assert result is not None, "Required property 'trust' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty"], result)

        @builtins.property
        def subject_alternative_names(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.SubjectAlternativeNamesProperty"]]:
            '''A reference to an object that represents the SANs for a virtual gateway's listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontext.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontext-subjectalternativenames
            '''
            result = self._values.get("subject_alternative_names")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.SubjectAlternativeNamesProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayTlsValidationContextProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"secret_name": "secretName"},
    )
    class VirtualGatewayTlsValidationContextSdsTrustProperty:
        def __init__(self, *, secret_name: builtins.str) -> None:
            '''An object that represents a virtual gateway's listener's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            The proxy must be configured with a local SDS provider via a Unix Domain Socket. See App Mesh `TLS documentation <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ for more info.

            :param secret_name: A reference to an object that represents the name of the secret for a virtual gateway's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextsdstrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_tls_validation_context_sds_trust_property = appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                    secret_name="secretName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty.__init__)
                check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
            self._values: typing.Dict[str, typing.Any] = {
                "secret_name": secret_name,
            }

        @builtins.property
        def secret_name(self) -> builtins.str:
            '''A reference to an object that represents the name of the secret for a virtual gateway's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextsdstrust.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontextsdstrust-secretname
            '''
            result = self._values.get("secret_name")
            assert result is not None, "Required property 'secret_name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayTlsValidationContextSdsTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"acm": "acm", "file": "file", "sds": "sds"},
    )
    class VirtualGatewayTlsValidationContextTrustProperty:
        def __init__(
            self,
            *,
            acm: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty", typing.Dict[str, typing.Any]]]] = None,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a Transport Layer Security (TLS) validation context trust.

            :param acm: A reference to an object that represents a Transport Layer Security (TLS) validation context trust for an AWS Certificate Manager certificate.
            :param file: An object that represents a Transport Layer Security (TLS) validation context trust for a local file.
            :param sds: A reference to an object that represents a virtual gateway's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontexttrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_gateway_tls_validation_context_trust_property = appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                    acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                        certificate_authority_arns=["certificateAuthorityArns"]
                    ),
                    file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                        certificate_chain="certificateChain"
                    ),
                    sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty.__init__)
                check_type(argname="argument acm", value=acm, expected_type=type_hints["acm"])
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if acm is not None:
                self._values["acm"] = acm
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def acm(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty"]]:
            '''A reference to an object that represents a Transport Layer Security (TLS) validation context trust for an AWS Certificate Manager certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontexttrust.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontexttrust-acm
            '''
            result = self._values.get("acm")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty"]], result)

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty"]]:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for a local file.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontexttrust.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontexttrust-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty"]]:
            '''A reference to an object that represents a virtual gateway's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualgateway-virtualgatewaytlsvalidationcontexttrust.html#cfn-appmesh-virtualgateway-virtualgatewaytlsvalidationcontexttrust-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualGatewayTlsValidationContextTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualGatewayProps",
    jsii_struct_bases=[],
    name_mapping={
        "mesh_name": "meshName",
        "spec": "spec",
        "mesh_owner": "meshOwner",
        "tags": "tags",
        "virtual_gateway_name": "virtualGatewayName",
    },
)
class CfnVirtualGatewayProps:
    def __init__(
        self,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union[CfnVirtualGateway.VirtualGatewaySpecProperty, typing.Dict[str, typing.Any]]],
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``CfnVirtualGateway``.

        :param mesh_name: The name of the service mesh that the virtual gateway resides in.
        :param spec: The specifications of the virtual gateway.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual gateway to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        :param virtual_gateway_name: The name of the virtual gateway.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html
        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            cfn_virtual_gateway_props = appmesh.CfnVirtualGatewayProps(
                mesh_name="meshName",
                spec=appmesh.CfnVirtualGateway.VirtualGatewaySpecProperty(
                    listeners=[appmesh.CfnVirtualGateway.VirtualGatewayListenerProperty(
                        port_mapping=appmesh.CfnVirtualGateway.VirtualGatewayPortMappingProperty(
                            port=123,
                            protocol="protocol"
                        ),
            
                        # the properties below are optional
                        connection_pool=appmesh.CfnVirtualGateway.VirtualGatewayConnectionPoolProperty(
                            grpc=appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty(
                                max_requests=123
                            ),
                            http=appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty(
                                max_connections=123,
            
                                # the properties below are optional
                                max_pending_requests=123
                            ),
                            http2=appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty(
                                max_requests=123
                            )
                        ),
                        health_check=appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(
                            healthy_threshold=123,
                            interval_millis=123,
                            protocol="protocol",
                            timeout_millis=123,
                            unhealthy_threshold=123,
            
                            # the properties below are optional
                            path="path",
                            port=123
                        ),
                        tls=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsProperty(
                            certificate=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty(
                                acm=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                                    certificate_arn="certificateArn"
                                ),
                                file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            mode="mode",
            
                            # the properties below are optional
                            validation=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty(
                                trust=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                                    file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
            
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            )
                        )
                    )],
            
                    # the properties below are optional
                    backend_defaults=appmesh.CfnVirtualGateway.VirtualGatewayBackendDefaultsProperty(
                        client_policy=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyProperty(
                            tls=appmesh.CfnVirtualGateway.VirtualGatewayClientPolicyTlsProperty(
                                validation=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextProperty(
                                    trust=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextTrustProperty(
                                        acm=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextAcmTrustProperty(
                                            certificate_authority_arns=["certificateAuthorityArns"]
                                        ),
                                        file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                            certificate_chain="certificateChain"
                                        ),
                                        sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                            secret_name="secretName"
                                        )
                                    ),
            
                                    # the properties below are optional
                                    subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                        match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                            exact=["exact"]
                                        )
                                    )
                                ),
            
                                # the properties below are optional
                                certificate=appmesh.CfnVirtualGateway.VirtualGatewayClientTlsCertificateProperty(
                                    file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                        certificate_chain="certificateChain",
                                        private_key="privateKey"
                                    ),
                                    sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                        secret_name="secretName"
                                    )
                                ),
                                enforce=False,
                                ports=[123]
                            )
                        )
                    ),
                    logging=appmesh.CfnVirtualGateway.VirtualGatewayLoggingProperty(
                        access_log=appmesh.CfnVirtualGateway.VirtualGatewayAccessLogProperty(
                            file=appmesh.CfnVirtualGateway.VirtualGatewayFileAccessLogProperty(
                                path="path",
            
                                # the properties below are optional
                                format=appmesh.CfnVirtualGateway.LoggingFormatProperty(
                                    json=[appmesh.CfnVirtualGateway.JsonFormatRefProperty(
                                        key="key",
                                        value="value"
                                    )],
                                    text="text"
                                )
                            )
                        )
                    )
                ),
            
                # the properties below are optional
                mesh_owner="meshOwner",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )],
                virtual_gateway_name="virtualGatewayName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualGatewayProps.__init__)
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument mesh_owner", value=mesh_owner, expected_type=type_hints["mesh_owner"])
            check_type(argname="argument tags", value=tags, expected_type=type_hints["tags"])
            check_type(argname="argument virtual_gateway_name", value=virtual_gateway_name, expected_type=type_hints["virtual_gateway_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh_name": mesh_name,
            "spec": spec,
        }
        if mesh_owner is not None:
            self._values["mesh_owner"] = mesh_owner
        if tags is not None:
            self._values["tags"] = tags
        if virtual_gateway_name is not None:
            self._values["virtual_gateway_name"] = virtual_gateway_name

    @builtins.property
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the virtual gateway resides in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-meshname
        '''
        result = self._values.get("mesh_name")
        assert result is not None, "Required property 'mesh_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnVirtualGateway.VirtualGatewaySpecProperty]:
        '''The specifications of the virtual gateway.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnVirtualGateway.VirtualGatewaySpecProperty], result)

    @builtins.property
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-meshowner
        '''
        result = self._values.get("mesh_owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''Optional metadata that you can apply to the virtual gateway to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def virtual_gateway_name(self) -> typing.Optional[builtins.str]:
        '''The name of the virtual gateway.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualgateway.html#cfn-appmesh-virtualgateway-virtualgatewayname
        '''
        result = self._values.get("virtual_gateway_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVirtualGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVirtualNode(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode",
):
    '''A CloudFormation ``AWS::AppMesh::VirtualNode``.

    Creates a virtual node within a service mesh.

    A virtual node acts as a logical pointer to a particular task group, such as an Amazon ECS service or a Kubernetes deployment. When you create a virtual node, you can specify the service discovery information for your task group, and whether the proxy running in a task group will communicate with other proxies using Transport Layer Security (TLS).

    You define a ``listener`` for any inbound traffic that your virtual node expects. Any virtual service that your virtual node expects to communicate to is specified as a ``backend`` .

    The response metadata for your new virtual node contains the ``arn`` that is associated with the virtual node. Set this value to the full ARN; for example, ``arn:aws:appmesh:us-west-2:123456789012:myMesh/default/virtualNode/myApp`` ) as the ``APPMESH_RESOURCE_ARN`` environment variable for your task group's Envoy proxy container in your task definition or pod spec. This is then mapped to the ``node.id`` and ``node.cluster`` Envoy parameters.
    .. epigraph::

       By default, App Mesh uses the name of the resource you specified in ``APPMESH_RESOURCE_ARN`` when Envoy is referring to itself in metrics and traces. You can override this behavior by setting the ``APPMESH_RESOURCE_CLUSTER`` environment variable with your own name.

    For more information about virtual nodes, see `Virtual nodes <https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_nodes.html>`_ . You must be using ``1.15.0`` or later of the Envoy image when setting these variables. For more information about App Mesh Envoy variables, see `Envoy image <https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html>`_ in the AWS App Mesh User Guide.

    :cloudformationResource: AWS::AppMesh::VirtualNode
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        cfn_virtual_node = appmesh.CfnVirtualNode(self, "MyCfnVirtualNode",
            mesh_name="meshName",
            spec=appmesh.CfnVirtualNode.VirtualNodeSpecProperty(
                backend_defaults=appmesh.CfnVirtualNode.BackendDefaultsProperty(
                    client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                        tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                            validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                    acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                        certificate_authority_arns=["certificateAuthorityArns"]
                                    ),
                                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
        
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            ),
        
                            # the properties below are optional
                            certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            enforce=False,
                            ports=[123]
                        )
                    )
                ),
                backends=[appmesh.CfnVirtualNode.BackendProperty(
                    virtual_service=appmesh.CfnVirtualNode.VirtualServiceBackendProperty(
                        virtual_service_name="virtualServiceName",
        
                        # the properties below are optional
                        client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                            tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                                validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                    trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                        acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                            certificate_authority_arns=["certificateAuthorityArns"]
                                        ),
                                        file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                            certificate_chain="certificateChain"
                                        ),
                                        sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                            secret_name="secretName"
                                        )
                                    ),
        
                                    # the properties below are optional
                                    subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                        match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                            exact=["exact"]
                                        )
                                    )
                                ),
        
                                # the properties below are optional
                                certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                        certificate_chain="certificateChain",
                                        private_key="privateKey"
                                    ),
                                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                        secret_name="secretName"
                                    )
                                ),
                                enforce=False,
                                ports=[123]
                            )
                        )
                    )
                )],
                listeners=[appmesh.CfnVirtualNode.ListenerProperty(
                    port_mapping=appmesh.CfnVirtualNode.PortMappingProperty(
                        port=123,
                        protocol="protocol"
                    ),
        
                    # the properties below are optional
                    connection_pool=appmesh.CfnVirtualNode.VirtualNodeConnectionPoolProperty(
                        grpc=appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty(
                            max_requests=123
                        ),
                        http=appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty(
                            max_connections=123,
        
                            # the properties below are optional
                            max_pending_requests=123
                        ),
                        http2=appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty(
                            max_requests=123
                        ),
                        tcp=appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty(
                            max_connections=123
                        )
                    ),
                    health_check=appmesh.CfnVirtualNode.HealthCheckProperty(
                        healthy_threshold=123,
                        interval_millis=123,
                        protocol="protocol",
                        timeout_millis=123,
                        unhealthy_threshold=123,
        
                        # the properties below are optional
                        path="path",
                        port=123
                    ),
                    outlier_detection=appmesh.CfnVirtualNode.OutlierDetectionProperty(
                        base_ejection_duration=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        interval=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        max_ejection_percent=123,
                        max_server_errors=123
                    ),
                    timeout=appmesh.CfnVirtualNode.ListenerTimeoutProperty(
                        grpc=appmesh.CfnVirtualNode.GrpcTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        http=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        http2=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        tcp=appmesh.CfnVirtualNode.TcpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    tls=appmesh.CfnVirtualNode.ListenerTlsProperty(
                        certificate=appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                            acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                                certificate_arn="certificateArn"
                            ),
                            file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        mode="mode",
        
                        # the properties below are optional
                        validation=appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty(
                            trust=appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                                file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
        
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        )
                    )
                )],
                logging=appmesh.CfnVirtualNode.LoggingProperty(
                    access_log=appmesh.CfnVirtualNode.AccessLogProperty(
                        file=appmesh.CfnVirtualNode.FileAccessLogProperty(
                            path="path",
        
                            # the properties below are optional
                            format=appmesh.CfnVirtualNode.LoggingFormatProperty(
                                json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                                    key="key",
                                    value="value"
                                )],
                                text="text"
                            )
                        )
                    )
                ),
                service_discovery=appmesh.CfnVirtualNode.ServiceDiscoveryProperty(
                    aws_cloud_map=appmesh.CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty(
                        namespace_name="namespaceName",
                        service_name="serviceName",
        
                        # the properties below are optional
                        attributes=[appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty(
                            key="key",
                            value="value"
                        )],
                        ip_preference="ipPreference"
                    ),
                    dns=appmesh.CfnVirtualNode.DnsServiceDiscoveryProperty(
                        hostname="hostname",
        
                        # the properties below are optional
                        ip_preference="ipPreference",
                        response_type="responseType"
                    )
                )
            ),
        
            # the properties below are optional
            mesh_owner="meshOwner",
            tags=[CfnTag(
                key="key",
                value="value"
            )],
            virtual_node_name="virtualNodeName"
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.VirtualNodeSpecProperty", typing.Dict[str, typing.Any]]],
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::AppMesh::VirtualNode``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param mesh_name: The name of the service mesh to create the virtual node in.
        :param spec: The virtual node specification to apply.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual node to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        :param virtual_node_name: The name to use for the virtual node.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualNode.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = CfnVirtualNodeProps(
            mesh_name=mesh_name,
            spec=spec,
            mesh_owner=mesh_owner,
            tags=tags,
            virtual_node_name=virtual_node_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualNode.inspect)
            check_type(argname="argument inspector", value=inspector, expected_type=type_hints["inspector"])
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualNode._render_properties)
            check_type(argname="argument props", value=props, expected_type=type_hints["props"])
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''The full Amazon Resource Name (ARN) for the virtual node.

        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshName")
    def attr_mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the virtual node resides in.

        :cloudformationAttribute: MeshName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshOwner")
    def attr_mesh_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: MeshOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrResourceOwner")
    def attr_resource_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the resource owner.

        If the account ID is not your own, then it's the ID of the mesh owner or of another account that the mesh is shared with. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: ResourceOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrUid")
    def attr_uid(self) -> builtins.str:
        '''The unique identifier for the virtual node.

        :cloudformationAttribute: Uid
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrUid"))

    @builtins.property
    @jsii.member(jsii_name="attrVirtualNodeName")
    def attr_virtual_node_name(self) -> builtins.str:
        '''The name of the virtual node.

        :cloudformationAttribute: VirtualNodeName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVirtualNodeName"))

    @builtins.property
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''Optional metadata that you can apply to the virtual node to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the virtual node in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-meshname
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))

    @mesh_name.setter
    def mesh_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualNode, "mesh_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshName", value)

    @builtins.property
    @jsii.member(jsii_name="spec")
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeSpecProperty"]:
        '''The virtual node specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-spec
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeSpecProperty"], jsii.get(self, "spec"))

    @spec.setter
    def spec(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeSpecProperty"],
    ) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualNode, "spec").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "spec", value)

    @builtins.property
    @jsii.member(jsii_name="meshOwner")
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-meshowner
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "meshOwner"))

    @mesh_owner.setter
    def mesh_owner(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualNode, "mesh_owner").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshOwner", value)

    @builtins.property
    @jsii.member(jsii_name="virtualNodeName")
    def virtual_node_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the virtual node.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-virtualnodename
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "virtualNodeName"))

    @virtual_node_name.setter
    def virtual_node_name(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualNode, "virtual_node_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "virtualNodeName", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.AccessLogProperty",
        jsii_struct_bases=[],
        name_mapping={"file": "file"},
    )
    class AccessLogProperty:
        def __init__(
            self,
            *,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.FileAccessLogProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the access logging information for a virtual node.

            :param file: The file object to send virtual node access logs to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-accesslog.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                access_log_property = appmesh.CfnVirtualNode.AccessLogProperty(
                    file=appmesh.CfnVirtualNode.FileAccessLogProperty(
                        path="path",
                
                        # the properties below are optional
                        format=appmesh.CfnVirtualNode.LoggingFormatProperty(
                            json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                                key="key",
                                value="value"
                            )],
                            text="text"
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.AccessLogProperty.__init__)
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
            self._values: typing.Dict[str, typing.Any] = {}
            if file is not None:
                self._values["file"] = file

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.FileAccessLogProperty"]]:
            '''The file object to send virtual node access logs to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-accesslog.html#cfn-appmesh-virtualnode-accesslog-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.FileAccessLogProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AccessLogProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty",
        jsii_struct_bases=[],
        name_mapping={"key": "key", "value": "value"},
    )
    class AwsCloudMapInstanceAttributeProperty:
        def __init__(self, *, key: builtins.str, value: builtins.str) -> None:
            '''An object that represents the AWS Cloud Map attribute information for your virtual node.

            .. epigraph::

               AWS Cloud Map is not available in the eu-south-1 Region.

            :param key: The name of an AWS Cloud Map service instance attribute key. Any AWS Cloud Map service instance that contains the specified key and value is returned.
            :param value: The value of an AWS Cloud Map service instance attribute key. Any AWS Cloud Map service instance that contains the specified key and value is returned.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapinstanceattribute.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                aws_cloud_map_instance_attribute_property = appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty(
                    key="key",
                    value="value"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.AwsCloudMapInstanceAttributeProperty.__init__)
                check_type(argname="argument key", value=key, expected_type=type_hints["key"])
                check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            self._values: typing.Dict[str, typing.Any] = {
                "key": key,
                "value": value,
            }

        @builtins.property
        def key(self) -> builtins.str:
            '''The name of an AWS Cloud Map service instance attribute key.

            Any AWS Cloud Map service instance that contains the specified key and value is returned.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapinstanceattribute.html#cfn-appmesh-virtualnode-awscloudmapinstanceattribute-key
            '''
            result = self._values.get("key")
            assert result is not None, "Required property 'key' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def value(self) -> builtins.str:
            '''The value of an AWS Cloud Map service instance attribute key.

            Any AWS Cloud Map service instance that contains the specified key and value is returned.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapinstanceattribute.html#cfn-appmesh-virtualnode-awscloudmapinstanceattribute-value
            '''
            result = self._values.get("value")
            assert result is not None, "Required property 'value' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AwsCloudMapInstanceAttributeProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty",
        jsii_struct_bases=[],
        name_mapping={
            "namespace_name": "namespaceName",
            "service_name": "serviceName",
            "attributes": "attributes",
            "ip_preference": "ipPreference",
        },
    )
    class AwsCloudMapServiceDiscoveryProperty:
        def __init__(
            self,
            *,
            namespace_name: builtins.str,
            service_name: builtins.str,
            attributes: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.AwsCloudMapInstanceAttributeProperty", typing.Dict[str, typing.Any]]]]]] = None,
            ip_preference: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the AWS Cloud Map service discovery information for your virtual node.

            .. epigraph::

               AWS Cloud Map is not available in the eu-south-1 Region.

            :param namespace_name: The name of the AWS Cloud Map namespace to use.
            :param service_name: The name of the AWS Cloud Map service to use.
            :param attributes: A string map that contains attributes with values that you can use to filter instances by any custom attribute that you specified when you registered the instance. Only instances that match all of the specified key/value pairs will be returned.
            :param ip_preference: The preferred IP version that this virtual node uses. Setting the IP preference on the virtual node only overrides the IP preference set for the mesh on this specific node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapservicediscovery.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                aws_cloud_map_service_discovery_property = appmesh.CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty(
                    namespace_name="namespaceName",
                    service_name="serviceName",
                
                    # the properties below are optional
                    attributes=[appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty(
                        key="key",
                        value="value"
                    )],
                    ip_preference="ipPreference"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty.__init__)
                check_type(argname="argument namespace_name", value=namespace_name, expected_type=type_hints["namespace_name"])
                check_type(argname="argument service_name", value=service_name, expected_type=type_hints["service_name"])
                check_type(argname="argument attributes", value=attributes, expected_type=type_hints["attributes"])
                check_type(argname="argument ip_preference", value=ip_preference, expected_type=type_hints["ip_preference"])
            self._values: typing.Dict[str, typing.Any] = {
                "namespace_name": namespace_name,
                "service_name": service_name,
            }
            if attributes is not None:
                self._values["attributes"] = attributes
            if ip_preference is not None:
                self._values["ip_preference"] = ip_preference

        @builtins.property
        def namespace_name(self) -> builtins.str:
            '''The name of the AWS Cloud Map namespace to use.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapservicediscovery.html#cfn-appmesh-virtualnode-awscloudmapservicediscovery-namespacename
            '''
            result = self._values.get("namespace_name")
            assert result is not None, "Required property 'namespace_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def service_name(self) -> builtins.str:
            '''The name of the AWS Cloud Map service to use.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapservicediscovery.html#cfn-appmesh-virtualnode-awscloudmapservicediscovery-servicename
            '''
            result = self._values.get("service_name")
            assert result is not None, "Required property 'service_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def attributes(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.AwsCloudMapInstanceAttributeProperty"]]]]:
            '''A string map that contains attributes with values that you can use to filter instances by any custom attribute that you specified when you registered the instance.

            Only instances that match all of the specified key/value pairs will be returned.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapservicediscovery.html#cfn-appmesh-virtualnode-awscloudmapservicediscovery-attributes
            '''
            result = self._values.get("attributes")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.AwsCloudMapInstanceAttributeProperty"]]]], result)

        @builtins.property
        def ip_preference(self) -> typing.Optional[builtins.str]:
            '''The preferred IP version that this virtual node uses.

            Setting the IP preference on the virtual node only overrides the IP preference set for the mesh on this specific node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-awscloudmapservicediscovery.html#cfn-appmesh-virtualnode-awscloudmapservicediscovery-ippreference
            '''
            result = self._values.get("ip_preference")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AwsCloudMapServiceDiscoveryProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.BackendDefaultsProperty",
        jsii_struct_bases=[],
        name_mapping={"client_policy": "clientPolicy"},
    )
    class BackendDefaultsProperty:
        def __init__(
            self,
            *,
            client_policy: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ClientPolicyProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the default properties for a backend.

            :param client_policy: A reference to an object that represents a client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-backenddefaults.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                backend_defaults_property = appmesh.CfnVirtualNode.BackendDefaultsProperty(
                    client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                        tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                            validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                    acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                        certificate_authority_arns=["certificateAuthorityArns"]
                                    ),
                                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
                
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            ),
                
                            # the properties below are optional
                            certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            enforce=False,
                            ports=[123]
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.BackendDefaultsProperty.__init__)
                check_type(argname="argument client_policy", value=client_policy, expected_type=type_hints["client_policy"])
            self._values: typing.Dict[str, typing.Any] = {}
            if client_policy is not None:
                self._values["client_policy"] = client_policy

        @builtins.property
        def client_policy(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientPolicyProperty"]]:
            '''A reference to an object that represents a client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-backenddefaults.html#cfn-appmesh-virtualnode-backenddefaults-clientpolicy
            '''
            result = self._values.get("client_policy")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientPolicyProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "BackendDefaultsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.BackendProperty",
        jsii_struct_bases=[],
        name_mapping={"virtual_service": "virtualService"},
    )
    class BackendProperty:
        def __init__(
            self,
            *,
            virtual_service: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.VirtualServiceBackendProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the backends that a virtual node is expected to send outbound traffic to.

            :param virtual_service: Specifies a virtual service to use as a backend.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-backend.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                backend_property = appmesh.CfnVirtualNode.BackendProperty(
                    virtual_service=appmesh.CfnVirtualNode.VirtualServiceBackendProperty(
                        virtual_service_name="virtualServiceName",
                
                        # the properties below are optional
                        client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                            tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                                validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                    trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                        acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                            certificate_authority_arns=["certificateAuthorityArns"]
                                        ),
                                        file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                            certificate_chain="certificateChain"
                                        ),
                                        sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                            secret_name="secretName"
                                        )
                                    ),
                
                                    # the properties below are optional
                                    subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                        match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                            exact=["exact"]
                                        )
                                    )
                                ),
                
                                # the properties below are optional
                                certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                        certificate_chain="certificateChain",
                                        private_key="privateKey"
                                    ),
                                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                        secret_name="secretName"
                                    )
                                ),
                                enforce=False,
                                ports=[123]
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.BackendProperty.__init__)
                check_type(argname="argument virtual_service", value=virtual_service, expected_type=type_hints["virtual_service"])
            self._values: typing.Dict[str, typing.Any] = {}
            if virtual_service is not None:
                self._values["virtual_service"] = virtual_service

        @builtins.property
        def virtual_service(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualServiceBackendProperty"]]:
            '''Specifies a virtual service to use as a backend.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-backend.html#cfn-appmesh-virtualnode-backend-virtualservice
            '''
            result = self._values.get("virtual_service")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualServiceBackendProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "BackendProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ClientPolicyProperty",
        jsii_struct_bases=[],
        name_mapping={"tls": "tls"},
    )
    class ClientPolicyProperty:
        def __init__(
            self,
            *,
            tls: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ClientPolicyTlsProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a client policy.

            :param tls: A reference to an object that represents a Transport Layer Security (TLS) client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clientpolicy.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                client_policy_property = appmesh.CfnVirtualNode.ClientPolicyProperty(
                    tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                        validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                            trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                    certificate_authority_arns=["certificateAuthorityArns"]
                                ),
                                file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
                
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        ),
                
                        # the properties below are optional
                        certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                            file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        enforce=False,
                        ports=[123]
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ClientPolicyProperty.__init__)
                check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
            self._values: typing.Dict[str, typing.Any] = {}
            if tls is not None:
                self._values["tls"] = tls

        @builtins.property
        def tls(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientPolicyTlsProperty"]]:
            '''A reference to an object that represents a Transport Layer Security (TLS) client policy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clientpolicy.html#cfn-appmesh-virtualnode-clientpolicy-tls
            '''
            result = self._values.get("tls")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientPolicyTlsProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ClientPolicyProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ClientPolicyTlsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "validation": "validation",
            "certificate": "certificate",
            "enforce": "enforce",
            "ports": "ports",
        },
    )
    class ClientPolicyTlsProperty:
        def __init__(
            self,
            *,
            validation: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TlsValidationContextProperty", typing.Dict[str, typing.Any]]],
            certificate: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ClientTlsCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            enforce: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            ports: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[jsii.Number]]] = None,
        ) -> None:
            '''A reference to an object that represents a Transport Layer Security (TLS) client policy.

            :param validation: A reference to an object that represents a TLS validation context.
            :param certificate: A reference to an object that represents a client's TLS certificate.
            :param enforce: Whether the policy is enforced. The default is ``True`` , if a value isn't specified.
            :param ports: One or more ports that the policy is enforced for.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clientpolicytls.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                client_policy_tls_property = appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                    validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                        trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                            acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                certificate_authority_arns=["certificateAuthorityArns"]
                            ),
                            file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                certificate_chain="certificateChain"
                            ),
                            sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                secret_name="secretName"
                            )
                        ),
                
                        # the properties below are optional
                        subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                            match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                exact=["exact"]
                            )
                        )
                    ),
                
                    # the properties below are optional
                    certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                        file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                            certificate_chain="certificateChain",
                            private_key="privateKey"
                        ),
                        sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                            secret_name="secretName"
                        )
                    ),
                    enforce=False,
                    ports=[123]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ClientPolicyTlsProperty.__init__)
                check_type(argname="argument validation", value=validation, expected_type=type_hints["validation"])
                check_type(argname="argument certificate", value=certificate, expected_type=type_hints["certificate"])
                check_type(argname="argument enforce", value=enforce, expected_type=type_hints["enforce"])
                check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
            self._values: typing.Dict[str, typing.Any] = {
                "validation": validation,
            }
            if certificate is not None:
                self._values["certificate"] = certificate
            if enforce is not None:
                self._values["enforce"] = enforce
            if ports is not None:
                self._values["ports"] = ports

        @builtins.property
        def validation(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextProperty"]:
            '''A reference to an object that represents a TLS validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clientpolicytls.html#cfn-appmesh-virtualnode-clientpolicytls-validation
            '''
            result = self._values.get("validation")
            assert result is not None, "Required property 'validation' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextProperty"], result)

        @builtins.property
        def certificate(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientTlsCertificateProperty"]]:
            '''A reference to an object that represents a client's TLS certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clientpolicytls.html#cfn-appmesh-virtualnode-clientpolicytls-certificate
            '''
            result = self._values.get("certificate")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientTlsCertificateProperty"]], result)

        @builtins.property
        def enforce(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''Whether the policy is enforced.

            The default is ``True`` , if a value isn't specified.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clientpolicytls.html#cfn-appmesh-virtualnode-clientpolicytls-enforce
            '''
            result = self._values.get("enforce")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def ports(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[jsii.Number]]]:
            '''One or more ports that the policy is enforced for.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clientpolicytls.html#cfn-appmesh-virtualnode-clientpolicytls-ports
            '''
            result = self._values.get("ports")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[jsii.Number]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ClientPolicyTlsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ClientTlsCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"file": "file", "sds": "sds"},
    )
    class ClientTlsCertificateProperty:
        def __init__(
            self,
            *,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsFileCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsSdsCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the client's certificate.

            :param file: An object that represents a local file certificate. The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ .
            :param sds: A reference to an object that represents a client's TLS Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clienttlscertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                client_tls_certificate_property = appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                        certificate_chain="certificateChain",
                        private_key="privateKey"
                    ),
                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ClientTlsCertificateProperty.__init__)
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsFileCertificateProperty"]]:
            '''An object that represents a local file certificate.

            The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clienttlscertificate.html#cfn-appmesh-virtualnode-clienttlscertificate-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsFileCertificateProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsSdsCertificateProperty"]]:
            '''A reference to an object that represents a client's TLS Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-clienttlscertificate.html#cfn-appmesh-virtualnode-clienttlscertificate-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsSdsCertificateProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ClientTlsCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.DnsServiceDiscoveryProperty",
        jsii_struct_bases=[],
        name_mapping={
            "hostname": "hostname",
            "ip_preference": "ipPreference",
            "response_type": "responseType",
        },
    )
    class DnsServiceDiscoveryProperty:
        def __init__(
            self,
            *,
            hostname: builtins.str,
            ip_preference: typing.Optional[builtins.str] = None,
            response_type: typing.Optional[builtins.str] = None,
        ) -> None:
            '''An object that represents the DNS service discovery information for your virtual node.

            :param hostname: Specifies the DNS service discovery hostname for the virtual node.
            :param ip_preference: The preferred IP version that this virtual node uses. Setting the IP preference on the virtual node only overrides the IP preference set for the mesh on this specific node.
            :param response_type: Specifies the DNS response type for the virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-dnsservicediscovery.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                dns_service_discovery_property = appmesh.CfnVirtualNode.DnsServiceDiscoveryProperty(
                    hostname="hostname",
                
                    # the properties below are optional
                    ip_preference="ipPreference",
                    response_type="responseType"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.DnsServiceDiscoveryProperty.__init__)
                check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
                check_type(argname="argument ip_preference", value=ip_preference, expected_type=type_hints["ip_preference"])
                check_type(argname="argument response_type", value=response_type, expected_type=type_hints["response_type"])
            self._values: typing.Dict[str, typing.Any] = {
                "hostname": hostname,
            }
            if ip_preference is not None:
                self._values["ip_preference"] = ip_preference
            if response_type is not None:
                self._values["response_type"] = response_type

        @builtins.property
        def hostname(self) -> builtins.str:
            '''Specifies the DNS service discovery hostname for the virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-dnsservicediscovery.html#cfn-appmesh-virtualnode-dnsservicediscovery-hostname
            '''
            result = self._values.get("hostname")
            assert result is not None, "Required property 'hostname' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def ip_preference(self) -> typing.Optional[builtins.str]:
            '''The preferred IP version that this virtual node uses.

            Setting the IP preference on the virtual node only overrides the IP preference set for the mesh on this specific node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-dnsservicediscovery.html#cfn-appmesh-virtualnode-dnsservicediscovery-ippreference
            '''
            result = self._values.get("ip_preference")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def response_type(self) -> typing.Optional[builtins.str]:
            '''Specifies the DNS response type for the virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-dnsservicediscovery.html#cfn-appmesh-virtualnode-dnsservicediscovery-responsetype
            '''
            result = self._values.get("response_type")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "DnsServiceDiscoveryProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.DurationProperty",
        jsii_struct_bases=[],
        name_mapping={"unit": "unit", "value": "value"},
    )
    class DurationProperty:
        def __init__(self, *, unit: builtins.str, value: jsii.Number) -> None:
            '''An object that represents a duration of time.

            :param unit: A unit of time.
            :param value: A number of time units.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-duration.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                duration_property = appmesh.CfnVirtualNode.DurationProperty(
                    unit="unit",
                    value=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.DurationProperty.__init__)
                check_type(argname="argument unit", value=unit, expected_type=type_hints["unit"])
                check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            self._values: typing.Dict[str, typing.Any] = {
                "unit": unit,
                "value": value,
            }

        @builtins.property
        def unit(self) -> builtins.str:
            '''A unit of time.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-duration.html#cfn-appmesh-virtualnode-duration-unit
            '''
            result = self._values.get("unit")
            assert result is not None, "Required property 'unit' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def value(self) -> jsii.Number:
            '''A number of time units.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-duration.html#cfn-appmesh-virtualnode-duration-value
            '''
            result = self._values.get("value")
            assert result is not None, "Required property 'value' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "DurationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.FileAccessLogProperty",
        jsii_struct_bases=[],
        name_mapping={"path": "path", "format": "format"},
    )
    class FileAccessLogProperty:
        def __init__(
            self,
            *,
            path: builtins.str,
            format: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.LoggingFormatProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents an access log file.

            :param path: The file path to write access logs to. You can use ``/dev/stdout`` to send access logs to standard out and configure your Envoy container to use a log driver, such as ``awslogs`` , to export the access logs to a log storage service such as Amazon CloudWatch Logs. You can also specify a path in the Envoy container's file system to write the files to disk. .. epigraph:: The Envoy process must have write permissions to the path that you specify here. Otherwise, Envoy fails to bootstrap properly.
            :param format: ``CfnVirtualNode.FileAccessLogProperty.Format``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-fileaccesslog.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                file_access_log_property = appmesh.CfnVirtualNode.FileAccessLogProperty(
                    path="path",
                
                    # the properties below are optional
                    format=appmesh.CfnVirtualNode.LoggingFormatProperty(
                        json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                            key="key",
                            value="value"
                        )],
                        text="text"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.FileAccessLogProperty.__init__)
                check_type(argname="argument path", value=path, expected_type=type_hints["path"])
                check_type(argname="argument format", value=format, expected_type=type_hints["format"])
            self._values: typing.Dict[str, typing.Any] = {
                "path": path,
            }
            if format is not None:
                self._values["format"] = format

        @builtins.property
        def path(self) -> builtins.str:
            '''The file path to write access logs to.

            You can use ``/dev/stdout`` to send access logs to standard out and configure your Envoy container to use a log driver, such as ``awslogs`` , to export the access logs to a log storage service such as Amazon CloudWatch Logs. You can also specify a path in the Envoy container's file system to write the files to disk.
            .. epigraph::

               The Envoy process must have write permissions to the path that you specify here. Otherwise, Envoy fails to bootstrap properly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-fileaccesslog.html#cfn-appmesh-virtualnode-fileaccesslog-path
            '''
            result = self._values.get("path")
            assert result is not None, "Required property 'path' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def format(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.LoggingFormatProperty"]]:
            '''``CfnVirtualNode.FileAccessLogProperty.Format``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-fileaccesslog.html#cfn-appmesh-virtualnode-fileaccesslog-format
            '''
            result = self._values.get("format")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.LoggingFormatProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FileAccessLogProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.GrpcTimeoutProperty",
        jsii_struct_bases=[],
        name_mapping={"idle": "idle", "per_request": "perRequest"},
    )
    class GrpcTimeoutProperty:
        def __init__(
            self,
            *,
            idle: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
            per_request: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents types of timeouts.

            :param idle: An object that represents an idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none.
            :param per_request: An object that represents a per request timeout. The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-grpctimeout.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                grpc_timeout_property = appmesh.CfnVirtualNode.GrpcTimeoutProperty(
                    idle=appmesh.CfnVirtualNode.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                    per_request=appmesh.CfnVirtualNode.DurationProperty(
                        unit="unit",
                        value=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.GrpcTimeoutProperty.__init__)
                check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
                check_type(argname="argument per_request", value=per_request, expected_type=type_hints["per_request"])
            self._values: typing.Dict[str, typing.Any] = {}
            if idle is not None:
                self._values["idle"] = idle
            if per_request is not None:
                self._values["per_request"] = per_request

        @builtins.property
        def idle(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]]:
            '''An object that represents an idle timeout.

            An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-grpctimeout.html#cfn-appmesh-virtualnode-grpctimeout-idle
            '''
            result = self._values.get("idle")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]], result)

        @builtins.property
        def per_request(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]]:
            '''An object that represents a per request timeout.

            The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-grpctimeout.html#cfn-appmesh-virtualnode-grpctimeout-perrequest
            '''
            result = self._values.get("per_request")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GrpcTimeoutProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.HealthCheckProperty",
        jsii_struct_bases=[],
        name_mapping={
            "healthy_threshold": "healthyThreshold",
            "interval_millis": "intervalMillis",
            "protocol": "protocol",
            "timeout_millis": "timeoutMillis",
            "unhealthy_threshold": "unhealthyThreshold",
            "path": "path",
            "port": "port",
        },
    )
    class HealthCheckProperty:
        def __init__(
            self,
            *,
            healthy_threshold: jsii.Number,
            interval_millis: jsii.Number,
            protocol: builtins.str,
            timeout_millis: jsii.Number,
            unhealthy_threshold: jsii.Number,
            path: typing.Optional[builtins.str] = None,
            port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''An object that represents the health check policy for a virtual node's listener.

            :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy.
            :param interval_millis: The time period in milliseconds between each health check execution.
            :param protocol: The protocol for the health check request. If you specify ``grpc`` , then your service must conform to the `GRPC Health Checking Protocol <https://docs.aws.amazon.com/https://github.com/grpc/grpc/blob/master/doc/health-checking.md>`_ .
            :param timeout_millis: The amount of time to wait when receiving a response from the health check, in milliseconds.
            :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a virtual node unhealthy.
            :param path: The destination path for the health check request. This value is only used if the specified protocol is HTTP or HTTP/2. For any other protocol, this value is ignored.
            :param port: The destination port for the health check request. This port must match the port defined in the ``PortMapping`` for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                health_check_property = appmesh.CfnVirtualNode.HealthCheckProperty(
                    healthy_threshold=123,
                    interval_millis=123,
                    protocol="protocol",
                    timeout_millis=123,
                    unhealthy_threshold=123,
                
                    # the properties below are optional
                    path="path",
                    port=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.HealthCheckProperty.__init__)
                check_type(argname="argument healthy_threshold", value=healthy_threshold, expected_type=type_hints["healthy_threshold"])
                check_type(argname="argument interval_millis", value=interval_millis, expected_type=type_hints["interval_millis"])
                check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
                check_type(argname="argument timeout_millis", value=timeout_millis, expected_type=type_hints["timeout_millis"])
                check_type(argname="argument unhealthy_threshold", value=unhealthy_threshold, expected_type=type_hints["unhealthy_threshold"])
                check_type(argname="argument path", value=path, expected_type=type_hints["path"])
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            self._values: typing.Dict[str, typing.Any] = {
                "healthy_threshold": healthy_threshold,
                "interval_millis": interval_millis,
                "protocol": protocol,
                "timeout_millis": timeout_millis,
                "unhealthy_threshold": unhealthy_threshold,
            }
            if path is not None:
                self._values["path"] = path
            if port is not None:
                self._values["port"] = port

        @builtins.property
        def healthy_threshold(self) -> jsii.Number:
            '''The number of consecutive successful health checks that must occur before declaring listener healthy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html#cfn-appmesh-virtualnode-healthcheck-healthythreshold
            '''
            result = self._values.get("healthy_threshold")
            assert result is not None, "Required property 'healthy_threshold' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def interval_millis(self) -> jsii.Number:
            '''The time period in milliseconds between each health check execution.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html#cfn-appmesh-virtualnode-healthcheck-intervalmillis
            '''
            result = self._values.get("interval_millis")
            assert result is not None, "Required property 'interval_millis' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def protocol(self) -> builtins.str:
            '''The protocol for the health check request.

            If you specify ``grpc`` , then your service must conform to the `GRPC Health Checking Protocol <https://docs.aws.amazon.com/https://github.com/grpc/grpc/blob/master/doc/health-checking.md>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html#cfn-appmesh-virtualnode-healthcheck-protocol
            '''
            result = self._values.get("protocol")
            assert result is not None, "Required property 'protocol' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def timeout_millis(self) -> jsii.Number:
            '''The amount of time to wait when receiving a response from the health check, in milliseconds.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html#cfn-appmesh-virtualnode-healthcheck-timeoutmillis
            '''
            result = self._values.get("timeout_millis")
            assert result is not None, "Required property 'timeout_millis' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def unhealthy_threshold(self) -> jsii.Number:
            '''The number of consecutive failed health checks that must occur before declaring a virtual node unhealthy.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html#cfn-appmesh-virtualnode-healthcheck-unhealthythreshold
            '''
            result = self._values.get("unhealthy_threshold")
            assert result is not None, "Required property 'unhealthy_threshold' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def path(self) -> typing.Optional[builtins.str]:
            '''The destination path for the health check request.

            This value is only used if the specified protocol is HTTP or HTTP/2. For any other protocol, this value is ignored.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html#cfn-appmesh-virtualnode-healthcheck-path
            '''
            result = self._values.get("path")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''The destination port for the health check request.

            This port must match the port defined in the ``PortMapping`` for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html#cfn-appmesh-virtualnode-healthcheck-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HealthCheckProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.HttpTimeoutProperty",
        jsii_struct_bases=[],
        name_mapping={"idle": "idle", "per_request": "perRequest"},
    )
    class HttpTimeoutProperty:
        def __init__(
            self,
            *,
            idle: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
            per_request: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents types of timeouts.

            :param idle: An object that represents an idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none.
            :param per_request: An object that represents a per request timeout. The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-httptimeout.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                http_timeout_property = appmesh.CfnVirtualNode.HttpTimeoutProperty(
                    idle=appmesh.CfnVirtualNode.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                    per_request=appmesh.CfnVirtualNode.DurationProperty(
                        unit="unit",
                        value=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.HttpTimeoutProperty.__init__)
                check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
                check_type(argname="argument per_request", value=per_request, expected_type=type_hints["per_request"])
            self._values: typing.Dict[str, typing.Any] = {}
            if idle is not None:
                self._values["idle"] = idle
            if per_request is not None:
                self._values["per_request"] = per_request

        @builtins.property
        def idle(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]]:
            '''An object that represents an idle timeout.

            An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-httptimeout.html#cfn-appmesh-virtualnode-httptimeout-idle
            '''
            result = self._values.get("idle")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]], result)

        @builtins.property
        def per_request(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]]:
            '''An object that represents a per request timeout.

            The default value is 15 seconds. If you set a higher timeout, then make sure that the higher value is set for each App Mesh resource in a conversation. For example, if a virtual node backend uses a virtual router provider to route to another virtual node, then the timeout should be greater than 15 seconds for the source and destination virtual node and the route.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-httptimeout.html#cfn-appmesh-virtualnode-httptimeout-perrequest
            '''
            result = self._values.get("per_request")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HttpTimeoutProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.JsonFormatRefProperty",
        jsii_struct_bases=[],
        name_mapping={"key": "key", "value": "value"},
    )
    class JsonFormatRefProperty:
        def __init__(self, *, key: builtins.str, value: builtins.str) -> None:
            '''
            :param key: ``CfnVirtualNode.JsonFormatRefProperty.Key``.
            :param value: ``CfnVirtualNode.JsonFormatRefProperty.Value``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-jsonformatref.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                json_format_ref_property = appmesh.CfnVirtualNode.JsonFormatRefProperty(
                    key="key",
                    value="value"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.JsonFormatRefProperty.__init__)
                check_type(argname="argument key", value=key, expected_type=type_hints["key"])
                check_type(argname="argument value", value=value, expected_type=type_hints["value"])
            self._values: typing.Dict[str, typing.Any] = {
                "key": key,
                "value": value,
            }

        @builtins.property
        def key(self) -> builtins.str:
            '''``CfnVirtualNode.JsonFormatRefProperty.Key``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-jsonformatref.html#cfn-appmesh-virtualnode-jsonformatref-key
            '''
            result = self._values.get("key")
            assert result is not None, "Required property 'key' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def value(self) -> builtins.str:
            '''``CfnVirtualNode.JsonFormatRefProperty.Value``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-jsonformatref.html#cfn-appmesh-virtualnode-jsonformatref-value
            '''
            result = self._values.get("value")
            assert result is not None, "Required property 'value' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "JsonFormatRefProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerProperty",
        jsii_struct_bases=[],
        name_mapping={
            "port_mapping": "portMapping",
            "connection_pool": "connectionPool",
            "health_check": "healthCheck",
            "outlier_detection": "outlierDetection",
            "timeout": "timeout",
            "tls": "tls",
        },
    )
    class ListenerProperty:
        def __init__(
            self,
            *,
            port_mapping: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.PortMappingProperty", typing.Dict[str, typing.Any]]],
            connection_pool: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.VirtualNodeConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
            health_check: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.HealthCheckProperty", typing.Dict[str, typing.Any]]]] = None,
            outlier_detection: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.OutlierDetectionProperty", typing.Dict[str, typing.Any]]]] = None,
            timeout: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
            tls: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a listener for a virtual node.

            :param port_mapping: The port mapping information for the listener.
            :param connection_pool: The connection pool information for the listener.
            :param health_check: The health check information for the listener.
            :param outlier_detection: The outlier detection information for the listener.
            :param timeout: An object that represents timeouts for different protocols.
            :param tls: A reference to an object that represents the Transport Layer Security (TLS) properties for a listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_property = appmesh.CfnVirtualNode.ListenerProperty(
                    port_mapping=appmesh.CfnVirtualNode.PortMappingProperty(
                        port=123,
                        protocol="protocol"
                    ),
                
                    # the properties below are optional
                    connection_pool=appmesh.CfnVirtualNode.VirtualNodeConnectionPoolProperty(
                        grpc=appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty(
                            max_requests=123
                        ),
                        http=appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty(
                            max_connections=123,
                
                            # the properties below are optional
                            max_pending_requests=123
                        ),
                        http2=appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty(
                            max_requests=123
                        ),
                        tcp=appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty(
                            max_connections=123
                        )
                    ),
                    health_check=appmesh.CfnVirtualNode.HealthCheckProperty(
                        healthy_threshold=123,
                        interval_millis=123,
                        protocol="protocol",
                        timeout_millis=123,
                        unhealthy_threshold=123,
                
                        # the properties below are optional
                        path="path",
                        port=123
                    ),
                    outlier_detection=appmesh.CfnVirtualNode.OutlierDetectionProperty(
                        base_ejection_duration=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        interval=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        max_ejection_percent=123,
                        max_server_errors=123
                    ),
                    timeout=appmesh.CfnVirtualNode.ListenerTimeoutProperty(
                        grpc=appmesh.CfnVirtualNode.GrpcTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        http=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        http2=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        tcp=appmesh.CfnVirtualNode.TcpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    tls=appmesh.CfnVirtualNode.ListenerTlsProperty(
                        certificate=appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                            acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                                certificate_arn="certificateArn"
                            ),
                            file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        mode="mode",
                
                        # the properties below are optional
                        validation=appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty(
                            trust=appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                                file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
                
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerProperty.__init__)
                check_type(argname="argument port_mapping", value=port_mapping, expected_type=type_hints["port_mapping"])
                check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
                check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
                check_type(argname="argument outlier_detection", value=outlier_detection, expected_type=type_hints["outlier_detection"])
                check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
                check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
            self._values: typing.Dict[str, typing.Any] = {
                "port_mapping": port_mapping,
            }
            if connection_pool is not None:
                self._values["connection_pool"] = connection_pool
            if health_check is not None:
                self._values["health_check"] = health_check
            if outlier_detection is not None:
                self._values["outlier_detection"] = outlier_detection
            if timeout is not None:
                self._values["timeout"] = timeout
            if tls is not None:
                self._values["tls"] = tls

        @builtins.property
        def port_mapping(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.PortMappingProperty"]:
            '''The port mapping information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html#cfn-appmesh-virtualnode-listener-portmapping
            '''
            result = self._values.get("port_mapping")
            assert result is not None, "Required property 'port_mapping' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.PortMappingProperty"], result)

        @builtins.property
        def connection_pool(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeConnectionPoolProperty"]]:
            '''The connection pool information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html#cfn-appmesh-virtualnode-listener-connectionpool
            '''
            result = self._values.get("connection_pool")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeConnectionPoolProperty"]], result)

        @builtins.property
        def health_check(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.HealthCheckProperty"]]:
            '''The health check information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html#cfn-appmesh-virtualnode-listener-healthcheck
            '''
            result = self._values.get("health_check")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.HealthCheckProperty"]], result)

        @builtins.property
        def outlier_detection(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.OutlierDetectionProperty"]]:
            '''The outlier detection information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html#cfn-appmesh-virtualnode-listener-outlierdetection
            '''
            result = self._values.get("outlier_detection")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.OutlierDetectionProperty"]], result)

        @builtins.property
        def timeout(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTimeoutProperty"]]:
            '''An object that represents timeouts for different protocols.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html#cfn-appmesh-virtualnode-listener-timeout
            '''
            result = self._values.get("timeout")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTimeoutProperty"]], result)

        @builtins.property
        def tls(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsProperty"]]:
            '''A reference to an object that represents the Transport Layer Security (TLS) properties for a listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html#cfn-appmesh-virtualnode-listener-tls
            '''
            result = self._values.get("tls")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTimeoutProperty",
        jsii_struct_bases=[],
        name_mapping={"grpc": "grpc", "http": "http", "http2": "http2", "tcp": "tcp"},
    )
    class ListenerTimeoutProperty:
        def __init__(
            self,
            *,
            grpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.GrpcTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
            http: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.HttpTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
            http2: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.HttpTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
            tcp: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TcpTimeoutProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents timeouts for different protocols.

            :param grpc: An object that represents types of timeouts.
            :param http: An object that represents types of timeouts.
            :param http2: An object that represents types of timeouts.
            :param tcp: An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_timeout_property = appmesh.CfnVirtualNode.ListenerTimeoutProperty(
                    grpc=appmesh.CfnVirtualNode.GrpcTimeoutProperty(
                        idle=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    ),
                    http=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                        idle=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    ),
                    http2=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                        idle=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    ),
                    tcp=appmesh.CfnVirtualNode.TcpTimeoutProperty(
                        idle=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTimeoutProperty.__init__)
                check_type(argname="argument grpc", value=grpc, expected_type=type_hints["grpc"])
                check_type(argname="argument http", value=http, expected_type=type_hints["http"])
                check_type(argname="argument http2", value=http2, expected_type=type_hints["http2"])
                check_type(argname="argument tcp", value=tcp, expected_type=type_hints["tcp"])
            self._values: typing.Dict[str, typing.Any] = {}
            if grpc is not None:
                self._values["grpc"] = grpc
            if http is not None:
                self._values["http"] = http
            if http2 is not None:
                self._values["http2"] = http2
            if tcp is not None:
                self._values["tcp"] = tcp

        @builtins.property
        def grpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.GrpcTimeoutProperty"]]:
            '''An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-grpc
            '''
            result = self._values.get("grpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.GrpcTimeoutProperty"]], result)

        @builtins.property
        def http(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.HttpTimeoutProperty"]]:
            '''An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-http
            '''
            result = self._values.get("http")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.HttpTimeoutProperty"]], result)

        @builtins.property
        def http2(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.HttpTimeoutProperty"]]:
            '''An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-http2
            '''
            result = self._values.get("http2")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.HttpTimeoutProperty"]], result)

        @builtins.property
        def tcp(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TcpTimeoutProperty"]]:
            '''An object that represents types of timeouts.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-tcp
            '''
            result = self._values.get("tcp")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TcpTimeoutProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTimeoutProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"certificate_arn": "certificateArn"},
    )
    class ListenerTlsAcmCertificateProperty:
        def __init__(self, *, certificate_arn: builtins.str) -> None:
            '''An object that represents an AWS Certificate Manager certificate.

            :param certificate_arn: The Amazon Resource Name (ARN) for the certificate. The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html#virtual-node-tls-prerequisites>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsacmcertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_tls_acm_certificate_property = appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                    certificate_arn="certificateArn"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTlsAcmCertificateProperty.__init__)
                check_type(argname="argument certificate_arn", value=certificate_arn, expected_type=type_hints["certificate_arn"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_arn": certificate_arn,
            }

        @builtins.property
        def certificate_arn(self) -> builtins.str:
            '''The Amazon Resource Name (ARN) for the certificate.

            The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html#virtual-node-tls-prerequisites>`_ .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsacmcertificate.html#cfn-appmesh-virtualnode-listenertlsacmcertificate-certificatearn
            '''
            result = self._values.get("certificate_arn")
            assert result is not None, "Required property 'certificate_arn' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTlsAcmCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTlsCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"acm": "acm", "file": "file", "sds": "sds"},
    )
    class ListenerTlsCertificateProperty:
        def __init__(
            self,
            *,
            acm: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsAcmCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsFileCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsSdsCertificateProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a listener's Transport Layer Security (TLS) certificate.

            :param acm: A reference to an object that represents an AWS Certificate Manager certificate.
            :param file: A reference to an object that represents a local file certificate.
            :param sds: A reference to an object that represents a listener's Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlscertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_tls_certificate_property = appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                    acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                        certificate_arn="certificateArn"
                    ),
                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                        certificate_chain="certificateChain",
                        private_key="privateKey"
                    ),
                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTlsCertificateProperty.__init__)
                check_type(argname="argument acm", value=acm, expected_type=type_hints["acm"])
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if acm is not None:
                self._values["acm"] = acm
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def acm(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsAcmCertificateProperty"]]:
            '''A reference to an object that represents an AWS Certificate Manager certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlscertificate.html#cfn-appmesh-virtualnode-listenertlscertificate-acm
            '''
            result = self._values.get("acm")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsAcmCertificateProperty"]], result)

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsFileCertificateProperty"]]:
            '''A reference to an object that represents a local file certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlscertificate.html#cfn-appmesh-virtualnode-listenertlscertificate-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsFileCertificateProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsSdsCertificateProperty"]]:
            '''A reference to an object that represents a listener's Secret Discovery Service certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlscertificate.html#cfn-appmesh-virtualnode-listenertlscertificate-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsSdsCertificateProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTlsCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={
            "certificate_chain": "certificateChain",
            "private_key": "privateKey",
        },
    )
    class ListenerTlsFileCertificateProperty:
        def __init__(
            self,
            *,
            certificate_chain: builtins.str,
            private_key: builtins.str,
        ) -> None:
            '''An object that represents a local file certificate.

            The certificate must meet specific requirements and you must have proxy authorization enabled. For more information, see `Transport Layer Security (TLS) <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html#virtual-node-tls-prerequisites>`_ .

            :param certificate_chain: The certificate chain for the certificate.
            :param private_key: The private key for a certificate stored on the file system of the virtual node that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsfilecertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_tls_file_certificate_property = appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                    certificate_chain="certificateChain",
                    private_key="privateKey"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTlsFileCertificateProperty.__init__)
                check_type(argname="argument certificate_chain", value=certificate_chain, expected_type=type_hints["certificate_chain"])
                check_type(argname="argument private_key", value=private_key, expected_type=type_hints["private_key"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_chain": certificate_chain,
                "private_key": private_key,
            }

        @builtins.property
        def certificate_chain(self) -> builtins.str:
            '''The certificate chain for the certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsfilecertificate.html#cfn-appmesh-virtualnode-listenertlsfilecertificate-certificatechain
            '''
            result = self._values.get("certificate_chain")
            assert result is not None, "Required property 'certificate_chain' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def private_key(self) -> builtins.str:
            '''The private key for a certificate stored on the file system of the virtual node that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsfilecertificate.html#cfn-appmesh-virtualnode-listenertlsfilecertificate-privatekey
            '''
            result = self._values.get("private_key")
            assert result is not None, "Required property 'private_key' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTlsFileCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTlsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "certificate": "certificate",
            "mode": "mode",
            "validation": "validation",
        },
    )
    class ListenerTlsProperty:
        def __init__(
            self,
            *,
            certificate: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsCertificateProperty", typing.Dict[str, typing.Any]]],
            mode: builtins.str,
            validation: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsValidationContextProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the Transport Layer Security (TLS) properties for a listener.

            :param certificate: A reference to an object that represents a listener's Transport Layer Security (TLS) certificate.
            :param mode: Specify one of the following modes. - ** STRICT – Listener only accepts connections with TLS enabled. - ** PERMISSIVE – Listener accepts connections with or without TLS enabled. - ** DISABLED – Listener only accepts connections without TLS.
            :param validation: A reference to an object that represents a listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertls.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_tls_property = appmesh.CfnVirtualNode.ListenerTlsProperty(
                    certificate=appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                        acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                            certificate_arn="certificateArn"
                        ),
                        file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                            certificate_chain="certificateChain",
                            private_key="privateKey"
                        ),
                        sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                            secret_name="secretName"
                        )
                    ),
                    mode="mode",
                
                    # the properties below are optional
                    validation=appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty(
                        trust=appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                            file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                certificate_chain="certificateChain"
                            ),
                            sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                secret_name="secretName"
                            )
                        ),
                
                        # the properties below are optional
                        subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                            match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                exact=["exact"]
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTlsProperty.__init__)
                check_type(argname="argument certificate", value=certificate, expected_type=type_hints["certificate"])
                check_type(argname="argument mode", value=mode, expected_type=type_hints["mode"])
                check_type(argname="argument validation", value=validation, expected_type=type_hints["validation"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate": certificate,
                "mode": mode,
            }
            if validation is not None:
                self._values["validation"] = validation

        @builtins.property
        def certificate(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsCertificateProperty"]:
            '''A reference to an object that represents a listener's Transport Layer Security (TLS) certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertls.html#cfn-appmesh-virtualnode-listenertls-certificate
            '''
            result = self._values.get("certificate")
            assert result is not None, "Required property 'certificate' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsCertificateProperty"], result)

        @builtins.property
        def mode(self) -> builtins.str:
            '''Specify one of the following modes.

            - ** STRICT – Listener only accepts connections with TLS enabled.
            - ** PERMISSIVE – Listener accepts connections with or without TLS enabled.
            - ** DISABLED – Listener only accepts connections without TLS.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertls.html#cfn-appmesh-virtualnode-listenertls-mode
            '''
            result = self._values.get("mode")
            assert result is not None, "Required property 'mode' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def validation(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsValidationContextProperty"]]:
            '''A reference to an object that represents a listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertls.html#cfn-appmesh-virtualnode-listenertls-validation
            '''
            result = self._values.get("validation")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsValidationContextProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTlsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={"secret_name": "secretName"},
    )
    class ListenerTlsSdsCertificateProperty:
        def __init__(self, *, secret_name: builtins.str) -> None:
            '''An object that represents the listener's Secret Discovery Service certificate.

            The proxy must be configured with a local SDS provider via a Unix Domain Socket. See App Mesh `TLS documentation <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ for more info.

            :param secret_name: A reference to an object that represents the name of the secret requested from the Secret Discovery Service provider representing Transport Layer Security (TLS) materials like a certificate or certificate chain.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlssdscertificate.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_tls_sds_certificate_property = appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                    secret_name="secretName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTlsSdsCertificateProperty.__init__)
                check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
            self._values: typing.Dict[str, typing.Any] = {
                "secret_name": secret_name,
            }

        @builtins.property
        def secret_name(self) -> builtins.str:
            '''A reference to an object that represents the name of the secret requested from the Secret Discovery Service provider representing Transport Layer Security (TLS) materials like a certificate or certificate chain.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlssdscertificate.html#cfn-appmesh-virtualnode-listenertlssdscertificate-secretname
            '''
            result = self._values.get("secret_name")
            assert result is not None, "Required property 'secret_name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTlsSdsCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty",
        jsii_struct_bases=[],
        name_mapping={
            "trust": "trust",
            "subject_alternative_names": "subjectAlternativeNames",
        },
    )
    class ListenerTlsValidationContextProperty:
        def __init__(
            self,
            *,
            trust: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerTlsValidationContextTrustProperty", typing.Dict[str, typing.Any]]],
            subject_alternative_names: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.SubjectAlternativeNamesProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a listener's Transport Layer Security (TLS) validation context.

            :param trust: A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.
            :param subject_alternative_names: A reference to an object that represents the SANs for a listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsvalidationcontext.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_tls_validation_context_property = appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty(
                    trust=appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                        file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                            certificate_chain="certificateChain"
                        ),
                        sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                            secret_name="secretName"
                        )
                    ),
                
                    # the properties below are optional
                    subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                        match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                            exact=["exact"]
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTlsValidationContextProperty.__init__)
                check_type(argname="argument trust", value=trust, expected_type=type_hints["trust"])
                check_type(argname="argument subject_alternative_names", value=subject_alternative_names, expected_type=type_hints["subject_alternative_names"])
            self._values: typing.Dict[str, typing.Any] = {
                "trust": trust,
            }
            if subject_alternative_names is not None:
                self._values["subject_alternative_names"] = subject_alternative_names

        @builtins.property
        def trust(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsValidationContextTrustProperty"]:
            '''A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsvalidationcontext.html#cfn-appmesh-virtualnode-listenertlsvalidationcontext-trust
            '''
            result = self._values.get("trust")
            assert result is not None, "Required property 'trust' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerTlsValidationContextTrustProperty"], result)

        @builtins.property
        def subject_alternative_names(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.SubjectAlternativeNamesProperty"]]:
            '''A reference to an object that represents the SANs for a listener's Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsvalidationcontext.html#cfn-appmesh-virtualnode-listenertlsvalidationcontext-subjectalternativenames
            '''
            result = self._values.get("subject_alternative_names")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.SubjectAlternativeNamesProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTlsValidationContextProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"file": "file", "sds": "sds"},
    )
    class ListenerTlsValidationContextTrustProperty:
        def __init__(
            self,
            *,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TlsValidationContextFileTrustProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TlsValidationContextSdsTrustProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a listener's Transport Layer Security (TLS) validation context trust.

            :param file: An object that represents a Transport Layer Security (TLS) validation context trust for a local file.
            :param sds: A reference to an object that represents a listener's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsvalidationcontexttrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                listener_tls_validation_context_trust_property = appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                        certificate_chain="certificateChain"
                    ),
                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ListenerTlsValidationContextTrustProperty.__init__)
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextFileTrustProperty"]]:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for a local file.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsvalidationcontexttrust.html#cfn-appmesh-virtualnode-listenertlsvalidationcontexttrust-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextFileTrustProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextSdsTrustProperty"]]:
            '''A reference to an object that represents a listener's Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertlsvalidationcontexttrust.html#cfn-appmesh-virtualnode-listenertlsvalidationcontexttrust-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextSdsTrustProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ListenerTlsValidationContextTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.LoggingFormatProperty",
        jsii_struct_bases=[],
        name_mapping={"json": "json", "text": "text"},
    )
    class LoggingFormatProperty:
        def __init__(
            self,
            *,
            json: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.JsonFormatRefProperty", typing.Dict[str, typing.Any]]]]]] = None,
            text: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param json: ``CfnVirtualNode.LoggingFormatProperty.Json``.
            :param text: ``CfnVirtualNode.LoggingFormatProperty.Text``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-loggingformat.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                logging_format_property = appmesh.CfnVirtualNode.LoggingFormatProperty(
                    json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                        key="key",
                        value="value"
                    )],
                    text="text"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.LoggingFormatProperty.__init__)
                check_type(argname="argument json", value=json, expected_type=type_hints["json"])
                check_type(argname="argument text", value=text, expected_type=type_hints["text"])
            self._values: typing.Dict[str, typing.Any] = {}
            if json is not None:
                self._values["json"] = json
            if text is not None:
                self._values["text"] = text

        @builtins.property
        def json(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.JsonFormatRefProperty"]]]]:
            '''``CfnVirtualNode.LoggingFormatProperty.Json``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-loggingformat.html#cfn-appmesh-virtualnode-loggingformat-json
            '''
            result = self._values.get("json")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.JsonFormatRefProperty"]]]], result)

        @builtins.property
        def text(self) -> typing.Optional[builtins.str]:
            '''``CfnVirtualNode.LoggingFormatProperty.Text``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-loggingformat.html#cfn-appmesh-virtualnode-loggingformat-text
            '''
            result = self._values.get("text")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LoggingFormatProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.LoggingProperty",
        jsii_struct_bases=[],
        name_mapping={"access_log": "accessLog"},
    )
    class LoggingProperty:
        def __init__(
            self,
            *,
            access_log: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.AccessLogProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the logging information for a virtual node.

            :param access_log: The access log configuration for a virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-logging.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                logging_property = appmesh.CfnVirtualNode.LoggingProperty(
                    access_log=appmesh.CfnVirtualNode.AccessLogProperty(
                        file=appmesh.CfnVirtualNode.FileAccessLogProperty(
                            path="path",
                
                            # the properties below are optional
                            format=appmesh.CfnVirtualNode.LoggingFormatProperty(
                                json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                                    key="key",
                                    value="value"
                                )],
                                text="text"
                            )
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.LoggingProperty.__init__)
                check_type(argname="argument access_log", value=access_log, expected_type=type_hints["access_log"])
            self._values: typing.Dict[str, typing.Any] = {}
            if access_log is not None:
                self._values["access_log"] = access_log

        @builtins.property
        def access_log(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.AccessLogProperty"]]:
            '''The access log configuration for a virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-logging.html#cfn-appmesh-virtualnode-logging-accesslog
            '''
            result = self._values.get("access_log")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.AccessLogProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LoggingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.OutlierDetectionProperty",
        jsii_struct_bases=[],
        name_mapping={
            "base_ejection_duration": "baseEjectionDuration",
            "interval": "interval",
            "max_ejection_percent": "maxEjectionPercent",
            "max_server_errors": "maxServerErrors",
        },
    )
    class OutlierDetectionProperty:
        def __init__(
            self,
            *,
            base_ejection_duration: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DurationProperty", typing.Dict[str, typing.Any]]],
            interval: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DurationProperty", typing.Dict[str, typing.Any]]],
            max_ejection_percent: jsii.Number,
            max_server_errors: jsii.Number,
        ) -> None:
            '''An object that represents the outlier detection for a virtual node's listener.

            :param base_ejection_duration: The base amount of time for which a host is ejected.
            :param interval: The time interval between ejection sweep analysis.
            :param max_ejection_percent: Maximum percentage of hosts in load balancing pool for upstream service that can be ejected. Will eject at least one host regardless of the value.
            :param max_server_errors: Number of consecutive ``5xx`` errors required for ejection.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-outlierdetection.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                outlier_detection_property = appmesh.CfnVirtualNode.OutlierDetectionProperty(
                    base_ejection_duration=appmesh.CfnVirtualNode.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                    interval=appmesh.CfnVirtualNode.DurationProperty(
                        unit="unit",
                        value=123
                    ),
                    max_ejection_percent=123,
                    max_server_errors=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.OutlierDetectionProperty.__init__)
                check_type(argname="argument base_ejection_duration", value=base_ejection_duration, expected_type=type_hints["base_ejection_duration"])
                check_type(argname="argument interval", value=interval, expected_type=type_hints["interval"])
                check_type(argname="argument max_ejection_percent", value=max_ejection_percent, expected_type=type_hints["max_ejection_percent"])
                check_type(argname="argument max_server_errors", value=max_server_errors, expected_type=type_hints["max_server_errors"])
            self._values: typing.Dict[str, typing.Any] = {
                "base_ejection_duration": base_ejection_duration,
                "interval": interval,
                "max_ejection_percent": max_ejection_percent,
                "max_server_errors": max_server_errors,
            }

        @builtins.property
        def base_ejection_duration(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]:
            '''The base amount of time for which a host is ejected.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-outlierdetection.html#cfn-appmesh-virtualnode-outlierdetection-baseejectionduration
            '''
            result = self._values.get("base_ejection_duration")
            assert result is not None, "Required property 'base_ejection_duration' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"], result)

        @builtins.property
        def interval(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]:
            '''The time interval between ejection sweep analysis.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-outlierdetection.html#cfn-appmesh-virtualnode-outlierdetection-interval
            '''
            result = self._values.get("interval")
            assert result is not None, "Required property 'interval' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"], result)

        @builtins.property
        def max_ejection_percent(self) -> jsii.Number:
            '''Maximum percentage of hosts in load balancing pool for upstream service that can be ejected.

            Will eject at least one host regardless of the value.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-outlierdetection.html#cfn-appmesh-virtualnode-outlierdetection-maxejectionpercent
            '''
            result = self._values.get("max_ejection_percent")
            assert result is not None, "Required property 'max_ejection_percent' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def max_server_errors(self) -> jsii.Number:
            '''Number of consecutive ``5xx`` errors required for ejection.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-outlierdetection.html#cfn-appmesh-virtualnode-outlierdetection-maxservererrors
            '''
            result = self._values.get("max_server_errors")
            assert result is not None, "Required property 'max_server_errors' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OutlierDetectionProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.PortMappingProperty",
        jsii_struct_bases=[],
        name_mapping={"port": "port", "protocol": "protocol"},
    )
    class PortMappingProperty:
        def __init__(self, *, port: jsii.Number, protocol: builtins.str) -> None:
            '''An object representing a virtual node or virtual router listener port mapping.

            :param port: The port used for the port mapping.
            :param protocol: The protocol used for the port mapping. Specify ``http`` , ``http2`` , ``grpc`` , or ``tcp`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-portmapping.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                port_mapping_property = appmesh.CfnVirtualNode.PortMappingProperty(
                    port=123,
                    protocol="protocol"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.PortMappingProperty.__init__)
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
                check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
            self._values: typing.Dict[str, typing.Any] = {
                "port": port,
                "protocol": protocol,
            }

        @builtins.property
        def port(self) -> jsii.Number:
            '''The port used for the port mapping.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-portmapping.html#cfn-appmesh-virtualnode-portmapping-port
            '''
            result = self._values.get("port")
            assert result is not None, "Required property 'port' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def protocol(self) -> builtins.str:
            '''The protocol used for the port mapping.

            Specify ``http`` , ``http2`` , ``grpc`` , or ``tcp`` .

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-portmapping.html#cfn-appmesh-virtualnode-portmapping-protocol
            '''
            result = self._values.get("protocol")
            assert result is not None, "Required property 'protocol' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PortMappingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.ServiceDiscoveryProperty",
        jsii_struct_bases=[],
        name_mapping={"aws_cloud_map": "awsCloudMap", "dns": "dns"},
    )
    class ServiceDiscoveryProperty:
        def __init__(
            self,
            *,
            aws_cloud_map: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty", typing.Dict[str, typing.Any]]]] = None,
            dns: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DnsServiceDiscoveryProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the service discovery information for a virtual node.

            :param aws_cloud_map: Specifies any AWS Cloud Map information for the virtual node.
            :param dns: Specifies the DNS information for the virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-servicediscovery.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                service_discovery_property = appmesh.CfnVirtualNode.ServiceDiscoveryProperty(
                    aws_cloud_map=appmesh.CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty(
                        namespace_name="namespaceName",
                        service_name="serviceName",
                
                        # the properties below are optional
                        attributes=[appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty(
                            key="key",
                            value="value"
                        )],
                        ip_preference="ipPreference"
                    ),
                    dns=appmesh.CfnVirtualNode.DnsServiceDiscoveryProperty(
                        hostname="hostname",
                
                        # the properties below are optional
                        ip_preference="ipPreference",
                        response_type="responseType"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.ServiceDiscoveryProperty.__init__)
                check_type(argname="argument aws_cloud_map", value=aws_cloud_map, expected_type=type_hints["aws_cloud_map"])
                check_type(argname="argument dns", value=dns, expected_type=type_hints["dns"])
            self._values: typing.Dict[str, typing.Any] = {}
            if aws_cloud_map is not None:
                self._values["aws_cloud_map"] = aws_cloud_map
            if dns is not None:
                self._values["dns"] = dns

        @builtins.property
        def aws_cloud_map(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty"]]:
            '''Specifies any AWS Cloud Map information for the virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-servicediscovery.html#cfn-appmesh-virtualnode-servicediscovery-awscloudmap
            '''
            result = self._values.get("aws_cloud_map")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty"]], result)

        @builtins.property
        def dns(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DnsServiceDiscoveryProperty"]]:
            '''Specifies the DNS information for the virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-servicediscovery.html#cfn-appmesh-virtualnode-servicediscovery-dns
            '''
            result = self._values.get("dns")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DnsServiceDiscoveryProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ServiceDiscoveryProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty",
        jsii_struct_bases=[],
        name_mapping={"exact": "exact"},
    )
    class SubjectAlternativeNameMatchersProperty:
        def __init__(
            self,
            *,
            exact: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''An object that represents the methods by which a subject alternative name on a peer Transport Layer Security (TLS) certificate can be matched.

            :param exact: The values sent must match the specified values exactly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-subjectalternativenamematchers.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                subject_alternative_name_matchers_property = appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                    exact=["exact"]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.SubjectAlternativeNameMatchersProperty.__init__)
                check_type(argname="argument exact", value=exact, expected_type=type_hints["exact"])
            self._values: typing.Dict[str, typing.Any] = {}
            if exact is not None:
                self._values["exact"] = exact

        @builtins.property
        def exact(self) -> typing.Optional[typing.List[builtins.str]]:
            '''The values sent must match the specified values exactly.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-subjectalternativenamematchers.html#cfn-appmesh-virtualnode-subjectalternativenamematchers-exact
            '''
            result = self._values.get("exact")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SubjectAlternativeNameMatchersProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty",
        jsii_struct_bases=[],
        name_mapping={"match": "match"},
    )
    class SubjectAlternativeNamesProperty:
        def __init__(
            self,
            *,
            match: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.SubjectAlternativeNameMatchersProperty", typing.Dict[str, typing.Any]]],
        ) -> None:
            '''An object that represents the subject alternative names secured by the certificate.

            :param match: An object that represents the criteria for determining a SANs match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-subjectalternativenames.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                subject_alternative_names_property = appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                    match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                        exact=["exact"]
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.SubjectAlternativeNamesProperty.__init__)
                check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            self._values: typing.Dict[str, typing.Any] = {
                "match": match,
            }

        @builtins.property
        def match(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.SubjectAlternativeNameMatchersProperty"]:
            '''An object that represents the criteria for determining a SANs match.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-subjectalternativenames.html#cfn-appmesh-virtualnode-subjectalternativenames-match
            '''
            result = self._values.get("match")
            assert result is not None, "Required property 'match' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.SubjectAlternativeNameMatchersProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SubjectAlternativeNamesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.TcpTimeoutProperty",
        jsii_struct_bases=[],
        name_mapping={"idle": "idle"},
    )
    class TcpTimeoutProperty:
        def __init__(
            self,
            *,
            idle: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.DurationProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents types of timeouts.

            :param idle: An object that represents an idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tcptimeout.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tcp_timeout_property = appmesh.CfnVirtualNode.TcpTimeoutProperty(
                    idle=appmesh.CfnVirtualNode.DurationProperty(
                        unit="unit",
                        value=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.TcpTimeoutProperty.__init__)
                check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
            self._values: typing.Dict[str, typing.Any] = {}
            if idle is not None:
                self._values["idle"] = idle

        @builtins.property
        def idle(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]]:
            '''An object that represents an idle timeout.

            An idle timeout bounds the amount of time that a connection may be idle. The default value is none.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tcptimeout.html#cfn-appmesh-virtualnode-tcptimeout-idle
            '''
            result = self._values.get("idle")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.DurationProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TcpTimeoutProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"certificate_authority_arns": "certificateAuthorityArns"},
    )
    class TlsValidationContextAcmTrustProperty:
        def __init__(
            self,
            *,
            certificate_authority_arns: typing.Sequence[builtins.str],
        ) -> None:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for an AWS Certificate Manager certificate.

            :param certificate_authority_arns: One or more ACM Amazon Resource Name (ARN)s.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontextacmtrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tls_validation_context_acm_trust_property = appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                    certificate_authority_arns=["certificateAuthorityArns"]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.TlsValidationContextAcmTrustProperty.__init__)
                check_type(argname="argument certificate_authority_arns", value=certificate_authority_arns, expected_type=type_hints["certificate_authority_arns"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_authority_arns": certificate_authority_arns,
            }

        @builtins.property
        def certificate_authority_arns(self) -> typing.List[builtins.str]:
            '''One or more ACM Amazon Resource Name (ARN)s.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontextacmtrust.html#cfn-appmesh-virtualnode-tlsvalidationcontextacmtrust-certificateauthorityarns
            '''
            result = self._values.get("certificate_authority_arns")
            assert result is not None, "Required property 'certificate_authority_arns' is missing"
            return typing.cast(typing.List[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TlsValidationContextAcmTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"certificate_chain": "certificateChain"},
    )
    class TlsValidationContextFileTrustProperty:
        def __init__(self, *, certificate_chain: builtins.str) -> None:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for a local file.

            :param certificate_chain: The certificate trust chain for a certificate stored on the file system of the virtual node that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontextfiletrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tls_validation_context_file_trust_property = appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                    certificate_chain="certificateChain"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.TlsValidationContextFileTrustProperty.__init__)
                check_type(argname="argument certificate_chain", value=certificate_chain, expected_type=type_hints["certificate_chain"])
            self._values: typing.Dict[str, typing.Any] = {
                "certificate_chain": certificate_chain,
            }

        @builtins.property
        def certificate_chain(self) -> builtins.str:
            '''The certificate trust chain for a certificate stored on the file system of the virtual node that the proxy is running on.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontextfiletrust.html#cfn-appmesh-virtualnode-tlsvalidationcontextfiletrust-certificatechain
            '''
            result = self._values.get("certificate_chain")
            assert result is not None, "Required property 'certificate_chain' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TlsValidationContextFileTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.TlsValidationContextProperty",
        jsii_struct_bases=[],
        name_mapping={
            "trust": "trust",
            "subject_alternative_names": "subjectAlternativeNames",
        },
    )
    class TlsValidationContextProperty:
        def __init__(
            self,
            *,
            trust: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TlsValidationContextTrustProperty", typing.Dict[str, typing.Any]]],
            subject_alternative_names: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.SubjectAlternativeNamesProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents how the proxy will validate its peer during Transport Layer Security (TLS) negotiation.

            :param trust: A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.
            :param subject_alternative_names: A reference to an object that represents the SANs for a Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontext.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tls_validation_context_property = appmesh.CfnVirtualNode.TlsValidationContextProperty(
                    trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                        acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                            certificate_authority_arns=["certificateAuthorityArns"]
                        ),
                        file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                            certificate_chain="certificateChain"
                        ),
                        sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                            secret_name="secretName"
                        )
                    ),
                
                    # the properties below are optional
                    subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                        match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                            exact=["exact"]
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.TlsValidationContextProperty.__init__)
                check_type(argname="argument trust", value=trust, expected_type=type_hints["trust"])
                check_type(argname="argument subject_alternative_names", value=subject_alternative_names, expected_type=type_hints["subject_alternative_names"])
            self._values: typing.Dict[str, typing.Any] = {
                "trust": trust,
            }
            if subject_alternative_names is not None:
                self._values["subject_alternative_names"] = subject_alternative_names

        @builtins.property
        def trust(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextTrustProperty"]:
            '''A reference to where to retrieve the trust chain when validating a peer’s Transport Layer Security (TLS) certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontext.html#cfn-appmesh-virtualnode-tlsvalidationcontext-trust
            '''
            result = self._values.get("trust")
            assert result is not None, "Required property 'trust' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextTrustProperty"], result)

        @builtins.property
        def subject_alternative_names(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.SubjectAlternativeNamesProperty"]]:
            '''A reference to an object that represents the SANs for a Transport Layer Security (TLS) validation context.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontext.html#cfn-appmesh-virtualnode-tlsvalidationcontext-subjectalternativenames
            '''
            result = self._values.get("subject_alternative_names")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.SubjectAlternativeNamesProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TlsValidationContextProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"secret_name": "secretName"},
    )
    class TlsValidationContextSdsTrustProperty:
        def __init__(self, *, secret_name: builtins.str) -> None:
            '''An object that represents a Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            The proxy must be configured with a local SDS provider via a Unix Domain Socket. See App Mesh `TLS documentation <https://docs.aws.amazon.com/app-mesh/latest/userguide/tls.html>`_ for more info.

            :param secret_name: A reference to an object that represents the name of the secret for a Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontextsdstrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tls_validation_context_sds_trust_property = appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                    secret_name="secretName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.TlsValidationContextSdsTrustProperty.__init__)
                check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
            self._values: typing.Dict[str, typing.Any] = {
                "secret_name": secret_name,
            }

        @builtins.property
        def secret_name(self) -> builtins.str:
            '''A reference to an object that represents the name of the secret for a Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontextsdstrust.html#cfn-appmesh-virtualnode-tlsvalidationcontextsdstrust-secretname
            '''
            result = self._values.get("secret_name")
            assert result is not None, "Required property 'secret_name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TlsValidationContextSdsTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.TlsValidationContextTrustProperty",
        jsii_struct_bases=[],
        name_mapping={"acm": "acm", "file": "file", "sds": "sds"},
    )
    class TlsValidationContextTrustProperty:
        def __init__(
            self,
            *,
            acm: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TlsValidationContextAcmTrustProperty", typing.Dict[str, typing.Any]]]] = None,
            file: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TlsValidationContextFileTrustProperty", typing.Dict[str, typing.Any]]]] = None,
            sds: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.TlsValidationContextSdsTrustProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a Transport Layer Security (TLS) validation context trust.

            :param acm: A reference to an object that represents a Transport Layer Security (TLS) validation context trust for an AWS Certificate Manager certificate.
            :param file: An object that represents a Transport Layer Security (TLS) validation context trust for a local file.
            :param sds: A reference to an object that represents a Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontexttrust.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                tls_validation_context_trust_property = appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                    acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                        certificate_authority_arns=["certificateAuthorityArns"]
                    ),
                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                        certificate_chain="certificateChain"
                    ),
                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                        secret_name="secretName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.TlsValidationContextTrustProperty.__init__)
                check_type(argname="argument acm", value=acm, expected_type=type_hints["acm"])
                check_type(argname="argument file", value=file, expected_type=type_hints["file"])
                check_type(argname="argument sds", value=sds, expected_type=type_hints["sds"])
            self._values: typing.Dict[str, typing.Any] = {}
            if acm is not None:
                self._values["acm"] = acm
            if file is not None:
                self._values["file"] = file
            if sds is not None:
                self._values["sds"] = sds

        @builtins.property
        def acm(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextAcmTrustProperty"]]:
            '''A reference to an object that represents a Transport Layer Security (TLS) validation context trust for an AWS Certificate Manager certificate.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontexttrust.html#cfn-appmesh-virtualnode-tlsvalidationcontexttrust-acm
            '''
            result = self._values.get("acm")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextAcmTrustProperty"]], result)

        @builtins.property
        def file(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextFileTrustProperty"]]:
            '''An object that represents a Transport Layer Security (TLS) validation context trust for a local file.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontexttrust.html#cfn-appmesh-virtualnode-tlsvalidationcontexttrust-file
            '''
            result = self._values.get("file")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextFileTrustProperty"]], result)

        @builtins.property
        def sds(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextSdsTrustProperty"]]:
            '''A reference to an object that represents a Transport Layer Security (TLS) Secret Discovery Service validation context trust.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontexttrust.html#cfn-appmesh-virtualnode-tlsvalidationcontexttrust-sds
            '''
            result = self._values.get("sds")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.TlsValidationContextSdsTrustProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TlsValidationContextTrustProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.VirtualNodeConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={"grpc": "grpc", "http": "http", "http2": "http2", "tcp": "tcp"},
    )
    class VirtualNodeConnectionPoolProperty:
        def __init__(
            self,
            *,
            grpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
            http: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
            http2: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
            tcp: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the type of virtual node connection pool.

            Only one protocol is used at a time and should be the same protocol as the one chosen under port mapping.

            If not present the default value for ``maxPendingRequests`` is ``2147483647`` .

            :param grpc: An object that represents a type of connection pool.
            :param http: An object that represents a type of connection pool.
            :param http2: An object that represents a type of connection pool.
            :param tcp: An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodeconnectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_node_connection_pool_property = appmesh.CfnVirtualNode.VirtualNodeConnectionPoolProperty(
                    grpc=appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty(
                        max_requests=123
                    ),
                    http=appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty(
                        max_connections=123,
                
                        # the properties below are optional
                        max_pending_requests=123
                    ),
                    http2=appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty(
                        max_requests=123
                    ),
                    tcp=appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty(
                        max_connections=123
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.VirtualNodeConnectionPoolProperty.__init__)
                check_type(argname="argument grpc", value=grpc, expected_type=type_hints["grpc"])
                check_type(argname="argument http", value=http, expected_type=type_hints["http"])
                check_type(argname="argument http2", value=http2, expected_type=type_hints["http2"])
                check_type(argname="argument tcp", value=tcp, expected_type=type_hints["tcp"])
            self._values: typing.Dict[str, typing.Any] = {}
            if grpc is not None:
                self._values["grpc"] = grpc
            if http is not None:
                self._values["http"] = http
            if http2 is not None:
                self._values["http2"] = http2
            if tcp is not None:
                self._values["tcp"] = tcp

        @builtins.property
        def grpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty"]]:
            '''An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodeconnectionpool.html#cfn-appmesh-virtualnode-virtualnodeconnectionpool-grpc
            '''
            result = self._values.get("grpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty"]], result)

        @builtins.property
        def http(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty"]]:
            '''An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodeconnectionpool.html#cfn-appmesh-virtualnode-virtualnodeconnectionpool-http
            '''
            result = self._values.get("http")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty"]], result)

        @builtins.property
        def http2(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty"]]:
            '''An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodeconnectionpool.html#cfn-appmesh-virtualnode-virtualnodeconnectionpool-http2
            '''
            result = self._values.get("http2")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty"]], result)

        @builtins.property
        def tcp(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty"]]:
            '''An object that represents a type of connection pool.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodeconnectionpool.html#cfn-appmesh-virtualnode-virtualnodeconnectionpool-tcp
            '''
            result = self._values.get("tcp")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualNodeConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={"max_requests": "maxRequests"},
    )
    class VirtualNodeGrpcConnectionPoolProperty:
        def __init__(self, *, max_requests: jsii.Number) -> None:
            '''An object that represents a type of connection pool.

            :param max_requests: Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodegrpcconnectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_node_grpc_connection_pool_property = appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty(
                    max_requests=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty.__init__)
                check_type(argname="argument max_requests", value=max_requests, expected_type=type_hints["max_requests"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_requests": max_requests,
            }

        @builtins.property
        def max_requests(self) -> jsii.Number:
            '''Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodegrpcconnectionpool.html#cfn-appmesh-virtualnode-virtualnodegrpcconnectionpool-maxrequests
            '''
            result = self._values.get("max_requests")
            assert result is not None, "Required property 'max_requests' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualNodeGrpcConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={"max_requests": "maxRequests"},
    )
    class VirtualNodeHttp2ConnectionPoolProperty:
        def __init__(self, *, max_requests: jsii.Number) -> None:
            '''An object that represents a type of connection pool.

            :param max_requests: Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodehttp2connectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_node_http2_connection_pool_property = appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty(
                    max_requests=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty.__init__)
                check_type(argname="argument max_requests", value=max_requests, expected_type=type_hints["max_requests"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_requests": max_requests,
            }

        @builtins.property
        def max_requests(self) -> jsii.Number:
            '''Maximum number of inflight requests Envoy can concurrently support across hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodehttp2connectionpool.html#cfn-appmesh-virtualnode-virtualnodehttp2connectionpool-maxrequests
            '''
            result = self._values.get("max_requests")
            assert result is not None, "Required property 'max_requests' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualNodeHttp2ConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={
            "max_connections": "maxConnections",
            "max_pending_requests": "maxPendingRequests",
        },
    )
    class VirtualNodeHttpConnectionPoolProperty:
        def __init__(
            self,
            *,
            max_connections: jsii.Number,
            max_pending_requests: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''An object that represents a type of connection pool.

            :param max_connections: Maximum number of outbound TCP connections Envoy can establish concurrently with all hosts in upstream cluster.
            :param max_pending_requests: Number of overflowing requests after ``max_connections`` Envoy will queue to upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodehttpconnectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_node_http_connection_pool_property = appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty(
                    max_connections=123,
                
                    # the properties below are optional
                    max_pending_requests=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty.__init__)
                check_type(argname="argument max_connections", value=max_connections, expected_type=type_hints["max_connections"])
                check_type(argname="argument max_pending_requests", value=max_pending_requests, expected_type=type_hints["max_pending_requests"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_connections": max_connections,
            }
            if max_pending_requests is not None:
                self._values["max_pending_requests"] = max_pending_requests

        @builtins.property
        def max_connections(self) -> jsii.Number:
            '''Maximum number of outbound TCP connections Envoy can establish concurrently with all hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodehttpconnectionpool.html#cfn-appmesh-virtualnode-virtualnodehttpconnectionpool-maxconnections
            '''
            result = self._values.get("max_connections")
            assert result is not None, "Required property 'max_connections' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def max_pending_requests(self) -> typing.Optional[jsii.Number]:
            '''Number of overflowing requests after ``max_connections`` Envoy will queue to upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodehttpconnectionpool.html#cfn-appmesh-virtualnode-virtualnodehttpconnectionpool-maxpendingrequests
            '''
            result = self._values.get("max_pending_requests")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualNodeHttpConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.VirtualNodeSpecProperty",
        jsii_struct_bases=[],
        name_mapping={
            "backend_defaults": "backendDefaults",
            "backends": "backends",
            "listeners": "listeners",
            "logging": "logging",
            "service_discovery": "serviceDiscovery",
        },
    )
    class VirtualNodeSpecProperty:
        def __init__(
            self,
            *,
            backend_defaults: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.BackendDefaultsProperty", typing.Dict[str, typing.Any]]]] = None,
            backends: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.BackendProperty", typing.Dict[str, typing.Any]]]]]] = None,
            listeners: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ListenerProperty", typing.Dict[str, typing.Any]]]]]] = None,
            logging: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.LoggingProperty", typing.Dict[str, typing.Any]]]] = None,
            service_discovery: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ServiceDiscoveryProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the specification of a virtual node.

            :param backend_defaults: A reference to an object that represents the defaults for backends.
            :param backends: The backends that the virtual node is expected to send outbound traffic to.
            :param listeners: The listener that the virtual node is expected to receive inbound traffic from. You can specify one listener.
            :param logging: The inbound and outbound access logging information for the virtual node.
            :param service_discovery: The service discovery information for the virtual node. If your virtual node does not expect ingress traffic, you can omit this parameter. If you specify a ``listener`` , then you must specify service discovery information.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodespec.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_node_spec_property = appmesh.CfnVirtualNode.VirtualNodeSpecProperty(
                    backend_defaults=appmesh.CfnVirtualNode.BackendDefaultsProperty(
                        client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                            tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                                validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                    trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                        acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                            certificate_authority_arns=["certificateAuthorityArns"]
                                        ),
                                        file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                            certificate_chain="certificateChain"
                                        ),
                                        sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                            secret_name="secretName"
                                        )
                                    ),
                
                                    # the properties below are optional
                                    subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                        match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                            exact=["exact"]
                                        )
                                    )
                                ),
                
                                # the properties below are optional
                                certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                        certificate_chain="certificateChain",
                                        private_key="privateKey"
                                    ),
                                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                        secret_name="secretName"
                                    )
                                ),
                                enforce=False,
                                ports=[123]
                            )
                        )
                    ),
                    backends=[appmesh.CfnVirtualNode.BackendProperty(
                        virtual_service=appmesh.CfnVirtualNode.VirtualServiceBackendProperty(
                            virtual_service_name="virtualServiceName",
                
                            # the properties below are optional
                            client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                                tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                                    validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                        trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                            acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                                certificate_authority_arns=["certificateAuthorityArns"]
                                            ),
                                            file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                                certificate_chain="certificateChain"
                                            ),
                                            sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                                secret_name="secretName"
                                            )
                                        ),
                
                                        # the properties below are optional
                                        subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                            match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                                exact=["exact"]
                                            )
                                        )
                                    ),
                
                                    # the properties below are optional
                                    certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                        file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                            certificate_chain="certificateChain",
                                            private_key="privateKey"
                                        ),
                                        sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                            secret_name="secretName"
                                        )
                                    ),
                                    enforce=False,
                                    ports=[123]
                                )
                            )
                        )
                    )],
                    listeners=[appmesh.CfnVirtualNode.ListenerProperty(
                        port_mapping=appmesh.CfnVirtualNode.PortMappingProperty(
                            port=123,
                            protocol="protocol"
                        ),
                
                        # the properties below are optional
                        connection_pool=appmesh.CfnVirtualNode.VirtualNodeConnectionPoolProperty(
                            grpc=appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty(
                                max_requests=123
                            ),
                            http=appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty(
                                max_connections=123,
                
                                # the properties below are optional
                                max_pending_requests=123
                            ),
                            http2=appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty(
                                max_requests=123
                            ),
                            tcp=appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty(
                                max_connections=123
                            )
                        ),
                        health_check=appmesh.CfnVirtualNode.HealthCheckProperty(
                            healthy_threshold=123,
                            interval_millis=123,
                            protocol="protocol",
                            timeout_millis=123,
                            unhealthy_threshold=123,
                
                            # the properties below are optional
                            path="path",
                            port=123
                        ),
                        outlier_detection=appmesh.CfnVirtualNode.OutlierDetectionProperty(
                            base_ejection_duration=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            interval=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            max_ejection_percent=123,
                            max_server_errors=123
                        ),
                        timeout=appmesh.CfnVirtualNode.ListenerTimeoutProperty(
                            grpc=appmesh.CfnVirtualNode.GrpcTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                ),
                                per_request=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            ),
                            http=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                ),
                                per_request=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            ),
                            http2=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                ),
                                per_request=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            ),
                            tcp=appmesh.CfnVirtualNode.TcpTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            )
                        ),
                        tls=appmesh.CfnVirtualNode.ListenerTlsProperty(
                            certificate=appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                                acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                                    certificate_arn="certificateArn"
                                ),
                                file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            mode="mode",
                
                            # the properties below are optional
                            validation=appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty(
                                trust=appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
                
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            )
                        )
                    )],
                    logging=appmesh.CfnVirtualNode.LoggingProperty(
                        access_log=appmesh.CfnVirtualNode.AccessLogProperty(
                            file=appmesh.CfnVirtualNode.FileAccessLogProperty(
                                path="path",
                
                                # the properties below are optional
                                format=appmesh.CfnVirtualNode.LoggingFormatProperty(
                                    json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                                        key="key",
                                        value="value"
                                    )],
                                    text="text"
                                )
                            )
                        )
                    ),
                    service_discovery=appmesh.CfnVirtualNode.ServiceDiscoveryProperty(
                        aws_cloud_map=appmesh.CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty(
                            namespace_name="namespaceName",
                            service_name="serviceName",
                
                            # the properties below are optional
                            attributes=[appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty(
                                key="key",
                                value="value"
                            )],
                            ip_preference="ipPreference"
                        ),
                        dns=appmesh.CfnVirtualNode.DnsServiceDiscoveryProperty(
                            hostname="hostname",
                
                            # the properties below are optional
                            ip_preference="ipPreference",
                            response_type="responseType"
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.VirtualNodeSpecProperty.__init__)
                check_type(argname="argument backend_defaults", value=backend_defaults, expected_type=type_hints["backend_defaults"])
                check_type(argname="argument backends", value=backends, expected_type=type_hints["backends"])
                check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
                check_type(argname="argument logging", value=logging, expected_type=type_hints["logging"])
                check_type(argname="argument service_discovery", value=service_discovery, expected_type=type_hints["service_discovery"])
            self._values: typing.Dict[str, typing.Any] = {}
            if backend_defaults is not None:
                self._values["backend_defaults"] = backend_defaults
            if backends is not None:
                self._values["backends"] = backends
            if listeners is not None:
                self._values["listeners"] = listeners
            if logging is not None:
                self._values["logging"] = logging
            if service_discovery is not None:
                self._values["service_discovery"] = service_discovery

        @builtins.property
        def backend_defaults(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.BackendDefaultsProperty"]]:
            '''A reference to an object that represents the defaults for backends.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodespec.html#cfn-appmesh-virtualnode-virtualnodespec-backenddefaults
            '''
            result = self._values.get("backend_defaults")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.BackendDefaultsProperty"]], result)

        @builtins.property
        def backends(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.BackendProperty"]]]]:
            '''The backends that the virtual node is expected to send outbound traffic to.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodespec.html#cfn-appmesh-virtualnode-virtualnodespec-backends
            '''
            result = self._values.get("backends")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.BackendProperty"]]]], result)

        @builtins.property
        def listeners(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerProperty"]]]]:
            '''The listener that the virtual node is expected to receive inbound traffic from.

            You can specify one listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodespec.html#cfn-appmesh-virtualnode-virtualnodespec-listeners
            '''
            result = self._values.get("listeners")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ListenerProperty"]]]], result)

        @builtins.property
        def logging(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.LoggingProperty"]]:
            '''The inbound and outbound access logging information for the virtual node.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodespec.html#cfn-appmesh-virtualnode-virtualnodespec-logging
            '''
            result = self._values.get("logging")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.LoggingProperty"]], result)

        @builtins.property
        def service_discovery(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ServiceDiscoveryProperty"]]:
            '''The service discovery information for the virtual node.

            If your virtual node does not expect ingress traffic, you can omit this parameter. If you specify a ``listener`` , then you must specify service discovery information.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodespec.html#cfn-appmesh-virtualnode-virtualnodespec-servicediscovery
            '''
            result = self._values.get("service_discovery")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ServiceDiscoveryProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualNodeSpecProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty",
        jsii_struct_bases=[],
        name_mapping={"max_connections": "maxConnections"},
    )
    class VirtualNodeTcpConnectionPoolProperty:
        def __init__(self, *, max_connections: jsii.Number) -> None:
            '''An object that represents a type of connection pool.

            :param max_connections: Maximum number of outbound TCP connections Envoy can establish concurrently with all hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodetcpconnectionpool.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_node_tcp_connection_pool_property = appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty(
                    max_connections=123
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty.__init__)
                check_type(argname="argument max_connections", value=max_connections, expected_type=type_hints["max_connections"])
            self._values: typing.Dict[str, typing.Any] = {
                "max_connections": max_connections,
            }

        @builtins.property
        def max_connections(self) -> jsii.Number:
            '''Maximum number of outbound TCP connections Envoy can establish concurrently with all hosts in upstream cluster.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualnodetcpconnectionpool.html#cfn-appmesh-virtualnode-virtualnodetcpconnectionpool-maxconnections
            '''
            result = self._values.get("max_connections")
            assert result is not None, "Required property 'max_connections' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualNodeTcpConnectionPoolProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNode.VirtualServiceBackendProperty",
        jsii_struct_bases=[],
        name_mapping={
            "virtual_service_name": "virtualServiceName",
            "client_policy": "clientPolicy",
        },
    )
    class VirtualServiceBackendProperty:
        def __init__(
            self,
            *,
            virtual_service_name: builtins.str,
            client_policy: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualNode.ClientPolicyProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents a virtual service backend for a virtual node.

            :param virtual_service_name: The name of the virtual service that is acting as a virtual node backend.
            :param client_policy: A reference to an object that represents the client policy for a backend.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualservicebackend.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_service_backend_property = appmesh.CfnVirtualNode.VirtualServiceBackendProperty(
                    virtual_service_name="virtualServiceName",
                
                    # the properties below are optional
                    client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                        tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                            validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                    acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                        certificate_authority_arns=["certificateAuthorityArns"]
                                    ),
                                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
                
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            ),
                
                            # the properties below are optional
                            certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            enforce=False,
                            ports=[123]
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualNode.VirtualServiceBackendProperty.__init__)
                check_type(argname="argument virtual_service_name", value=virtual_service_name, expected_type=type_hints["virtual_service_name"])
                check_type(argname="argument client_policy", value=client_policy, expected_type=type_hints["client_policy"])
            self._values: typing.Dict[str, typing.Any] = {
                "virtual_service_name": virtual_service_name,
            }
            if client_policy is not None:
                self._values["client_policy"] = client_policy

        @builtins.property
        def virtual_service_name(self) -> builtins.str:
            '''The name of the virtual service that is acting as a virtual node backend.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualservicebackend.html#cfn-appmesh-virtualnode-virtualservicebackend-virtualservicename
            '''
            result = self._values.get("virtual_service_name")
            assert result is not None, "Required property 'virtual_service_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def client_policy(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientPolicyProperty"]]:
            '''A reference to an object that represents the client policy for a backend.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-virtualservicebackend.html#cfn-appmesh-virtualnode-virtualservicebackend-clientpolicy
            '''
            result = self._values.get("client_policy")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualNode.ClientPolicyProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualServiceBackendProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualNodeProps",
    jsii_struct_bases=[],
    name_mapping={
        "mesh_name": "meshName",
        "spec": "spec",
        "mesh_owner": "meshOwner",
        "tags": "tags",
        "virtual_node_name": "virtualNodeName",
    },
)
class CfnVirtualNodeProps:
    def __init__(
        self,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union[CfnVirtualNode.VirtualNodeSpecProperty, typing.Dict[str, typing.Any]]],
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``CfnVirtualNode``.

        :param mesh_name: The name of the service mesh to create the virtual node in.
        :param spec: The virtual node specification to apply.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual node to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        :param virtual_node_name: The name to use for the virtual node.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html
        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            cfn_virtual_node_props = appmesh.CfnVirtualNodeProps(
                mesh_name="meshName",
                spec=appmesh.CfnVirtualNode.VirtualNodeSpecProperty(
                    backend_defaults=appmesh.CfnVirtualNode.BackendDefaultsProperty(
                        client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                            tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                                validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                    trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                        acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                            certificate_authority_arns=["certificateAuthorityArns"]
                                        ),
                                        file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                            certificate_chain="certificateChain"
                                        ),
                                        sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                            secret_name="secretName"
                                        )
                                    ),
            
                                    # the properties below are optional
                                    subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                        match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                            exact=["exact"]
                                        )
                                    )
                                ),
            
                                # the properties below are optional
                                certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                        certificate_chain="certificateChain",
                                        private_key="privateKey"
                                    ),
                                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                        secret_name="secretName"
                                    )
                                ),
                                enforce=False,
                                ports=[123]
                            )
                        )
                    ),
                    backends=[appmesh.CfnVirtualNode.BackendProperty(
                        virtual_service=appmesh.CfnVirtualNode.VirtualServiceBackendProperty(
                            virtual_service_name="virtualServiceName",
            
                            # the properties below are optional
                            client_policy=appmesh.CfnVirtualNode.ClientPolicyProperty(
                                tls=appmesh.CfnVirtualNode.ClientPolicyTlsProperty(
                                    validation=appmesh.CfnVirtualNode.TlsValidationContextProperty(
                                        trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                                            acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                                                certificate_authority_arns=["certificateAuthorityArns"]
                                            ),
                                            file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                                certificate_chain="certificateChain"
                                            ),
                                            sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                                secret_name="secretName"
                                            )
                                        ),
            
                                        # the properties below are optional
                                        subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                            match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                                exact=["exact"]
                                            )
                                        )
                                    ),
            
                                    # the properties below are optional
                                    certificate=appmesh.CfnVirtualNode.ClientTlsCertificateProperty(
                                        file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                            certificate_chain="certificateChain",
                                            private_key="privateKey"
                                        ),
                                        sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                            secret_name="secretName"
                                        )
                                    ),
                                    enforce=False,
                                    ports=[123]
                                )
                            )
                        )
                    )],
                    listeners=[appmesh.CfnVirtualNode.ListenerProperty(
                        port_mapping=appmesh.CfnVirtualNode.PortMappingProperty(
                            port=123,
                            protocol="protocol"
                        ),
            
                        # the properties below are optional
                        connection_pool=appmesh.CfnVirtualNode.VirtualNodeConnectionPoolProperty(
                            grpc=appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty(
                                max_requests=123
                            ),
                            http=appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty(
                                max_connections=123,
            
                                # the properties below are optional
                                max_pending_requests=123
                            ),
                            http2=appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty(
                                max_requests=123
                            ),
                            tcp=appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty(
                                max_connections=123
                            )
                        ),
                        health_check=appmesh.CfnVirtualNode.HealthCheckProperty(
                            healthy_threshold=123,
                            interval_millis=123,
                            protocol="protocol",
                            timeout_millis=123,
                            unhealthy_threshold=123,
            
                            # the properties below are optional
                            path="path",
                            port=123
                        ),
                        outlier_detection=appmesh.CfnVirtualNode.OutlierDetectionProperty(
                            base_ejection_duration=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            interval=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            max_ejection_percent=123,
                            max_server_errors=123
                        ),
                        timeout=appmesh.CfnVirtualNode.ListenerTimeoutProperty(
                            grpc=appmesh.CfnVirtualNode.GrpcTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                ),
                                per_request=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            ),
                            http=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                ),
                                per_request=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            ),
                            http2=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                ),
                                per_request=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            ),
                            tcp=appmesh.CfnVirtualNode.TcpTimeoutProperty(
                                idle=appmesh.CfnVirtualNode.DurationProperty(
                                    unit="unit",
                                    value=123
                                )
                            )
                        ),
                        tls=appmesh.CfnVirtualNode.ListenerTlsProperty(
                            certificate=appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                                acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                                    certificate_arn="certificateArn"
                                ),
                                file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                    certificate_chain="certificateChain",
                                    private_key="privateKey"
                                ),
                                sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                    secret_name="secretName"
                                )
                            ),
                            mode="mode",
            
                            # the properties below are optional
                            validation=appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty(
                                trust=appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                        certificate_chain="certificateChain"
                                    ),
                                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                        secret_name="secretName"
                                    )
                                ),
            
                                # the properties below are optional
                                subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                    match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                        exact=["exact"]
                                    )
                                )
                            )
                        )
                    )],
                    logging=appmesh.CfnVirtualNode.LoggingProperty(
                        access_log=appmesh.CfnVirtualNode.AccessLogProperty(
                            file=appmesh.CfnVirtualNode.FileAccessLogProperty(
                                path="path",
            
                                # the properties below are optional
                                format=appmesh.CfnVirtualNode.LoggingFormatProperty(
                                    json=[appmesh.CfnVirtualNode.JsonFormatRefProperty(
                                        key="key",
                                        value="value"
                                    )],
                                    text="text"
                                )
                            )
                        )
                    ),
                    service_discovery=appmesh.CfnVirtualNode.ServiceDiscoveryProperty(
                        aws_cloud_map=appmesh.CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty(
                            namespace_name="namespaceName",
                            service_name="serviceName",
            
                            # the properties below are optional
                            attributes=[appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty(
                                key="key",
                                value="value"
                            )],
                            ip_preference="ipPreference"
                        ),
                        dns=appmesh.CfnVirtualNode.DnsServiceDiscoveryProperty(
                            hostname="hostname",
            
                            # the properties below are optional
                            ip_preference="ipPreference",
                            response_type="responseType"
                        )
                    )
                ),
            
                # the properties below are optional
                mesh_owner="meshOwner",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )],
                virtual_node_name="virtualNodeName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualNodeProps.__init__)
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument mesh_owner", value=mesh_owner, expected_type=type_hints["mesh_owner"])
            check_type(argname="argument tags", value=tags, expected_type=type_hints["tags"])
            check_type(argname="argument virtual_node_name", value=virtual_node_name, expected_type=type_hints["virtual_node_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh_name": mesh_name,
            "spec": spec,
        }
        if mesh_owner is not None:
            self._values["mesh_owner"] = mesh_owner
        if tags is not None:
            self._values["tags"] = tags
        if virtual_node_name is not None:
            self._values["virtual_node_name"] = virtual_node_name

    @builtins.property
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the virtual node in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-meshname
        '''
        result = self._values.get("mesh_name")
        assert result is not None, "Required property 'mesh_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnVirtualNode.VirtualNodeSpecProperty]:
        '''The virtual node specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnVirtualNode.VirtualNodeSpecProperty], result)

    @builtins.property
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-meshowner
        '''
        result = self._values.get("mesh_owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''Optional metadata that you can apply to the virtual node to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def virtual_node_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the virtual node.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualnode.html#cfn-appmesh-virtualnode-virtualnodename
        '''
        result = self._values.get("virtual_node_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVirtualNodeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVirtualRouter(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualRouter",
):
    '''A CloudFormation ``AWS::AppMesh::VirtualRouter``.

    Creates a virtual router within a service mesh.

    Specify a ``listener`` for any inbound traffic that your virtual router receives. Create a virtual router for each protocol and port that you need to route. Virtual routers handle traffic for one or more virtual services within your mesh. After you create your virtual router, create and associate routes for your virtual router that direct incoming requests to different virtual nodes.

    For more information about virtual routers, see `Virtual routers <https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_routers.html>`_ .

    :cloudformationResource: AWS::AppMesh::VirtualRouter
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        cfn_virtual_router = appmesh.CfnVirtualRouter(self, "MyCfnVirtualRouter",
            mesh_name="meshName",
            spec=appmesh.CfnVirtualRouter.VirtualRouterSpecProperty(
                listeners=[appmesh.CfnVirtualRouter.VirtualRouterListenerProperty(
                    port_mapping=appmesh.CfnVirtualRouter.PortMappingProperty(
                        port=123,
                        protocol="protocol"
                    )
                )]
            ),
        
            # the properties below are optional
            mesh_owner="meshOwner",
            tags=[CfnTag(
                key="key",
                value="value"
            )],
            virtual_router_name="virtualRouterName"
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualRouter.VirtualRouterSpecProperty", typing.Dict[str, typing.Any]]],
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::AppMesh::VirtualRouter``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param mesh_name: The name of the service mesh to create the virtual router in.
        :param spec: The virtual router specification to apply.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual router to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        :param virtual_router_name: The name to use for the virtual router.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualRouter.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = CfnVirtualRouterProps(
            mesh_name=mesh_name,
            spec=spec,
            mesh_owner=mesh_owner,
            tags=tags,
            virtual_router_name=virtual_router_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualRouter.inspect)
            check_type(argname="argument inspector", value=inspector, expected_type=type_hints["inspector"])
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualRouter._render_properties)
            check_type(argname="argument props", value=props, expected_type=type_hints["props"])
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''The full Amazon Resource Name (ARN) for the virtual router.

        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshName")
    def attr_mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the virtual router resides in.

        :cloudformationAttribute: MeshName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshOwner")
    def attr_mesh_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: MeshOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrResourceOwner")
    def attr_resource_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the resource owner.

        If the account ID is not your own, then it's the ID of the mesh owner or of another account that the mesh is shared with. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: ResourceOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrUid")
    def attr_uid(self) -> builtins.str:
        '''The unique identifier for the virtual router.

        :cloudformationAttribute: Uid
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrUid"))

    @builtins.property
    @jsii.member(jsii_name="attrVirtualRouterName")
    def attr_virtual_router_name(self) -> builtins.str:
        '''The name of the virtual router.

        :cloudformationAttribute: VirtualRouterName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVirtualRouterName"))

    @builtins.property
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''Optional metadata that you can apply to the virtual router to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the virtual router in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-meshname
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))

    @mesh_name.setter
    def mesh_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualRouter, "mesh_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshName", value)

    @builtins.property
    @jsii.member(jsii_name="spec")
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualRouter.VirtualRouterSpecProperty"]:
        '''The virtual router specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-spec
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualRouter.VirtualRouterSpecProperty"], jsii.get(self, "spec"))

    @spec.setter
    def spec(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnVirtualRouter.VirtualRouterSpecProperty"],
    ) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualRouter, "spec").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "spec", value)

    @builtins.property
    @jsii.member(jsii_name="meshOwner")
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-meshowner
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "meshOwner"))

    @mesh_owner.setter
    def mesh_owner(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualRouter, "mesh_owner").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshOwner", value)

    @builtins.property
    @jsii.member(jsii_name="virtualRouterName")
    def virtual_router_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the virtual router.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-virtualroutername
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "virtualRouterName"))

    @virtual_router_name.setter
    def virtual_router_name(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualRouter, "virtual_router_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "virtualRouterName", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualRouter.PortMappingProperty",
        jsii_struct_bases=[],
        name_mapping={"port": "port", "protocol": "protocol"},
    )
    class PortMappingProperty:
        def __init__(self, *, port: jsii.Number, protocol: builtins.str) -> None:
            '''An object representing a virtual router listener port mapping.

            :param port: The port used for the port mapping.
            :param protocol: The protocol used for the port mapping. Specify one protocol.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualrouter-portmapping.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                port_mapping_property = appmesh.CfnVirtualRouter.PortMappingProperty(
                    port=123,
                    protocol="protocol"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualRouter.PortMappingProperty.__init__)
                check_type(argname="argument port", value=port, expected_type=type_hints["port"])
                check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
            self._values: typing.Dict[str, typing.Any] = {
                "port": port,
                "protocol": protocol,
            }

        @builtins.property
        def port(self) -> jsii.Number:
            '''The port used for the port mapping.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualrouter-portmapping.html#cfn-appmesh-virtualrouter-portmapping-port
            '''
            result = self._values.get("port")
            assert result is not None, "Required property 'port' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def protocol(self) -> builtins.str:
            '''The protocol used for the port mapping.

            Specify one protocol.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualrouter-portmapping.html#cfn-appmesh-virtualrouter-portmapping-protocol
            '''
            result = self._values.get("protocol")
            assert result is not None, "Required property 'protocol' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PortMappingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualRouter.VirtualRouterListenerProperty",
        jsii_struct_bases=[],
        name_mapping={"port_mapping": "portMapping"},
    )
    class VirtualRouterListenerProperty:
        def __init__(
            self,
            *,
            port_mapping: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualRouter.PortMappingProperty", typing.Dict[str, typing.Any]]],
        ) -> None:
            '''An object that represents a virtual router listener.

            :param port_mapping: The port mapping information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualrouter-virtualrouterlistener.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_router_listener_property = appmesh.CfnVirtualRouter.VirtualRouterListenerProperty(
                    port_mapping=appmesh.CfnVirtualRouter.PortMappingProperty(
                        port=123,
                        protocol="protocol"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualRouter.VirtualRouterListenerProperty.__init__)
                check_type(argname="argument port_mapping", value=port_mapping, expected_type=type_hints["port_mapping"])
            self._values: typing.Dict[str, typing.Any] = {
                "port_mapping": port_mapping,
            }

        @builtins.property
        def port_mapping(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualRouter.PortMappingProperty"]:
            '''The port mapping information for the listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualrouter-virtualrouterlistener.html#cfn-appmesh-virtualrouter-virtualrouterlistener-portmapping
            '''
            result = self._values.get("port_mapping")
            assert result is not None, "Required property 'port_mapping' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualRouter.PortMappingProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualRouterListenerProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualRouter.VirtualRouterSpecProperty",
        jsii_struct_bases=[],
        name_mapping={"listeners": "listeners"},
    )
    class VirtualRouterSpecProperty:
        def __init__(
            self,
            *,
            listeners: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualRouter.VirtualRouterListenerProperty", typing.Dict[str, typing.Any]]]]],
        ) -> None:
            '''An object that represents the specification of a virtual router.

            :param listeners: The listeners that the virtual router is expected to receive inbound traffic from. You can specify one listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualrouter-virtualrouterspec.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_router_spec_property = appmesh.CfnVirtualRouter.VirtualRouterSpecProperty(
                    listeners=[appmesh.CfnVirtualRouter.VirtualRouterListenerProperty(
                        port_mapping=appmesh.CfnVirtualRouter.PortMappingProperty(
                            port=123,
                            protocol="protocol"
                        )
                    )]
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualRouter.VirtualRouterSpecProperty.__init__)
                check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
            self._values: typing.Dict[str, typing.Any] = {
                "listeners": listeners,
            }

        @builtins.property
        def listeners(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualRouter.VirtualRouterListenerProperty"]]]:
            '''The listeners that the virtual router is expected to receive inbound traffic from.

            You can specify one listener.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualrouter-virtualrouterspec.html#cfn-appmesh-virtualrouter-virtualrouterspec-listeners
            '''
            result = self._values.get("listeners")
            assert result is not None, "Required property 'listeners' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualRouter.VirtualRouterListenerProperty"]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualRouterSpecProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualRouterProps",
    jsii_struct_bases=[],
    name_mapping={
        "mesh_name": "meshName",
        "spec": "spec",
        "mesh_owner": "meshOwner",
        "tags": "tags",
        "virtual_router_name": "virtualRouterName",
    },
)
class CfnVirtualRouterProps:
    def __init__(
        self,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union[CfnVirtualRouter.VirtualRouterSpecProperty, typing.Dict[str, typing.Any]]],
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``CfnVirtualRouter``.

        :param mesh_name: The name of the service mesh to create the virtual router in.
        :param spec: The virtual router specification to apply.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual router to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        :param virtual_router_name: The name to use for the virtual router.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html
        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            cfn_virtual_router_props = appmesh.CfnVirtualRouterProps(
                mesh_name="meshName",
                spec=appmesh.CfnVirtualRouter.VirtualRouterSpecProperty(
                    listeners=[appmesh.CfnVirtualRouter.VirtualRouterListenerProperty(
                        port_mapping=appmesh.CfnVirtualRouter.PortMappingProperty(
                            port=123,
                            protocol="protocol"
                        )
                    )]
                ),
            
                # the properties below are optional
                mesh_owner="meshOwner",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )],
                virtual_router_name="virtualRouterName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualRouterProps.__init__)
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument mesh_owner", value=mesh_owner, expected_type=type_hints["mesh_owner"])
            check_type(argname="argument tags", value=tags, expected_type=type_hints["tags"])
            check_type(argname="argument virtual_router_name", value=virtual_router_name, expected_type=type_hints["virtual_router_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh_name": mesh_name,
            "spec": spec,
        }
        if mesh_owner is not None:
            self._values["mesh_owner"] = mesh_owner
        if tags is not None:
            self._values["tags"] = tags
        if virtual_router_name is not None:
            self._values["virtual_router_name"] = virtual_router_name

    @builtins.property
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the virtual router in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-meshname
        '''
        result = self._values.get("mesh_name")
        assert result is not None, "Required property 'mesh_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnVirtualRouter.VirtualRouterSpecProperty]:
        '''The virtual router specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnVirtualRouter.VirtualRouterSpecProperty], result)

    @builtins.property
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-meshowner
        '''
        result = self._values.get("mesh_owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''Optional metadata that you can apply to the virtual router to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def virtual_router_name(self) -> typing.Optional[builtins.str]:
        '''The name to use for the virtual router.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualrouter.html#cfn-appmesh-virtualrouter-virtualroutername
        '''
        result = self._values.get("virtual_router_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVirtualRouterProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVirtualService(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualService",
):
    '''A CloudFormation ``AWS::AppMesh::VirtualService``.

    Creates a virtual service within a service mesh.

    A virtual service is an abstraction of a real service that is provided by a virtual node directly or indirectly by means of a virtual router. Dependent services call your virtual service by its ``virtualServiceName`` , and those requests are routed to the virtual node or virtual router that is specified as the provider for the virtual service.

    For more information about virtual services, see `Virtual services <https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_services.html>`_ .

    :cloudformationResource: AWS::AppMesh::VirtualService
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        cfn_virtual_service = appmesh.CfnVirtualService(self, "MyCfnVirtualService",
            mesh_name="meshName",
            spec=appmesh.CfnVirtualService.VirtualServiceSpecProperty(
                provider=appmesh.CfnVirtualService.VirtualServiceProviderProperty(
                    virtual_node=appmesh.CfnVirtualService.VirtualNodeServiceProviderProperty(
                        virtual_node_name="virtualNodeName"
                    ),
                    virtual_router=appmesh.CfnVirtualService.VirtualRouterServiceProviderProperty(
                        virtual_router_name="virtualRouterName"
                    )
                )
            ),
            virtual_service_name="virtualServiceName",
        
            # the properties below are optional
            mesh_owner="meshOwner",
            tags=[CfnTag(
                key="key",
                value="value"
            )]
        )
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualService.VirtualServiceSpecProperty", typing.Dict[str, typing.Any]]],
        virtual_service_name: builtins.str,
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Create a new ``AWS::AppMesh::VirtualService``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param mesh_name: The name of the service mesh to create the virtual service in.
        :param spec: The virtual service specification to apply.
        :param virtual_service_name: The name to use for the virtual service.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual service to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualService.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = CfnVirtualServiceProps(
            mesh_name=mesh_name,
            spec=spec,
            virtual_service_name=virtual_service_name,
            mesh_owner=mesh_owner,
            tags=tags,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualService.inspect)
            check_type(argname="argument inspector", value=inspector, expected_type=type_hints["inspector"])
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualService._render_properties)
            check_type(argname="argument props", value=props, expected_type=type_hints["props"])
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''The full Amazon Resource Name (ARN) for the virtual service.

        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshName")
    def attr_mesh_name(self) -> builtins.str:
        '''The name of the service mesh that the virtual service resides in.

        :cloudformationAttribute: MeshName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshName"))

    @builtins.property
    @jsii.member(jsii_name="attrMeshOwner")
    def attr_mesh_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then it's the ID of the account that shared the mesh with your account. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: MeshOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMeshOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrResourceOwner")
    def attr_resource_owner(self) -> builtins.str:
        '''The AWS IAM account ID of the resource owner.

        If the account ID is not your own, then it's the ID of the mesh owner or of another account that the mesh is shared with. For more information about mesh sharing, see `Working with Shared Meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :cloudformationAttribute: ResourceOwner
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceOwner"))

    @builtins.property
    @jsii.member(jsii_name="attrUid")
    def attr_uid(self) -> builtins.str:
        '''The unique identifier for the virtual service.

        :cloudformationAttribute: Uid
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrUid"))

    @builtins.property
    @jsii.member(jsii_name="attrVirtualServiceName")
    def attr_virtual_service_name(self) -> builtins.str:
        '''The name of the virtual service.

        :cloudformationAttribute: VirtualServiceName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVirtualServiceName"))

    @builtins.property
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''Optional metadata that you can apply to the virtual service to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the virtual service in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-meshname
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))

    @mesh_name.setter
    def mesh_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualService, "mesh_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshName", value)

    @builtins.property
    @jsii.member(jsii_name="spec")
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualServiceSpecProperty"]:
        '''The virtual service specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-spec
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualServiceSpecProperty"], jsii.get(self, "spec"))

    @spec.setter
    def spec(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualServiceSpecProperty"],
    ) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualService, "spec").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "spec", value)

    @builtins.property
    @jsii.member(jsii_name="virtualServiceName")
    def virtual_service_name(self) -> builtins.str:
        '''The name to use for the virtual service.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-virtualservicename
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualServiceName"))

    @virtual_service_name.setter
    def virtual_service_name(self, value: builtins.str) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualService, "virtual_service_name").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "virtualServiceName", value)

    @builtins.property
    @jsii.member(jsii_name="meshOwner")
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-meshowner
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "meshOwner"))

    @mesh_owner.setter
    def mesh_owner(self, value: typing.Optional[builtins.str]) -> None:
        if __debug__:
            type_hints = typing.get_type_hints(getattr(CfnVirtualService, "mesh_owner").fset)
            check_type(argname="argument value", value=value, expected_type=type_hints["value"])
        jsii.set(self, "meshOwner", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualService.VirtualNodeServiceProviderProperty",
        jsii_struct_bases=[],
        name_mapping={"virtual_node_name": "virtualNodeName"},
    )
    class VirtualNodeServiceProviderProperty:
        def __init__(self, *, virtual_node_name: builtins.str) -> None:
            '''An object that represents a virtual node service provider.

            :param virtual_node_name: The name of the virtual node that is acting as a service provider.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualnodeserviceprovider.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_node_service_provider_property = appmesh.CfnVirtualService.VirtualNodeServiceProviderProperty(
                    virtual_node_name="virtualNodeName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualService.VirtualNodeServiceProviderProperty.__init__)
                check_type(argname="argument virtual_node_name", value=virtual_node_name, expected_type=type_hints["virtual_node_name"])
            self._values: typing.Dict[str, typing.Any] = {
                "virtual_node_name": virtual_node_name,
            }

        @builtins.property
        def virtual_node_name(self) -> builtins.str:
            '''The name of the virtual node that is acting as a service provider.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualnodeserviceprovider.html#cfn-appmesh-virtualservice-virtualnodeserviceprovider-virtualnodename
            '''
            result = self._values.get("virtual_node_name")
            assert result is not None, "Required property 'virtual_node_name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualNodeServiceProviderProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualService.VirtualRouterServiceProviderProperty",
        jsii_struct_bases=[],
        name_mapping={"virtual_router_name": "virtualRouterName"},
    )
    class VirtualRouterServiceProviderProperty:
        def __init__(self, *, virtual_router_name: builtins.str) -> None:
            '''An object that represents a virtual node service provider.

            :param virtual_router_name: The name of the virtual router that is acting as a service provider.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualrouterserviceprovider.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_router_service_provider_property = appmesh.CfnVirtualService.VirtualRouterServiceProviderProperty(
                    virtual_router_name="virtualRouterName"
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualService.VirtualRouterServiceProviderProperty.__init__)
                check_type(argname="argument virtual_router_name", value=virtual_router_name, expected_type=type_hints["virtual_router_name"])
            self._values: typing.Dict[str, typing.Any] = {
                "virtual_router_name": virtual_router_name,
            }

        @builtins.property
        def virtual_router_name(self) -> builtins.str:
            '''The name of the virtual router that is acting as a service provider.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualrouterserviceprovider.html#cfn-appmesh-virtualservice-virtualrouterserviceprovider-virtualroutername
            '''
            result = self._values.get("virtual_router_name")
            assert result is not None, "Required property 'virtual_router_name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualRouterServiceProviderProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualService.VirtualServiceProviderProperty",
        jsii_struct_bases=[],
        name_mapping={
            "virtual_node": "virtualNode",
            "virtual_router": "virtualRouter",
        },
    )
    class VirtualServiceProviderProperty:
        def __init__(
            self,
            *,
            virtual_node: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualService.VirtualNodeServiceProviderProperty", typing.Dict[str, typing.Any]]]] = None,
            virtual_router: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualService.VirtualRouterServiceProviderProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the provider for a virtual service.

            :param virtual_node: The virtual node associated with a virtual service.
            :param virtual_router: The virtual router associated with a virtual service.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualserviceprovider.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_service_provider_property = appmesh.CfnVirtualService.VirtualServiceProviderProperty(
                    virtual_node=appmesh.CfnVirtualService.VirtualNodeServiceProviderProperty(
                        virtual_node_name="virtualNodeName"
                    ),
                    virtual_router=appmesh.CfnVirtualService.VirtualRouterServiceProviderProperty(
                        virtual_router_name="virtualRouterName"
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualService.VirtualServiceProviderProperty.__init__)
                check_type(argname="argument virtual_node", value=virtual_node, expected_type=type_hints["virtual_node"])
                check_type(argname="argument virtual_router", value=virtual_router, expected_type=type_hints["virtual_router"])
            self._values: typing.Dict[str, typing.Any] = {}
            if virtual_node is not None:
                self._values["virtual_node"] = virtual_node
            if virtual_router is not None:
                self._values["virtual_router"] = virtual_router

        @builtins.property
        def virtual_node(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualNodeServiceProviderProperty"]]:
            '''The virtual node associated with a virtual service.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualserviceprovider.html#cfn-appmesh-virtualservice-virtualserviceprovider-virtualnode
            '''
            result = self._values.get("virtual_node")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualNodeServiceProviderProperty"]], result)

        @builtins.property
        def virtual_router(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualRouterServiceProviderProperty"]]:
            '''The virtual router associated with a virtual service.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualserviceprovider.html#cfn-appmesh-virtualservice-virtualserviceprovider-virtualrouter
            '''
            result = self._values.get("virtual_router")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualRouterServiceProviderProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualServiceProviderProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-appmesh.CfnVirtualService.VirtualServiceSpecProperty",
        jsii_struct_bases=[],
        name_mapping={"provider": "provider"},
    )
    class VirtualServiceSpecProperty:
        def __init__(
            self,
            *,
            provider: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Union["CfnVirtualService.VirtualServiceProviderProperty", typing.Dict[str, typing.Any]]]] = None,
        ) -> None:
            '''An object that represents the specification of a virtual service.

            :param provider: The App Mesh object that is acting as the provider for a virtual service. You can specify a single virtual node or virtual router.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualservicespec.html
            :exampleMetadata: fixture=_generated

            Example::

                # The code below shows an example of how to instantiate this type.
                # The values are placeholders you should change.
                import aws_cdk.aws_appmesh as appmesh
                
                virtual_service_spec_property = appmesh.CfnVirtualService.VirtualServiceSpecProperty(
                    provider=appmesh.CfnVirtualService.VirtualServiceProviderProperty(
                        virtual_node=appmesh.CfnVirtualService.VirtualNodeServiceProviderProperty(
                            virtual_node_name="virtualNodeName"
                        ),
                        virtual_router=appmesh.CfnVirtualService.VirtualRouterServiceProviderProperty(
                            virtual_router_name="virtualRouterName"
                        )
                    )
                )
            '''
            if __debug__:
                type_hints = typing.get_type_hints(CfnVirtualService.VirtualServiceSpecProperty.__init__)
                check_type(argname="argument provider", value=provider, expected_type=type_hints["provider"])
            self._values: typing.Dict[str, typing.Any] = {}
            if provider is not None:
                self._values["provider"] = provider

        @builtins.property
        def provider(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualServiceProviderProperty"]]:
            '''The App Mesh object that is acting as the provider for a virtual service.

            You can specify a single virtual node or virtual router.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualservice-virtualservicespec.html#cfn-appmesh-virtualservice-virtualservicespec-provider
            '''
            result = self._values.get("provider")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnVirtualService.VirtualServiceProviderProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VirtualServiceSpecProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CfnVirtualServiceProps",
    jsii_struct_bases=[],
    name_mapping={
        "mesh_name": "meshName",
        "spec": "spec",
        "virtual_service_name": "virtualServiceName",
        "mesh_owner": "meshOwner",
        "tags": "tags",
    },
)
class CfnVirtualServiceProps:
    def __init__(
        self,
        *,
        mesh_name: builtins.str,
        spec: typing.Union[aws_cdk.core.IResolvable, typing.Union[CfnVirtualService.VirtualServiceSpecProperty, typing.Dict[str, typing.Any]]],
        virtual_service_name: builtins.str,
        mesh_owner: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Sequence[typing.Union[aws_cdk.core.CfnTag, typing.Dict[str, typing.Any]]]] = None,
    ) -> None:
        '''Properties for defining a ``CfnVirtualService``.

        :param mesh_name: The name of the service mesh to create the virtual service in.
        :param spec: The virtual service specification to apply.
        :param virtual_service_name: The name to use for the virtual service.
        :param mesh_owner: The AWS IAM account ID of the service mesh owner. If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .
        :param tags: Optional metadata that you can apply to the virtual service to assist with categorization and organization. Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html
        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            cfn_virtual_service_props = appmesh.CfnVirtualServiceProps(
                mesh_name="meshName",
                spec=appmesh.CfnVirtualService.VirtualServiceSpecProperty(
                    provider=appmesh.CfnVirtualService.VirtualServiceProviderProperty(
                        virtual_node=appmesh.CfnVirtualService.VirtualNodeServiceProviderProperty(
                            virtual_node_name="virtualNodeName"
                        ),
                        virtual_router=appmesh.CfnVirtualService.VirtualRouterServiceProviderProperty(
                            virtual_router_name="virtualRouterName"
                        )
                    )
                ),
                virtual_service_name="virtualServiceName",
            
                # the properties below are optional
                mesh_owner="meshOwner",
                tags=[CfnTag(
                    key="key",
                    value="value"
                )]
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CfnVirtualServiceProps.__init__)
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
            check_type(argname="argument spec", value=spec, expected_type=type_hints["spec"])
            check_type(argname="argument virtual_service_name", value=virtual_service_name, expected_type=type_hints["virtual_service_name"])
            check_type(argname="argument mesh_owner", value=mesh_owner, expected_type=type_hints["mesh_owner"])
            check_type(argname="argument tags", value=tags, expected_type=type_hints["tags"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh_name": mesh_name,
            "spec": spec,
            "virtual_service_name": virtual_service_name,
        }
        if mesh_owner is not None:
            self._values["mesh_owner"] = mesh_owner
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def mesh_name(self) -> builtins.str:
        '''The name of the service mesh to create the virtual service in.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-meshname
        '''
        result = self._values.get("mesh_name")
        assert result is not None, "Required property 'mesh_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def spec(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnVirtualService.VirtualServiceSpecProperty]:
        '''The virtual service specification to apply.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-spec
        '''
        result = self._values.get("spec")
        assert result is not None, "Required property 'spec' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnVirtualService.VirtualServiceSpecProperty], result)

    @builtins.property
    def virtual_service_name(self) -> builtins.str:
        '''The name to use for the virtual service.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-virtualservicename
        '''
        result = self._values.get("virtual_service_name")
        assert result is not None, "Required property 'virtual_service_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def mesh_owner(self) -> typing.Optional[builtins.str]:
        '''The AWS IAM account ID of the service mesh owner.

        If the account ID is not your own, then the account that you specify must share the mesh with your account before you can create the resource in the service mesh. For more information about mesh sharing, see `Working with shared meshes <https://docs.aws.amazon.com/app-mesh/latest/userguide/sharing.html>`_ .

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-meshowner
        '''
        result = self._values.get("mesh_owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''Optional metadata that you can apply to the virtual service to assist with categorization and organization.

        Each tag consists of a key and an optional value, both of which you define. Tag keys can have a maximum character length of 128 characters, and tag values can have a maximum length of 256 characters.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appmesh-virtualservice.html#cfn-appmesh-virtualservice-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVirtualServiceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.CommonGatewayRouteSpecOptions",
    jsii_struct_bases=[],
    name_mapping={"priority": "priority"},
)
class CommonGatewayRouteSpecOptions:
    def __init__(self, *, priority: typing.Optional[jsii.Number] = None) -> None:
        '''Base options for all gateway route specs.

        :param priority: The priority for the gateway route. When a Virtual Gateway has multiple gateway routes, gateway route match is performed in the order of specified value, where 0 is the highest priority, and first matched gateway route is selected. Default: - no particular priority

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            common_gateway_route_spec_options = appmesh.CommonGatewayRouteSpecOptions(
                priority=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(CommonGatewayRouteSpecOptions.__init__)
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
        self._values: typing.Dict[str, typing.Any] = {}
        if priority is not None:
            self._values["priority"] = priority

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the gateway route.

        When a Virtual Gateway has multiple gateway routes, gateway route match
        is performed in the order of specified value, where 0 is the highest priority,
        and first matched gateway route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CommonGatewayRouteSpecOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.DnsResponseType")
class DnsResponseType(enum.Enum):
    '''Enum of DNS service discovery response type.

    :exampleMetadata: infused

    Example::

        # A Virtual Node with a gRPC listener with a connection pool set
        # mesh: appmesh.Mesh
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            # DNS service discovery can optionally specify the DNS response type as either LOAD_BALANCER or ENDPOINTS.
            # LOAD_BALANCER means that the DNS resolver returns a loadbalanced set of endpoints,
            # whereas ENDPOINTS means that the DNS resolver is returning all the endpoints.
            # By default, the response type is assumed to be LOAD_BALANCER
            service_discovery=appmesh.ServiceDiscovery.dns("node", appmesh.DnsResponseType.ENDPOINTS),
            listeners=[appmesh.VirtualNodeListener.http(
                port=80,
                connection_pool=appmesh.HttpConnectionPool(
                    max_connections=100,
                    max_pending_requests=10
                )
            )]
        )
        
        # A Virtual Gateway with a gRPC listener with a connection pool set
        gateway = appmesh.VirtualGateway(self, "gateway",
            mesh=mesh,
            listeners=[appmesh.VirtualGatewayListener.grpc(
                port=8080,
                connection_pool=appmesh.GrpcConnectionPool(
                    max_requests=10
                )
            )],
            virtual_gateway_name="gateway"
        )
    '''

    LOAD_BALANCER = "LOAD_BALANCER"
    '''DNS resolver returns a loadbalanced set of endpoints and the traffic would be sent to the given endpoints.

    It would not drain existing connections to other endpoints that are not part of this list.
    '''
    ENDPOINTS = "ENDPOINTS"
    '''DNS resolver is returning all the endpoints.

    This also means that if an endpoint is missing, it would drain the current connections to the missing endpoint.
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GatewayRouteAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "gateway_route_name": "gatewayRouteName",
        "virtual_gateway": "virtualGateway",
    },
)
class GatewayRouteAttributes:
    def __init__(
        self,
        *,
        gateway_route_name: builtins.str,
        virtual_gateway: "IVirtualGateway",
    ) -> None:
        '''Interface with properties necessary to import a reusable GatewayRoute.

        :param gateway_route_name: The name of the GatewayRoute.
        :param virtual_gateway: The VirtualGateway this GatewayRoute is associated with.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # virtual_gateway: appmesh.VirtualGateway
            
            gateway_route_attributes = appmesh.GatewayRouteAttributes(
                gateway_route_name="gatewayRouteName",
                virtual_gateway=virtual_gateway
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteAttributes.__init__)
            check_type(argname="argument gateway_route_name", value=gateway_route_name, expected_type=type_hints["gateway_route_name"])
            check_type(argname="argument virtual_gateway", value=virtual_gateway, expected_type=type_hints["virtual_gateway"])
        self._values: typing.Dict[str, typing.Any] = {
            "gateway_route_name": gateway_route_name,
            "virtual_gateway": virtual_gateway,
        }

    @builtins.property
    def gateway_route_name(self) -> builtins.str:
        '''The name of the GatewayRoute.'''
        result = self._values.get("gateway_route_name")
        assert result is not None, "Required property 'gateway_route_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def virtual_gateway(self) -> "IVirtualGateway":
        '''The VirtualGateway this GatewayRoute is associated with.'''
        result = self._values.get("virtual_gateway")
        assert result is not None, "Required property 'virtual_gateway' is missing"
        return typing.cast("IVirtualGateway", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayRouteAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GatewayRouteBaseProps",
    jsii_struct_bases=[],
    name_mapping={"route_spec": "routeSpec", "gateway_route_name": "gatewayRouteName"},
)
class GatewayRouteBaseProps:
    def __init__(
        self,
        *,
        route_spec: "GatewayRouteSpec",
        gateway_route_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Basic configuration properties for a GatewayRoute.

        :param route_spec: What protocol the route uses.
        :param gateway_route_name: The name of the GatewayRoute. Default: - an automatically generated name

        :exampleMetadata: infused

        Example::

            # gateway: appmesh.VirtualGateway
            # virtual_service: appmesh.VirtualService
            
            
            gateway.add_gateway_route("gateway-route-grpc",
                route_spec=appmesh.GatewayRouteSpec.grpc(
                    route_target=virtual_service,
                    match=appmesh.GrpcGatewayRouteMatch(
                        hostname=appmesh.GatewayRouteHostnameMatch.exactly("example.com"),
                        # This disables the default rewrite to virtual service name and retain original request.
                        rewrite_request_hostname=False
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteBaseProps.__init__)
            check_type(argname="argument route_spec", value=route_spec, expected_type=type_hints["route_spec"])
            check_type(argname="argument gateway_route_name", value=gateway_route_name, expected_type=type_hints["gateway_route_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "route_spec": route_spec,
        }
        if gateway_route_name is not None:
            self._values["gateway_route_name"] = gateway_route_name

    @builtins.property
    def route_spec(self) -> "GatewayRouteSpec":
        '''What protocol the route uses.'''
        result = self._values.get("route_spec")
        assert result is not None, "Required property 'route_spec' is missing"
        return typing.cast("GatewayRouteSpec", result)

    @builtins.property
    def gateway_route_name(self) -> typing.Optional[builtins.str]:
        '''The name of the GatewayRoute.

        :default: - an automatically generated name
        '''
        result = self._values.get("gateway_route_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayRouteBaseProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class GatewayRouteHostnameMatch(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.GatewayRouteHostnameMatch",
):
    '''Used to generate host name matching methods.

    :exampleMetadata: infused

    Example::

        # gateway: appmesh.VirtualGateway
        # virtual_service: appmesh.VirtualService
        
        
        gateway.add_gateway_route("gateway-route-grpc",
            route_spec=appmesh.GatewayRouteSpec.grpc(
                route_target=virtual_service,
                match=appmesh.GrpcGatewayRouteMatch(
                    hostname=appmesh.GatewayRouteHostnameMatch.ends_with(".example.com")
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="endsWith")
    @builtins.classmethod
    def ends_with(cls, suffix: builtins.str) -> "GatewayRouteHostnameMatch":
        '''The value of the host name with the given name must end with the specified characters.

        :param suffix: The specified ending characters of the host name to match on.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteHostnameMatch.ends_with)
            check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
        return typing.cast("GatewayRouteHostnameMatch", jsii.sinvoke(cls, "endsWith", [suffix]))

    @jsii.member(jsii_name="exactly")
    @builtins.classmethod
    def exactly(cls, name: builtins.str) -> "GatewayRouteHostnameMatch":
        '''The value of the host name must match the specified value exactly.

        :param name: The exact host name to match on.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteHostnameMatch.exactly)
            check_type(argname="argument name", value=name, expected_type=type_hints["name"])
        return typing.cast("GatewayRouteHostnameMatch", jsii.sinvoke(cls, "exactly", [name]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "GatewayRouteHostnameMatchConfig":
        '''Returns the gateway route host name match configuration.

        :param scope: -
        '''
        ...


class _GatewayRouteHostnameMatchProxy(GatewayRouteHostnameMatch):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "GatewayRouteHostnameMatchConfig":
        '''Returns the gateway route host name match configuration.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteHostnameMatch.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("GatewayRouteHostnameMatchConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, GatewayRouteHostnameMatch).__jsii_proxy_class__ = lambda : _GatewayRouteHostnameMatchProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GatewayRouteHostnameMatchConfig",
    jsii_struct_bases=[],
    name_mapping={"hostname_match": "hostnameMatch"},
)
class GatewayRouteHostnameMatchConfig:
    def __init__(
        self,
        *,
        hostname_match: typing.Union[CfnGatewayRoute.GatewayRouteHostnameMatchProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''Configuration for gateway route host name match.

        :param hostname_match: GatewayRoute CFN configuration for host name match.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            gateway_route_hostname_match_config = appmesh.GatewayRouteHostnameMatchConfig(
                hostname_match=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                    exact="exact",
                    suffix="suffix"
                )
            )
        '''
        if isinstance(hostname_match, dict):
            hostname_match = CfnGatewayRoute.GatewayRouteHostnameMatchProperty(**hostname_match)
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteHostnameMatchConfig.__init__)
            check_type(argname="argument hostname_match", value=hostname_match, expected_type=type_hints["hostname_match"])
        self._values: typing.Dict[str, typing.Any] = {
            "hostname_match": hostname_match,
        }

    @builtins.property
    def hostname_match(self) -> CfnGatewayRoute.GatewayRouteHostnameMatchProperty:
        '''GatewayRoute CFN configuration for host name match.'''
        result = self._values.get("hostname_match")
        assert result is not None, "Required property 'hostname_match' is missing"
        return typing.cast(CfnGatewayRoute.GatewayRouteHostnameMatchProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayRouteHostnameMatchConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GatewayRouteProps",
    jsii_struct_bases=[GatewayRouteBaseProps],
    name_mapping={
        "route_spec": "routeSpec",
        "gateway_route_name": "gatewayRouteName",
        "virtual_gateway": "virtualGateway",
    },
)
class GatewayRouteProps(GatewayRouteBaseProps):
    def __init__(
        self,
        *,
        route_spec: "GatewayRouteSpec",
        gateway_route_name: typing.Optional[builtins.str] = None,
        virtual_gateway: "IVirtualGateway",
    ) -> None:
        '''Properties to define a new GatewayRoute.

        :param route_spec: What protocol the route uses.
        :param gateway_route_name: The name of the GatewayRoute. Default: - an automatically generated name
        :param virtual_gateway: The VirtualGateway this GatewayRoute is associated with.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # gateway_route_spec: appmesh.GatewayRouteSpec
            # virtual_gateway: appmesh.VirtualGateway
            
            gateway_route_props = appmesh.GatewayRouteProps(
                route_spec=gateway_route_spec,
                virtual_gateway=virtual_gateway,
            
                # the properties below are optional
                gateway_route_name="gatewayRouteName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteProps.__init__)
            check_type(argname="argument route_spec", value=route_spec, expected_type=type_hints["route_spec"])
            check_type(argname="argument gateway_route_name", value=gateway_route_name, expected_type=type_hints["gateway_route_name"])
            check_type(argname="argument virtual_gateway", value=virtual_gateway, expected_type=type_hints["virtual_gateway"])
        self._values: typing.Dict[str, typing.Any] = {
            "route_spec": route_spec,
            "virtual_gateway": virtual_gateway,
        }
        if gateway_route_name is not None:
            self._values["gateway_route_name"] = gateway_route_name

    @builtins.property
    def route_spec(self) -> "GatewayRouteSpec":
        '''What protocol the route uses.'''
        result = self._values.get("route_spec")
        assert result is not None, "Required property 'route_spec' is missing"
        return typing.cast("GatewayRouteSpec", result)

    @builtins.property
    def gateway_route_name(self) -> typing.Optional[builtins.str]:
        '''The name of the GatewayRoute.

        :default: - an automatically generated name
        '''
        result = self._values.get("gateway_route_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def virtual_gateway(self) -> "IVirtualGateway":
        '''The VirtualGateway this GatewayRoute is associated with.'''
        result = self._values.get("virtual_gateway")
        assert result is not None, "Required property 'virtual_gateway' is missing"
        return typing.cast("IVirtualGateway", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class GatewayRouteSpec(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.GatewayRouteSpec",
):
    '''Used to generate specs with different protocols for a GatewayRoute.

    :exampleMetadata: infused

    Example::

        # gateway: appmesh.VirtualGateway
        # virtual_service: appmesh.VirtualService
        
        
        gateway.add_gateway_route("gateway-route-grpc",
            route_spec=appmesh.GatewayRouteSpec.grpc(
                route_target=virtual_service,
                match=appmesh.GrpcGatewayRouteMatch(
                    hostname=appmesh.GatewayRouteHostnameMatch.exactly("example.com"),
                    # This disables the default rewrite to virtual service name and retain original request.
                    rewrite_request_hostname=False
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="grpc")
    @builtins.classmethod
    def grpc(
        cls,
        *,
        match: typing.Union["GrpcGatewayRouteMatch", typing.Dict[str, typing.Any]],
        route_target: "IVirtualService",
        priority: typing.Optional[jsii.Number] = None,
    ) -> "GatewayRouteSpec":
        '''Creates an gRPC Based GatewayRoute.

        :param match: The criterion for determining a request match for this GatewayRoute.
        :param route_target: The VirtualService this GatewayRoute directs traffic to.
        :param priority: The priority for the gateway route. When a Virtual Gateway has multiple gateway routes, gateway route match is performed in the order of specified value, where 0 is the highest priority, and first matched gateway route is selected. Default: - no particular priority
        '''
        options = GrpcGatewayRouteSpecOptions(
            match=match, route_target=route_target, priority=priority
        )

        return typing.cast("GatewayRouteSpec", jsii.sinvoke(cls, "grpc", [options]))

    @jsii.member(jsii_name="http")
    @builtins.classmethod
    def http(
        cls,
        *,
        route_target: "IVirtualService",
        match: typing.Optional[typing.Union["HttpGatewayRouteMatch", typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> "GatewayRouteSpec":
        '''Creates an HTTP Based GatewayRoute.

        :param route_target: The VirtualService this GatewayRoute directs traffic to.
        :param match: The criterion for determining a request match for this GatewayRoute. When path match is defined, this may optionally determine the path rewrite configuration. Default: - matches any path and automatically rewrites the path to '/'
        :param priority: The priority for the gateway route. When a Virtual Gateway has multiple gateway routes, gateway route match is performed in the order of specified value, where 0 is the highest priority, and first matched gateway route is selected. Default: - no particular priority
        '''
        options = HttpGatewayRouteSpecOptions(
            route_target=route_target, match=match, priority=priority
        )

        return typing.cast("GatewayRouteSpec", jsii.sinvoke(cls, "http", [options]))

    @jsii.member(jsii_name="http2")
    @builtins.classmethod
    def http2(
        cls,
        *,
        route_target: "IVirtualService",
        match: typing.Optional[typing.Union["HttpGatewayRouteMatch", typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> "GatewayRouteSpec":
        '''Creates an HTTP2 Based GatewayRoute.

        :param route_target: The VirtualService this GatewayRoute directs traffic to.
        :param match: The criterion for determining a request match for this GatewayRoute. When path match is defined, this may optionally determine the path rewrite configuration. Default: - matches any path and automatically rewrites the path to '/'
        :param priority: The priority for the gateway route. When a Virtual Gateway has multiple gateway routes, gateway route match is performed in the order of specified value, where 0 is the highest priority, and first matched gateway route is selected. Default: - no particular priority
        '''
        options = HttpGatewayRouteSpecOptions(
            route_target=route_target, match=match, priority=priority
        )

        return typing.cast("GatewayRouteSpec", jsii.sinvoke(cls, "http2", [options]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "GatewayRouteSpecConfig":
        '''Called when the GatewayRouteSpec type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        '''
        ...


class _GatewayRouteSpecProxy(GatewayRouteSpec):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "GatewayRouteSpecConfig":
        '''Called when the GatewayRouteSpec type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteSpec.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("GatewayRouteSpecConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, GatewayRouteSpec).__jsii_proxy_class__ = lambda : _GatewayRouteSpecProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GatewayRouteSpecConfig",
    jsii_struct_bases=[],
    name_mapping={
        "grpc_spec_config": "grpcSpecConfig",
        "http2_spec_config": "http2SpecConfig",
        "http_spec_config": "httpSpecConfig",
        "priority": "priority",
    },
)
class GatewayRouteSpecConfig:
    def __init__(
        self,
        *,
        grpc_spec_config: typing.Optional[typing.Union[CfnGatewayRoute.GrpcGatewayRouteProperty, typing.Dict[str, typing.Any]]] = None,
        http2_spec_config: typing.Optional[typing.Union[CfnGatewayRoute.HttpGatewayRouteProperty, typing.Dict[str, typing.Any]]] = None,
        http_spec_config: typing.Optional[typing.Union[CfnGatewayRoute.HttpGatewayRouteProperty, typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''All Properties for GatewayRoute Specs.

        :param grpc_spec_config: The spec for a grpc gateway route. Default: - no grpc spec
        :param http2_spec_config: The spec for an http2 gateway route. Default: - no http2 spec
        :param http_spec_config: The spec for an http gateway route. Default: - no http spec
        :param priority: The priority for the gateway route. When a Virtual Gateway has multiple gateway routes, gateway route match is performed in the order of specified value, where 0 is the highest priority, and first matched gateway route is selected. Default: - no particular priority

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            gateway_route_spec_config = appmesh.GatewayRouteSpecConfig(
                grpc_spec_config=appmesh.CfnGatewayRoute.GrpcGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.GrpcGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
            
                            # the properties below are optional
                            port=123
                        ),
            
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.GrpcGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.GrpcGatewayRouteMatchProperty(
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        metadata=[appmesh.CfnGatewayRoute.GrpcGatewayRouteMetadataProperty(
                            name="name",
            
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.GatewayRouteMetadataMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        port=123,
                        service_name="serviceName"
                    )
                ),
                http2_spec_config=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
            
                            # the properties below are optional
                            port=123
                        ),
            
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            ),
                            path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                exact="exact"
                            ),
                            prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                default_prefix="defaultPrefix",
                                value="value"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                        headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                            name="name",
            
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        method="method",
                        path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                            name="name",
            
                            # the properties below are optional
                            match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )]
                    )
                ),
                http_spec_config=appmesh.CfnGatewayRoute.HttpGatewayRouteProperty(
                    action=appmesh.CfnGatewayRoute.HttpGatewayRouteActionProperty(
                        target=appmesh.CfnGatewayRoute.GatewayRouteTargetProperty(
                            virtual_service=appmesh.CfnGatewayRoute.GatewayRouteVirtualServiceProperty(
                                virtual_service_name="virtualServiceName"
                            ),
            
                            # the properties below are optional
                            port=123
                        ),
            
                        # the properties below are optional
                        rewrite=appmesh.CfnGatewayRoute.HttpGatewayRouteRewriteProperty(
                            hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameRewriteProperty(
                                default_target_hostname="defaultTargetHostname"
                            ),
                            path=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                                exact="exact"
                            ),
                            prefix=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                                default_prefix="defaultPrefix",
                                value="value"
                            )
                        )
                    ),
                    match=appmesh.CfnGatewayRoute.HttpGatewayRouteMatchProperty(
                        headers=[appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderProperty(
                            name="name",
            
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnGatewayRoute.HttpGatewayRouteHeaderMatchProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnGatewayRoute.GatewayRouteRangeMatchProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        hostname=appmesh.CfnGatewayRoute.GatewayRouteHostnameMatchProperty(
                            exact="exact",
                            suffix="suffix"
                        ),
                        method="method",
                        path=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnGatewayRoute.QueryParameterProperty(
                            name="name",
            
                            # the properties below are optional
                            match=appmesh.CfnGatewayRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )]
                    )
                ),
                priority=123
            )
        '''
        if isinstance(grpc_spec_config, dict):
            grpc_spec_config = CfnGatewayRoute.GrpcGatewayRouteProperty(**grpc_spec_config)
        if isinstance(http2_spec_config, dict):
            http2_spec_config = CfnGatewayRoute.HttpGatewayRouteProperty(**http2_spec_config)
        if isinstance(http_spec_config, dict):
            http_spec_config = CfnGatewayRoute.HttpGatewayRouteProperty(**http_spec_config)
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRouteSpecConfig.__init__)
            check_type(argname="argument grpc_spec_config", value=grpc_spec_config, expected_type=type_hints["grpc_spec_config"])
            check_type(argname="argument http2_spec_config", value=http2_spec_config, expected_type=type_hints["http2_spec_config"])
            check_type(argname="argument http_spec_config", value=http_spec_config, expected_type=type_hints["http_spec_config"])
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
        self._values: typing.Dict[str, typing.Any] = {}
        if grpc_spec_config is not None:
            self._values["grpc_spec_config"] = grpc_spec_config
        if http2_spec_config is not None:
            self._values["http2_spec_config"] = http2_spec_config
        if http_spec_config is not None:
            self._values["http_spec_config"] = http_spec_config
        if priority is not None:
            self._values["priority"] = priority

    @builtins.property
    def grpc_spec_config(
        self,
    ) -> typing.Optional[CfnGatewayRoute.GrpcGatewayRouteProperty]:
        '''The spec for a grpc gateway route.

        :default: - no grpc spec
        '''
        result = self._values.get("grpc_spec_config")
        return typing.cast(typing.Optional[CfnGatewayRoute.GrpcGatewayRouteProperty], result)

    @builtins.property
    def http2_spec_config(
        self,
    ) -> typing.Optional[CfnGatewayRoute.HttpGatewayRouteProperty]:
        '''The spec for an http2 gateway route.

        :default: - no http2 spec
        '''
        result = self._values.get("http2_spec_config")
        return typing.cast(typing.Optional[CfnGatewayRoute.HttpGatewayRouteProperty], result)

    @builtins.property
    def http_spec_config(
        self,
    ) -> typing.Optional[CfnGatewayRoute.HttpGatewayRouteProperty]:
        '''The spec for an http gateway route.

        :default: - no http spec
        '''
        result = self._values.get("http_spec_config")
        return typing.cast(typing.Optional[CfnGatewayRoute.HttpGatewayRouteProperty], result)

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the gateway route.

        When a Virtual Gateway has multiple gateway routes, gateway route match
        is performed in the order of specified value, where 0 is the highest priority,
        and first matched gateway route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayRouteSpecConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcConnectionPool",
    jsii_struct_bases=[],
    name_mapping={"max_requests": "maxRequests"},
)
class GrpcConnectionPool:
    def __init__(self, *, max_requests: jsii.Number) -> None:
        '''Connection pool properties for gRPC listeners.

        :param max_requests: The maximum requests in the pool. Default: - none

        :exampleMetadata: infused

        Example::

            # A Virtual Node with a gRPC listener with a connection pool set
            # mesh: appmesh.Mesh
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                # DNS service discovery can optionally specify the DNS response type as either LOAD_BALANCER or ENDPOINTS.
                # LOAD_BALANCER means that the DNS resolver returns a loadbalanced set of endpoints,
                # whereas ENDPOINTS means that the DNS resolver is returning all the endpoints.
                # By default, the response type is assumed to be LOAD_BALANCER
                service_discovery=appmesh.ServiceDiscovery.dns("node", appmesh.DnsResponseType.ENDPOINTS),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=80,
                    connection_pool=appmesh.HttpConnectionPool(
                        max_connections=100,
                        max_pending_requests=10
                    )
                )]
            )
            
            # A Virtual Gateway with a gRPC listener with a connection pool set
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.grpc(
                    port=8080,
                    connection_pool=appmesh.GrpcConnectionPool(
                        max_requests=10
                    )
                )],
                virtual_gateway_name="gateway"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GrpcConnectionPool.__init__)
            check_type(argname="argument max_requests", value=max_requests, expected_type=type_hints["max_requests"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_requests": max_requests,
        }

    @builtins.property
    def max_requests(self) -> jsii.Number:
        '''The maximum requests in the pool.

        :default: - none
        '''
        result = self._values.get("max_requests")
        assert result is not None, "Required property 'max_requests' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcConnectionPool(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcGatewayListenerOptions",
    jsii_struct_bases=[],
    name_mapping={
        "connection_pool": "connectionPool",
        "health_check": "healthCheck",
        "port": "port",
        "tls": "tls",
    },
)
class GrpcGatewayListenerOptions:
    def __init__(
        self,
        *,
        connection_pool: typing.Optional[typing.Union[GrpcConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional["HealthCheck"] = None,
        port: typing.Optional[jsii.Number] = None,
        tls: typing.Optional[typing.Union["ListenerTlsOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents the properties needed to define GRPC Listeners for a VirtualGateway.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param port: Port to listen for connections on. Default: - 8080
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none

        :exampleMetadata: infused

        Example::

            # A Virtual Node with listener TLS from an ACM provided certificate
            # cert: certificatemanager.Certificate
            # mesh: appmesh.Mesh
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.dns("node"),
                listeners=[appmesh.VirtualNodeListener.grpc(
                    port=80,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.acm(cert)
                    )
                )]
            )
            
            # A Virtual Gateway with listener TLS from a customer provided file certificate
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.grpc(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey")
                    )
                )],
                virtual_gateway_name="gateway"
            )
            
            # A Virtual Gateway with listener TLS from a SDS provided certificate
            gateway2 = appmesh.VirtualGateway(self, "gateway2",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.http2(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.sds("secrete_certificate")
                    )
                )],
                virtual_gateway_name="gateway2"
            )
        '''
        if isinstance(connection_pool, dict):
            connection_pool = GrpcConnectionPool(**connection_pool)
        if isinstance(tls, dict):
            tls = ListenerTlsOptions(**tls)
        if __debug__:
            type_hints = typing.get_type_hints(GrpcGatewayListenerOptions.__init__)
            check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
            check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_pool is not None:
            self._values["connection_pool"] = connection_pool
        if health_check is not None:
            self._values["health_check"] = health_check
        if port is not None:
            self._values["port"] = port
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def connection_pool(self) -> typing.Optional[GrpcConnectionPool]:
        '''Connection pool for http listeners.

        :default: - None
        '''
        result = self._values.get("connection_pool")
        return typing.cast(typing.Optional[GrpcConnectionPool], result)

    @builtins.property
    def health_check(self) -> typing.Optional["HealthCheck"]:
        '''The health check information for the listener.

        :default: - no healthcheck
        '''
        result = self._values.get("health_check")
        return typing.cast(typing.Optional["HealthCheck"], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''Port to listen for connections on.

        :default: - 8080
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tls(self) -> typing.Optional["ListenerTlsOptions"]:
        '''Represents the configuration for enabling TLS on a listener.

        :default: - none
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional["ListenerTlsOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcGatewayListenerOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcGatewayRouteMatch",
    jsii_struct_bases=[],
    name_mapping={
        "hostname": "hostname",
        "metadata": "metadata",
        "rewrite_request_hostname": "rewriteRequestHostname",
        "service_name": "serviceName",
    },
)
class GrpcGatewayRouteMatch:
    def __init__(
        self,
        *,
        hostname: typing.Optional[GatewayRouteHostnameMatch] = None,
        metadata: typing.Optional[typing.Sequence["HeaderMatch"]] = None,
        rewrite_request_hostname: typing.Optional[builtins.bool] = None,
        service_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''The criterion for determining a request match for this GatewayRoute.

        :param hostname: Create host name based gRPC gateway route match. Default: - no matching on host name
        :param metadata: Create metadata based gRPC gateway route match. All specified metadata must match for the route to match. Default: - no matching on metadata
        :param rewrite_request_hostname: When ``true``, rewrites the original request received at the Virtual Gateway to the destination Virtual Service name. When ``false``, retains the original hostname from the request. Default: true
        :param service_name: Create service name based gRPC gateway route match. Default: - no matching on service name

        :exampleMetadata: infused

        Example::

            # gateway: appmesh.VirtualGateway
            # virtual_service: appmesh.VirtualService
            
            
            gateway.add_gateway_route("gateway-route-grpc",
                route_spec=appmesh.GatewayRouteSpec.grpc(
                    route_target=virtual_service,
                    match=appmesh.GrpcGatewayRouteMatch(
                        hostname=appmesh.GatewayRouteHostnameMatch.ends_with(".example.com")
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GrpcGatewayRouteMatch.__init__)
            check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument rewrite_request_hostname", value=rewrite_request_hostname, expected_type=type_hints["rewrite_request_hostname"])
            check_type(argname="argument service_name", value=service_name, expected_type=type_hints["service_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if hostname is not None:
            self._values["hostname"] = hostname
        if metadata is not None:
            self._values["metadata"] = metadata
        if rewrite_request_hostname is not None:
            self._values["rewrite_request_hostname"] = rewrite_request_hostname
        if service_name is not None:
            self._values["service_name"] = service_name

    @builtins.property
    def hostname(self) -> typing.Optional[GatewayRouteHostnameMatch]:
        '''Create host name based gRPC gateway route match.

        :default: - no matching on host name
        '''
        result = self._values.get("hostname")
        return typing.cast(typing.Optional[GatewayRouteHostnameMatch], result)

    @builtins.property
    def metadata(self) -> typing.Optional[typing.List["HeaderMatch"]]:
        '''Create metadata based gRPC gateway route match.

        All specified metadata must match for the route to match.

        :default: - no matching on metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional[typing.List["HeaderMatch"]], result)

    @builtins.property
    def rewrite_request_hostname(self) -> typing.Optional[builtins.bool]:
        '''When ``true``, rewrites the original request received at the Virtual Gateway to the destination Virtual Service name.

        When ``false``, retains the original hostname from the request.

        :default: true
        '''
        result = self._values.get("rewrite_request_hostname")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def service_name(self) -> typing.Optional[builtins.str]:
        '''Create service name based gRPC gateway route match.

        :default: - no matching on service name
        '''
        result = self._values.get("service_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcGatewayRouteMatch(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcGatewayRouteSpecOptions",
    jsii_struct_bases=[CommonGatewayRouteSpecOptions],
    name_mapping={
        "priority": "priority",
        "match": "match",
        "route_target": "routeTarget",
    },
)
class GrpcGatewayRouteSpecOptions(CommonGatewayRouteSpecOptions):
    def __init__(
        self,
        *,
        priority: typing.Optional[jsii.Number] = None,
        match: typing.Union[GrpcGatewayRouteMatch, typing.Dict[str, typing.Any]],
        route_target: "IVirtualService",
    ) -> None:
        '''Properties specific for a gRPC GatewayRoute.

        :param priority: The priority for the gateway route. When a Virtual Gateway has multiple gateway routes, gateway route match is performed in the order of specified value, where 0 is the highest priority, and first matched gateway route is selected. Default: - no particular priority
        :param match: The criterion for determining a request match for this GatewayRoute.
        :param route_target: The VirtualService this GatewayRoute directs traffic to.

        :exampleMetadata: infused

        Example::

            # gateway: appmesh.VirtualGateway
            # virtual_service: appmesh.VirtualService
            
            
            gateway.add_gateway_route("gateway-route-grpc",
                route_spec=appmesh.GatewayRouteSpec.grpc(
                    route_target=virtual_service,
                    match=appmesh.GrpcGatewayRouteMatch(
                        hostname=appmesh.GatewayRouteHostnameMatch.ends_with(".example.com")
                    )
                )
            )
        '''
        if isinstance(match, dict):
            match = GrpcGatewayRouteMatch(**match)
        if __debug__:
            type_hints = typing.get_type_hints(GrpcGatewayRouteSpecOptions.__init__)
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            check_type(argname="argument route_target", value=route_target, expected_type=type_hints["route_target"])
        self._values: typing.Dict[str, typing.Any] = {
            "match": match,
            "route_target": route_target,
        }
        if priority is not None:
            self._values["priority"] = priority

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the gateway route.

        When a Virtual Gateway has multiple gateway routes, gateway route match
        is performed in the order of specified value, where 0 is the highest priority,
        and first matched gateway route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def match(self) -> GrpcGatewayRouteMatch:
        '''The criterion for determining a request match for this GatewayRoute.'''
        result = self._values.get("match")
        assert result is not None, "Required property 'match' is missing"
        return typing.cast(GrpcGatewayRouteMatch, result)

    @builtins.property
    def route_target(self) -> "IVirtualService":
        '''The VirtualService this GatewayRoute directs traffic to.'''
        result = self._values.get("route_target")
        assert result is not None, "Required property 'route_target' is missing"
        return typing.cast("IVirtualService", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcGatewayRouteSpecOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcHealthCheckOptions",
    jsii_struct_bases=[],
    name_mapping={
        "healthy_threshold": "healthyThreshold",
        "interval": "interval",
        "timeout": "timeout",
        "unhealthy_threshold": "unhealthyThreshold",
    },
)
class GrpcHealthCheckOptions:
    def __init__(
        self,
        *,
        healthy_threshold: typing.Optional[jsii.Number] = None,
        interval: typing.Optional[aws_cdk.core.Duration] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
        unhealthy_threshold: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties used to define GRPC Based healthchecks.

        :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy. Default: 2
        :param interval: The time period between each health check execution. Default: Duration.seconds(5)
        :param timeout: The amount of time to wait when receiving a response from the health check. Default: Duration.seconds(2)
        :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a listener unhealthy. Default: - 2

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            import aws_cdk.core as cdk
            
            grpc_health_check_options = appmesh.GrpcHealthCheckOptions(
                healthy_threshold=123,
                interval=cdk.Duration.minutes(30),
                timeout=cdk.Duration.minutes(30),
                unhealthy_threshold=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GrpcHealthCheckOptions.__init__)
            check_type(argname="argument healthy_threshold", value=healthy_threshold, expected_type=type_hints["healthy_threshold"])
            check_type(argname="argument interval", value=interval, expected_type=type_hints["interval"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            check_type(argname="argument unhealthy_threshold", value=unhealthy_threshold, expected_type=type_hints["unhealthy_threshold"])
        self._values: typing.Dict[str, typing.Any] = {}
        if healthy_threshold is not None:
            self._values["healthy_threshold"] = healthy_threshold
        if interval is not None:
            self._values["interval"] = interval
        if timeout is not None:
            self._values["timeout"] = timeout
        if unhealthy_threshold is not None:
            self._values["unhealthy_threshold"] = unhealthy_threshold

    @builtins.property
    def healthy_threshold(self) -> typing.Optional[jsii.Number]:
        '''The number of consecutive successful health checks that must occur before declaring listener healthy.

        :default: 2
        '''
        result = self._values.get("healthy_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def interval(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The time period between each health check execution.

        :default: Duration.seconds(5)
        '''
        result = self._values.get("interval")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The amount of time to wait when receiving a response from the health check.

        :default: Duration.seconds(2)
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def unhealthy_threshold(self) -> typing.Optional[jsii.Number]:
        '''The number of consecutive failed health checks that must occur before declaring a listener unhealthy.

        :default: - 2
        '''
        result = self._values.get("unhealthy_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcHealthCheckOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.GrpcRetryEvent")
class GrpcRetryEvent(enum.Enum):
    '''gRPC events.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-grpc-retry",
            route_spec=appmesh.RouteSpec.grpc(
                weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                match=appmesh.GrpcRouteMatch(service_name="servicename"),
                retry_policy=appmesh.GrpcRetryPolicy(
                    tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                    http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                    # Retry if gRPC responds that the request was cancelled, a resource
                    # was exhausted, or if the service is unavailable
                    grpc_retry_events=[appmesh.GrpcRetryEvent.CANCELLED, appmesh.GrpcRetryEvent.RESOURCE_EXHAUSTED, appmesh.GrpcRetryEvent.UNAVAILABLE
                    ],
                    retry_attempts=5,
                    retry_timeout=cdk.Duration.seconds(1)
                )
            )
        )
    '''

    CANCELLED = "CANCELLED"
    '''Request was cancelled.

    :see: https://grpc.github.io/grpc/core/md_doc_statuscodes.html
    '''
    DEADLINE_EXCEEDED = "DEADLINE_EXCEEDED"
    '''The deadline was exceeded.

    :see: https://grpc.github.io/grpc/core/md_doc_statuscodes.html
    '''
    INTERNAL_ERROR = "INTERNAL_ERROR"
    '''Internal error.

    :see: https://grpc.github.io/grpc/core/md_doc_statuscodes.html
    '''
    RESOURCE_EXHAUSTED = "RESOURCE_EXHAUSTED"
    '''A resource was exhausted.

    :see: https://grpc.github.io/grpc/core/md_doc_statuscodes.html
    '''
    UNAVAILABLE = "UNAVAILABLE"
    '''The service is unavailable.

    :see: https://grpc.github.io/grpc/core/md_doc_statuscodes.html
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcRouteMatch",
    jsii_struct_bases=[],
    name_mapping={
        "metadata": "metadata",
        "method_name": "methodName",
        "service_name": "serviceName",
    },
)
class GrpcRouteMatch:
    def __init__(
        self,
        *,
        metadata: typing.Optional[typing.Sequence["HeaderMatch"]] = None,
        method_name: typing.Optional[builtins.str] = None,
        service_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''The criterion for determining a request match for this Route.

        At least one match type must be selected.

        :param metadata: Create metadata based gRPC route match. All specified metadata must match for the route to match. Default: - do not match on metadata
        :param method_name: The method name to match from the request. If the method name is specified, service name must be also provided. Default: - do not match on method name
        :param service_name: Create service name based gRPC route match. Default: - do not match on service name

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-http",
                route_spec=appmesh.RouteSpec.grpc(
                    weighted_targets=[appmesh.WeightedTarget(
                        virtual_node=node
                    )
                    ],
                    match=appmesh.GrpcRouteMatch(
                        service_name="my-service.default.svc.cluster.local"
                    ),
                    timeout=appmesh.GrpcTimeout(
                        idle=cdk.Duration.seconds(2),
                        per_request=cdk.Duration.seconds(1)
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GrpcRouteMatch.__init__)
            check_type(argname="argument metadata", value=metadata, expected_type=type_hints["metadata"])
            check_type(argname="argument method_name", value=method_name, expected_type=type_hints["method_name"])
            check_type(argname="argument service_name", value=service_name, expected_type=type_hints["service_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if metadata is not None:
            self._values["metadata"] = metadata
        if method_name is not None:
            self._values["method_name"] = method_name
        if service_name is not None:
            self._values["service_name"] = service_name

    @builtins.property
    def metadata(self) -> typing.Optional[typing.List["HeaderMatch"]]:
        '''Create metadata based gRPC route match.

        All specified metadata must match for the route to match.

        :default: - do not match on metadata
        '''
        result = self._values.get("metadata")
        return typing.cast(typing.Optional[typing.List["HeaderMatch"]], result)

    @builtins.property
    def method_name(self) -> typing.Optional[builtins.str]:
        '''The method name to match from the request.

        If the method name is specified, service name must be also provided.

        :default: - do not match on method name
        '''
        result = self._values.get("method_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def service_name(self) -> typing.Optional[builtins.str]:
        '''Create service name based gRPC route match.

        :default: - do not match on service name
        '''
        result = self._values.get("service_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcRouteMatch(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcTimeout",
    jsii_struct_bases=[],
    name_mapping={"idle": "idle", "per_request": "perRequest"},
)
class GrpcTimeout:
    def __init__(
        self,
        *,
        idle: typing.Optional[aws_cdk.core.Duration] = None,
        per_request: typing.Optional[aws_cdk.core.Duration] = None,
    ) -> None:
        '''Represents timeouts for GRPC protocols.

        :param idle: Represents an idle timeout. The amount of time that a connection may be idle. Default: - none
        :param per_request: Represents per request timeout. Default: - 15 s

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-http",
                route_spec=appmesh.RouteSpec.grpc(
                    weighted_targets=[appmesh.WeightedTarget(
                        virtual_node=node
                    )
                    ],
                    match=appmesh.GrpcRouteMatch(
                        service_name="my-service.default.svc.cluster.local"
                    ),
                    timeout=appmesh.GrpcTimeout(
                        idle=cdk.Duration.seconds(2),
                        per_request=cdk.Duration.seconds(1)
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GrpcTimeout.__init__)
            check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
            check_type(argname="argument per_request", value=per_request, expected_type=type_hints["per_request"])
        self._values: typing.Dict[str, typing.Any] = {}
        if idle is not None:
            self._values["idle"] = idle
        if per_request is not None:
            self._values["per_request"] = per_request

    @builtins.property
    def idle(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''Represents an idle timeout.

        The amount of time that a connection may be idle.

        :default: - none
        '''
        result = self._values.get("idle")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def per_request(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''Represents per request timeout.

        :default: - 15 s
        '''
        result = self._values.get("per_request")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcTimeout(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcVirtualNodeListenerOptions",
    jsii_struct_bases=[],
    name_mapping={
        "connection_pool": "connectionPool",
        "health_check": "healthCheck",
        "outlier_detection": "outlierDetection",
        "port": "port",
        "timeout": "timeout",
        "tls": "tls",
    },
)
class GrpcVirtualNodeListenerOptions:
    def __init__(
        self,
        *,
        connection_pool: typing.Optional[typing.Union[GrpcConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional["HealthCheck"] = None,
        outlier_detection: typing.Optional[typing.Union["OutlierDetection", typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union[GrpcTimeout, typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union["ListenerTlsOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represent the GRPC Node Listener prorperty.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for GRPC protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none

        :exampleMetadata: infused

        Example::

            # A Virtual Node with listener TLS from an ACM provided certificate
            # cert: certificatemanager.Certificate
            # mesh: appmesh.Mesh
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.dns("node"),
                listeners=[appmesh.VirtualNodeListener.grpc(
                    port=80,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.acm(cert)
                    )
                )]
            )
            
            # A Virtual Gateway with listener TLS from a customer provided file certificate
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.grpc(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey")
                    )
                )],
                virtual_gateway_name="gateway"
            )
            
            # A Virtual Gateway with listener TLS from a SDS provided certificate
            gateway2 = appmesh.VirtualGateway(self, "gateway2",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.http2(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.sds("secrete_certificate")
                    )
                )],
                virtual_gateway_name="gateway2"
            )
        '''
        if isinstance(connection_pool, dict):
            connection_pool = GrpcConnectionPool(**connection_pool)
        if isinstance(outlier_detection, dict):
            outlier_detection = OutlierDetection(**outlier_detection)
        if isinstance(timeout, dict):
            timeout = GrpcTimeout(**timeout)
        if isinstance(tls, dict):
            tls = ListenerTlsOptions(**tls)
        if __debug__:
            type_hints = typing.get_type_hints(GrpcVirtualNodeListenerOptions.__init__)
            check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
            check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
            check_type(argname="argument outlier_detection", value=outlier_detection, expected_type=type_hints["outlier_detection"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_pool is not None:
            self._values["connection_pool"] = connection_pool
        if health_check is not None:
            self._values["health_check"] = health_check
        if outlier_detection is not None:
            self._values["outlier_detection"] = outlier_detection
        if port is not None:
            self._values["port"] = port
        if timeout is not None:
            self._values["timeout"] = timeout
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def connection_pool(self) -> typing.Optional[GrpcConnectionPool]:
        '''Connection pool for http listeners.

        :default: - None
        '''
        result = self._values.get("connection_pool")
        return typing.cast(typing.Optional[GrpcConnectionPool], result)

    @builtins.property
    def health_check(self) -> typing.Optional["HealthCheck"]:
        '''The health check information for the listener.

        :default: - no healthcheck
        '''
        result = self._values.get("health_check")
        return typing.cast(typing.Optional["HealthCheck"], result)

    @builtins.property
    def outlier_detection(self) -> typing.Optional["OutlierDetection"]:
        '''Represents the configuration for enabling outlier detection.

        :default: - none
        '''
        result = self._values.get("outlier_detection")
        return typing.cast(typing.Optional["OutlierDetection"], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''Port to listen for connections on.

        :default: - 8080
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def timeout(self) -> typing.Optional[GrpcTimeout]:
        '''Timeout for GRPC protocol.

        :default: - None
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[GrpcTimeout], result)

    @builtins.property
    def tls(self) -> typing.Optional["ListenerTlsOptions"]:
        '''Represents the configuration for enabling TLS on a listener.

        :default: - none
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional["ListenerTlsOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcVirtualNodeListenerOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class HeaderMatch(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.HeaderMatch",
):
    '''Used to generate header matching methods.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http2",
            route_spec=appmesh.RouteSpec.http2(
                weighted_targets=[appmesh.WeightedTarget(
                    virtual_node=node
                )
                ],
                match=appmesh.HttpRouteMatch(
                    path=appmesh.HttpRoutePathMatch.exactly("/exact"),
                    method=appmesh.HttpRouteMethod.POST,
                    protocol=appmesh.HttpRouteProtocol.HTTPS,
                    headers=[
                        # All specified headers must match for the route to match.
                        appmesh.HeaderMatch.value_is("Content-Type", "application/json"),
                        appmesh.HeaderMatch.value_is_not("Content-Type", "application/json")
                    ],
                    query_parameters=[
                        # All specified query parameters must match for the route to match.
                        appmesh.QueryParameterMatch.value_is("query-field", "value")
                    ]
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="valueDoesNotEndWith")
    @builtins.classmethod
    def value_does_not_end_with(
        cls,
        header_name: builtins.str,
        suffix: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must not end with the specified characters.

        :param header_name: the name of the header to match against.
        :param suffix: The suffix to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_does_not_end_with)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueDoesNotEndWith", [header_name, suffix]))

    @jsii.member(jsii_name="valueDoesNotMatchRegex")
    @builtins.classmethod
    def value_does_not_match_regex(
        cls,
        header_name: builtins.str,
        regex: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must not include the specified characters.

        :param header_name: the name of the header to match against.
        :param regex: The regex to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_does_not_match_regex)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueDoesNotMatchRegex", [header_name, regex]))

    @jsii.member(jsii_name="valueDoesNotStartWith")
    @builtins.classmethod
    def value_does_not_start_with(
        cls,
        header_name: builtins.str,
        prefix: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must not start with the specified characters.

        :param header_name: the name of the header to match against.
        :param prefix: The prefix to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_does_not_start_with)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueDoesNotStartWith", [header_name, prefix]))

    @jsii.member(jsii_name="valueEndsWith")
    @builtins.classmethod
    def value_ends_with(
        cls,
        header_name: builtins.str,
        suffix: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must end with the specified characters.

        :param header_name: the name of the header to match against.
        :param suffix: The suffix to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_ends_with)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument suffix", value=suffix, expected_type=type_hints["suffix"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueEndsWith", [header_name, suffix]))

    @jsii.member(jsii_name="valueIs")
    @builtins.classmethod
    def value_is(
        cls,
        header_name: builtins.str,
        header_value: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must match the specified value exactly.

        :param header_name: the name of the header to match against.
        :param header_value: The exact value to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_is)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument header_value", value=header_value, expected_type=type_hints["header_value"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueIs", [header_name, header_value]))

    @jsii.member(jsii_name="valueIsNot")
    @builtins.classmethod
    def value_is_not(
        cls,
        header_name: builtins.str,
        header_value: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must not match the specified value exactly.

        :param header_name: the name of the header to match against.
        :param header_value: The exact value to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_is_not)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument header_value", value=header_value, expected_type=type_hints["header_value"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueIsNot", [header_name, header_value]))

    @jsii.member(jsii_name="valueMatchesRegex")
    @builtins.classmethod
    def value_matches_regex(
        cls,
        header_name: builtins.str,
        regex: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must include the specified characters.

        :param header_name: the name of the header to match against.
        :param regex: The regex to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_matches_regex)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueMatchesRegex", [header_name, regex]))

    @jsii.member(jsii_name="valuesIsInRange")
    @builtins.classmethod
    def values_is_in_range(
        cls,
        header_name: builtins.str,
        start: jsii.Number,
        end: jsii.Number,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must be in a range of values.

        :param header_name: the name of the header to match against.
        :param start: Match on values starting at and including this value.
        :param end: Match on values up to but not including this value.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.values_is_in_range)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument start", value=start, expected_type=type_hints["start"])
            check_type(argname="argument end", value=end, expected_type=type_hints["end"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valuesIsInRange", [header_name, start, end]))

    @jsii.member(jsii_name="valuesIsNotInRange")
    @builtins.classmethod
    def values_is_not_in_range(
        cls,
        header_name: builtins.str,
        start: jsii.Number,
        end: jsii.Number,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must not be in a range of values.

        :param header_name: the name of the header to match against.
        :param start: Match on values starting at and including this value.
        :param end: Match on values up to but not including this value.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.values_is_not_in_range)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument start", value=start, expected_type=type_hints["start"])
            check_type(argname="argument end", value=end, expected_type=type_hints["end"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valuesIsNotInRange", [header_name, start, end]))

    @jsii.member(jsii_name="valueStartsWith")
    @builtins.classmethod
    def value_starts_with(
        cls,
        header_name: builtins.str,
        prefix: builtins.str,
    ) -> "HeaderMatch":
        '''The value of the header with the given name in the request must start with the specified characters.

        :param header_name: the name of the header to match against.
        :param prefix: The prefix to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.value_starts_with)
            check_type(argname="argument header_name", value=header_name, expected_type=type_hints["header_name"])
            check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
        return typing.cast("HeaderMatch", jsii.sinvoke(cls, "valueStartsWith", [header_name, prefix]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "HeaderMatchConfig":
        '''Returns the header match configuration.

        :param scope: -
        '''
        ...


class _HeaderMatchProxy(HeaderMatch):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "HeaderMatchConfig":
        '''Returns the header match configuration.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatch.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("HeaderMatchConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, HeaderMatch).__jsii_proxy_class__ = lambda : _HeaderMatchProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HeaderMatchConfig",
    jsii_struct_bases=[],
    name_mapping={"header_match": "headerMatch"},
)
class HeaderMatchConfig:
    def __init__(
        self,
        *,
        header_match: typing.Union[CfnRoute.HttpRouteHeaderProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''Configuration for ``HeaderMatch``.

        :param header_match: Route CFN configuration for the route header match.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            header_match_config = appmesh.HeaderMatchConfig(
                header_match=appmesh.CfnRoute.HttpRouteHeaderProperty(
                    name="name",
            
                    # the properties below are optional
                    invert=False,
                    match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                        exact="exact",
                        prefix="prefix",
                        range=appmesh.CfnRoute.MatchRangeProperty(
                            end=123,
                            start=123
                        ),
                        regex="regex",
                        suffix="suffix"
                    )
                )
            )
        '''
        if isinstance(header_match, dict):
            header_match = CfnRoute.HttpRouteHeaderProperty(**header_match)
        if __debug__:
            type_hints = typing.get_type_hints(HeaderMatchConfig.__init__)
            check_type(argname="argument header_match", value=header_match, expected_type=type_hints["header_match"])
        self._values: typing.Dict[str, typing.Any] = {
            "header_match": header_match,
        }

    @builtins.property
    def header_match(self) -> CfnRoute.HttpRouteHeaderProperty:
        '''Route CFN configuration for the route header match.'''
        result = self._values.get("header_match")
        assert result is not None, "Required property 'header_match' is missing"
        return typing.cast(CfnRoute.HttpRouteHeaderProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HeaderMatchConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class HealthCheck(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.HealthCheck",
):
    '''Contains static factory methods for creating health checks for different protocols.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        vpc = ec2.Vpc(self, "vpc")
        namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
            vpc=vpc,
            name="domain.local"
        )
        service = namespace.create_service("Svc")
        node = mesh.add_virtual_node("virtual-node",
            service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
            listeners=[appmesh.VirtualNodeListener.http(
                port=8081,
                health_check=appmesh.HealthCheck.http(
                    healthy_threshold=3,
                    interval=cdk.Duration.seconds(5),  # minimum
                    path="/health-check-path",
                    timeout=cdk.Duration.seconds(2),  # minimum
                    unhealthy_threshold=2
                )
            )],
            access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="grpc")
    @builtins.classmethod
    def grpc(
        cls,
        *,
        healthy_threshold: typing.Optional[jsii.Number] = None,
        interval: typing.Optional[aws_cdk.core.Duration] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
        unhealthy_threshold: typing.Optional[jsii.Number] = None,
    ) -> "HealthCheck":
        '''Construct a GRPC health check.

        :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy. Default: 2
        :param interval: The time period between each health check execution. Default: Duration.seconds(5)
        :param timeout: The amount of time to wait when receiving a response from the health check. Default: Duration.seconds(2)
        :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a listener unhealthy. Default: - 2
        '''
        options = GrpcHealthCheckOptions(
            healthy_threshold=healthy_threshold,
            interval=interval,
            timeout=timeout,
            unhealthy_threshold=unhealthy_threshold,
        )

        return typing.cast("HealthCheck", jsii.sinvoke(cls, "grpc", [options]))

    @jsii.member(jsii_name="http")
    @builtins.classmethod
    def http(
        cls,
        *,
        healthy_threshold: typing.Optional[jsii.Number] = None,
        interval: typing.Optional[aws_cdk.core.Duration] = None,
        path: typing.Optional[builtins.str] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
        unhealthy_threshold: typing.Optional[jsii.Number] = None,
    ) -> "HealthCheck":
        '''Construct a HTTP health check.

        :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy. Default: 2
        :param interval: The time period between each health check execution. Default: Duration.seconds(5)
        :param path: The destination path for the health check request. Default: /
        :param timeout: The amount of time to wait when receiving a response from the health check. Default: Duration.seconds(2)
        :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a listener unhealthy. Default: - 2
        '''
        options = HttpHealthCheckOptions(
            healthy_threshold=healthy_threshold,
            interval=interval,
            path=path,
            timeout=timeout,
            unhealthy_threshold=unhealthy_threshold,
        )

        return typing.cast("HealthCheck", jsii.sinvoke(cls, "http", [options]))

    @jsii.member(jsii_name="http2")
    @builtins.classmethod
    def http2(
        cls,
        *,
        healthy_threshold: typing.Optional[jsii.Number] = None,
        interval: typing.Optional[aws_cdk.core.Duration] = None,
        path: typing.Optional[builtins.str] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
        unhealthy_threshold: typing.Optional[jsii.Number] = None,
    ) -> "HealthCheck":
        '''Construct a HTTP2 health check.

        :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy. Default: 2
        :param interval: The time period between each health check execution. Default: Duration.seconds(5)
        :param path: The destination path for the health check request. Default: /
        :param timeout: The amount of time to wait when receiving a response from the health check. Default: Duration.seconds(2)
        :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a listener unhealthy. Default: - 2
        '''
        options = HttpHealthCheckOptions(
            healthy_threshold=healthy_threshold,
            interval=interval,
            path=path,
            timeout=timeout,
            unhealthy_threshold=unhealthy_threshold,
        )

        return typing.cast("HealthCheck", jsii.sinvoke(cls, "http2", [options]))

    @jsii.member(jsii_name="tcp")
    @builtins.classmethod
    def tcp(
        cls,
        *,
        healthy_threshold: typing.Optional[jsii.Number] = None,
        interval: typing.Optional[aws_cdk.core.Duration] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
        unhealthy_threshold: typing.Optional[jsii.Number] = None,
    ) -> "HealthCheck":
        '''Construct a TCP health check.

        :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy. Default: 2
        :param interval: The time period between each health check execution. Default: Duration.seconds(5)
        :param timeout: The amount of time to wait when receiving a response from the health check. Default: Duration.seconds(2)
        :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a listener unhealthy. Default: - 2
        '''
        options = TcpHealthCheckOptions(
            healthy_threshold=healthy_threshold,
            interval=interval,
            timeout=timeout,
            unhealthy_threshold=unhealthy_threshold,
        )

        return typing.cast("HealthCheck", jsii.sinvoke(cls, "tcp", [options]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(
        self,
        scope: aws_cdk.core.Construct,
        *,
        default_port: typing.Optional[jsii.Number] = None,
    ) -> "HealthCheckConfig":
        '''Called when the AccessLog type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        :param default_port: Port for Health Check interface. Default: - no default port is provided
        '''
        ...


class _HealthCheckProxy(HealthCheck):
    @jsii.member(jsii_name="bind")
    def bind(
        self,
        scope: aws_cdk.core.Construct,
        *,
        default_port: typing.Optional[jsii.Number] = None,
    ) -> "HealthCheckConfig":
        '''Called when the AccessLog type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        :param default_port: Port for Health Check interface. Default: - no default port is provided
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HealthCheck.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        options = HealthCheckBindOptions(default_port=default_port)

        return typing.cast("HealthCheckConfig", jsii.invoke(self, "bind", [scope, options]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, HealthCheck).__jsii_proxy_class__ = lambda : _HealthCheckProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HealthCheckBindOptions",
    jsii_struct_bases=[],
    name_mapping={"default_port": "defaultPort"},
)
class HealthCheckBindOptions:
    def __init__(self, *, default_port: typing.Optional[jsii.Number] = None) -> None:
        '''Options used for creating the Health Check object.

        :param default_port: Port for Health Check interface. Default: - no default port is provided

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            health_check_bind_options = appmesh.HealthCheckBindOptions(
                default_port=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HealthCheckBindOptions.__init__)
            check_type(argname="argument default_port", value=default_port, expected_type=type_hints["default_port"])
        self._values: typing.Dict[str, typing.Any] = {}
        if default_port is not None:
            self._values["default_port"] = default_port

    @builtins.property
    def default_port(self) -> typing.Optional[jsii.Number]:
        '''Port for Health Check interface.

        :default: - no default port is provided
        '''
        result = self._values.get("default_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HealthCheckBindOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HealthCheckConfig",
    jsii_struct_bases=[],
    name_mapping={
        "virtual_gateway_health_check": "virtualGatewayHealthCheck",
        "virtual_node_health_check": "virtualNodeHealthCheck",
    },
)
class HealthCheckConfig:
    def __init__(
        self,
        *,
        virtual_gateway_health_check: typing.Optional[typing.Union[CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty, typing.Dict[str, typing.Any]]] = None,
        virtual_node_health_check: typing.Optional[typing.Union[CfnVirtualNode.HealthCheckProperty, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''All Properties for Health Checks for mesh endpoints.

        :param virtual_gateway_health_check: VirtualGateway CFN configuration for Health Checks. Default: - no health checks
        :param virtual_node_health_check: VirtualNode CFN configuration for Health Checks. Default: - no health checks

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            health_check_config = appmesh.HealthCheckConfig(
                virtual_gateway_health_check=appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(
                    healthy_threshold=123,
                    interval_millis=123,
                    protocol="protocol",
                    timeout_millis=123,
                    unhealthy_threshold=123,
            
                    # the properties below are optional
                    path="path",
                    port=123
                ),
                virtual_node_health_check=appmesh.CfnVirtualNode.HealthCheckProperty(
                    healthy_threshold=123,
                    interval_millis=123,
                    protocol="protocol",
                    timeout_millis=123,
                    unhealthy_threshold=123,
            
                    # the properties below are optional
                    path="path",
                    port=123
                )
            )
        '''
        if isinstance(virtual_gateway_health_check, dict):
            virtual_gateway_health_check = CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(**virtual_gateway_health_check)
        if isinstance(virtual_node_health_check, dict):
            virtual_node_health_check = CfnVirtualNode.HealthCheckProperty(**virtual_node_health_check)
        if __debug__:
            type_hints = typing.get_type_hints(HealthCheckConfig.__init__)
            check_type(argname="argument virtual_gateway_health_check", value=virtual_gateway_health_check, expected_type=type_hints["virtual_gateway_health_check"])
            check_type(argname="argument virtual_node_health_check", value=virtual_node_health_check, expected_type=type_hints["virtual_node_health_check"])
        self._values: typing.Dict[str, typing.Any] = {}
        if virtual_gateway_health_check is not None:
            self._values["virtual_gateway_health_check"] = virtual_gateway_health_check
        if virtual_node_health_check is not None:
            self._values["virtual_node_health_check"] = virtual_node_health_check

    @builtins.property
    def virtual_gateway_health_check(
        self,
    ) -> typing.Optional[CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty]:
        '''VirtualGateway CFN configuration for Health Checks.

        :default: - no health checks
        '''
        result = self._values.get("virtual_gateway_health_check")
        return typing.cast(typing.Optional[CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty], result)

    @builtins.property
    def virtual_node_health_check(
        self,
    ) -> typing.Optional[CfnVirtualNode.HealthCheckProperty]:
        '''VirtualNode CFN configuration for Health Checks.

        :default: - no health checks
        '''
        result = self._values.get("virtual_node_health_check")
        return typing.cast(typing.Optional[CfnVirtualNode.HealthCheckProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HealthCheckConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.Http2ConnectionPool",
    jsii_struct_bases=[],
    name_mapping={"max_requests": "maxRequests"},
)
class Http2ConnectionPool:
    def __init__(self, *, max_requests: jsii.Number) -> None:
        '''Connection pool properties for HTTP2 listeners.

        :param max_requests: The maximum requests in the pool. Default: - none

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            http2_connection_pool = appmesh.Http2ConnectionPool(
                max_requests=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Http2ConnectionPool.__init__)
            check_type(argname="argument max_requests", value=max_requests, expected_type=type_hints["max_requests"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_requests": max_requests,
        }

    @builtins.property
    def max_requests(self) -> jsii.Number:
        '''The maximum requests in the pool.

        :default: - none
        '''
        result = self._values.get("max_requests")
        assert result is not None, "Required property 'max_requests' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Http2ConnectionPool(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.Http2GatewayListenerOptions",
    jsii_struct_bases=[],
    name_mapping={
        "connection_pool": "connectionPool",
        "health_check": "healthCheck",
        "port": "port",
        "tls": "tls",
    },
)
class Http2GatewayListenerOptions:
    def __init__(
        self,
        *,
        connection_pool: typing.Optional[typing.Union[Http2ConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        port: typing.Optional[jsii.Number] = None,
        tls: typing.Optional[typing.Union["ListenerTlsOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents the properties needed to define HTTP2 Listeners for a VirtualGateway.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param port: Port to listen for connections on. Default: - 8080
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none

        :exampleMetadata: infused

        Example::

            # A Virtual Node with listener TLS from an ACM provided certificate
            # cert: certificatemanager.Certificate
            # mesh: appmesh.Mesh
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.dns("node"),
                listeners=[appmesh.VirtualNodeListener.grpc(
                    port=80,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.acm(cert)
                    )
                )]
            )
            
            # A Virtual Gateway with listener TLS from a customer provided file certificate
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.grpc(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey")
                    )
                )],
                virtual_gateway_name="gateway"
            )
            
            # A Virtual Gateway with listener TLS from a SDS provided certificate
            gateway2 = appmesh.VirtualGateway(self, "gateway2",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.http2(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.sds("secrete_certificate")
                    )
                )],
                virtual_gateway_name="gateway2"
            )
        '''
        if isinstance(connection_pool, dict):
            connection_pool = Http2ConnectionPool(**connection_pool)
        if isinstance(tls, dict):
            tls = ListenerTlsOptions(**tls)
        if __debug__:
            type_hints = typing.get_type_hints(Http2GatewayListenerOptions.__init__)
            check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
            check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_pool is not None:
            self._values["connection_pool"] = connection_pool
        if health_check is not None:
            self._values["health_check"] = health_check
        if port is not None:
            self._values["port"] = port
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def connection_pool(self) -> typing.Optional[Http2ConnectionPool]:
        '''Connection pool for http listeners.

        :default: - None
        '''
        result = self._values.get("connection_pool")
        return typing.cast(typing.Optional[Http2ConnectionPool], result)

    @builtins.property
    def health_check(self) -> typing.Optional[HealthCheck]:
        '''The health check information for the listener.

        :default: - no healthcheck
        '''
        result = self._values.get("health_check")
        return typing.cast(typing.Optional[HealthCheck], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''Port to listen for connections on.

        :default: - 8080
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tls(self) -> typing.Optional["ListenerTlsOptions"]:
        '''Represents the configuration for enabling TLS on a listener.

        :default: - none
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional["ListenerTlsOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Http2GatewayListenerOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.Http2VirtualNodeListenerOptions",
    jsii_struct_bases=[],
    name_mapping={
        "connection_pool": "connectionPool",
        "health_check": "healthCheck",
        "outlier_detection": "outlierDetection",
        "port": "port",
        "timeout": "timeout",
        "tls": "tls",
    },
)
class Http2VirtualNodeListenerOptions:
    def __init__(
        self,
        *,
        connection_pool: typing.Optional[typing.Union[Http2ConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        outlier_detection: typing.Optional[typing.Union["OutlierDetection", typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union["HttpTimeout", typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union["ListenerTlsOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represent the HTTP2 Node Listener prorperty.

        :param connection_pool: Connection pool for http2 listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for HTTP protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            import aws_cdk.core as cdk
            
            # health_check: appmesh.HealthCheck
            # mutual_tls_validation_trust: appmesh.MutualTlsValidationTrust
            # subject_alternative_names: appmesh.SubjectAlternativeNames
            # tls_certificate: appmesh.TlsCertificate
            
            http2_virtual_node_listener_options = appmesh.Http2VirtualNodeListenerOptions(
                connection_pool=appmesh.Http2ConnectionPool(
                    max_requests=123
                ),
                health_check=health_check,
                outlier_detection=appmesh.OutlierDetection(
                    base_ejection_duration=cdk.Duration.minutes(30),
                    interval=cdk.Duration.minutes(30),
                    max_ejection_percent=123,
                    max_server_errors=123
                ),
                port=123,
                timeout=appmesh.HttpTimeout(
                    idle=cdk.Duration.minutes(30),
                    per_request=cdk.Duration.minutes(30)
                ),
                tls=appmesh.ListenerTlsOptions(
                    certificate=tls_certificate,
                    mode=appmesh.TlsMode.STRICT,
            
                    # the properties below are optional
                    mutual_tls_validation=appmesh.MutualTlsValidation(
                        trust=mutual_tls_validation_trust,
            
                        # the properties below are optional
                        subject_alternative_names=subject_alternative_names
                    )
                )
            )
        '''
        if isinstance(connection_pool, dict):
            connection_pool = Http2ConnectionPool(**connection_pool)
        if isinstance(outlier_detection, dict):
            outlier_detection = OutlierDetection(**outlier_detection)
        if isinstance(timeout, dict):
            timeout = HttpTimeout(**timeout)
        if isinstance(tls, dict):
            tls = ListenerTlsOptions(**tls)
        if __debug__:
            type_hints = typing.get_type_hints(Http2VirtualNodeListenerOptions.__init__)
            check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
            check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
            check_type(argname="argument outlier_detection", value=outlier_detection, expected_type=type_hints["outlier_detection"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_pool is not None:
            self._values["connection_pool"] = connection_pool
        if health_check is not None:
            self._values["health_check"] = health_check
        if outlier_detection is not None:
            self._values["outlier_detection"] = outlier_detection
        if port is not None:
            self._values["port"] = port
        if timeout is not None:
            self._values["timeout"] = timeout
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def connection_pool(self) -> typing.Optional[Http2ConnectionPool]:
        '''Connection pool for http2 listeners.

        :default: - None
        '''
        result = self._values.get("connection_pool")
        return typing.cast(typing.Optional[Http2ConnectionPool], result)

    @builtins.property
    def health_check(self) -> typing.Optional[HealthCheck]:
        '''The health check information for the listener.

        :default: - no healthcheck
        '''
        result = self._values.get("health_check")
        return typing.cast(typing.Optional[HealthCheck], result)

    @builtins.property
    def outlier_detection(self) -> typing.Optional["OutlierDetection"]:
        '''Represents the configuration for enabling outlier detection.

        :default: - none
        '''
        result = self._values.get("outlier_detection")
        return typing.cast(typing.Optional["OutlierDetection"], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''Port to listen for connections on.

        :default: - 8080
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def timeout(self) -> typing.Optional["HttpTimeout"]:
        '''Timeout for HTTP protocol.

        :default: - None
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional["HttpTimeout"], result)

    @builtins.property
    def tls(self) -> typing.Optional["ListenerTlsOptions"]:
        '''Represents the configuration for enabling TLS on a listener.

        :default: - none
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional["ListenerTlsOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Http2VirtualNodeListenerOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpConnectionPool",
    jsii_struct_bases=[],
    name_mapping={
        "max_connections": "maxConnections",
        "max_pending_requests": "maxPendingRequests",
    },
)
class HttpConnectionPool:
    def __init__(
        self,
        *,
        max_connections: jsii.Number,
        max_pending_requests: jsii.Number,
    ) -> None:
        '''Connection pool properties for HTTP listeners.

        :param max_connections: The maximum connections in the pool. Default: - none
        :param max_pending_requests: The maximum pending requests in the pool. Default: - none

        :exampleMetadata: infused

        Example::

            # A Virtual Node with a gRPC listener with a connection pool set
            # mesh: appmesh.Mesh
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                # DNS service discovery can optionally specify the DNS response type as either LOAD_BALANCER or ENDPOINTS.
                # LOAD_BALANCER means that the DNS resolver returns a loadbalanced set of endpoints,
                # whereas ENDPOINTS means that the DNS resolver is returning all the endpoints.
                # By default, the response type is assumed to be LOAD_BALANCER
                service_discovery=appmesh.ServiceDiscovery.dns("node", appmesh.DnsResponseType.ENDPOINTS),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=80,
                    connection_pool=appmesh.HttpConnectionPool(
                        max_connections=100,
                        max_pending_requests=10
                    )
                )]
            )
            
            # A Virtual Gateway with a gRPC listener with a connection pool set
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.grpc(
                    port=8080,
                    connection_pool=appmesh.GrpcConnectionPool(
                        max_requests=10
                    )
                )],
                virtual_gateway_name="gateway"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpConnectionPool.__init__)
            check_type(argname="argument max_connections", value=max_connections, expected_type=type_hints["max_connections"])
            check_type(argname="argument max_pending_requests", value=max_pending_requests, expected_type=type_hints["max_pending_requests"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_connections": max_connections,
            "max_pending_requests": max_pending_requests,
        }

    @builtins.property
    def max_connections(self) -> jsii.Number:
        '''The maximum connections in the pool.

        :default: - none
        '''
        result = self._values.get("max_connections")
        assert result is not None, "Required property 'max_connections' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def max_pending_requests(self) -> jsii.Number:
        '''The maximum pending requests in the pool.

        :default: - none
        '''
        result = self._values.get("max_pending_requests")
        assert result is not None, "Required property 'max_pending_requests' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpConnectionPool(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpGatewayListenerOptions",
    jsii_struct_bases=[],
    name_mapping={
        "connection_pool": "connectionPool",
        "health_check": "healthCheck",
        "port": "port",
        "tls": "tls",
    },
)
class HttpGatewayListenerOptions:
    def __init__(
        self,
        *,
        connection_pool: typing.Optional[typing.Union[HttpConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        port: typing.Optional[jsii.Number] = None,
        tls: typing.Optional[typing.Union["ListenerTlsOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents the properties needed to define HTTP Listeners for a VirtualGateway.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param port: Port to listen for connections on. Default: - 8080
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            
            certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
            
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.http(
                    port=443,
                    health_check=appmesh.HealthCheck.http(
                        interval=cdk.Duration.seconds(10)
                    )
                )],
                backend_defaults=appmesh.BackendDefaults(
                    tls_client_policy=appmesh.TlsClientPolicy(
                        ports=[8080, 8081],
                        validation=appmesh.TlsValidation(
                            trust=appmesh.TlsValidationTrust.acm([
                                acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                            ])
                        )
                    )
                ),
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout"),
                virtual_gateway_name="virtualGateway"
            )
        '''
        if isinstance(connection_pool, dict):
            connection_pool = HttpConnectionPool(**connection_pool)
        if isinstance(tls, dict):
            tls = ListenerTlsOptions(**tls)
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayListenerOptions.__init__)
            check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
            check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_pool is not None:
            self._values["connection_pool"] = connection_pool
        if health_check is not None:
            self._values["health_check"] = health_check
        if port is not None:
            self._values["port"] = port
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def connection_pool(self) -> typing.Optional[HttpConnectionPool]:
        '''Connection pool for http listeners.

        :default: - None
        '''
        result = self._values.get("connection_pool")
        return typing.cast(typing.Optional[HttpConnectionPool], result)

    @builtins.property
    def health_check(self) -> typing.Optional[HealthCheck]:
        '''The health check information for the listener.

        :default: - no healthcheck
        '''
        result = self._values.get("health_check")
        return typing.cast(typing.Optional[HealthCheck], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''Port to listen for connections on.

        :default: - 8080
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tls(self) -> typing.Optional["ListenerTlsOptions"]:
        '''Represents the configuration for enabling TLS on a listener.

        :default: - none
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional["ListenerTlsOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpGatewayListenerOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpGatewayRouteMatch",
    jsii_struct_bases=[],
    name_mapping={
        "headers": "headers",
        "hostname": "hostname",
        "method": "method",
        "path": "path",
        "query_parameters": "queryParameters",
        "rewrite_request_hostname": "rewriteRequestHostname",
    },
)
class HttpGatewayRouteMatch:
    def __init__(
        self,
        *,
        headers: typing.Optional[typing.Sequence[HeaderMatch]] = None,
        hostname: typing.Optional[GatewayRouteHostnameMatch] = None,
        method: typing.Optional["HttpRouteMethod"] = None,
        path: typing.Optional["HttpGatewayRoutePathMatch"] = None,
        query_parameters: typing.Optional[typing.Sequence["QueryParameterMatch"]] = None,
        rewrite_request_hostname: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''The criterion for determining a request match for this GatewayRoute.

        :param headers: Specifies the client request headers to match on. All specified headers must match for the gateway route to match. Default: - do not match on headers
        :param hostname: The gateway route host name to be matched on. Default: - do not match on host name
        :param method: The method to match on. Default: - do not match on method
        :param path: Specify how to match requests based on the 'path' part of their URL. Default: - matches requests with any path
        :param query_parameters: The query parameters to match on. All specified query parameters must match for the route to match. Default: - do not match on query parameters
        :param rewrite_request_hostname: When ``true``, rewrites the original request received at the Virtual Gateway to the destination Virtual Service name. When ``false``, retains the original hostname from the request. Default: true

        :exampleMetadata: infused

        Example::

            # gateway: appmesh.VirtualGateway
            # virtual_service: appmesh.VirtualService
            
            
            gateway.add_gateway_route("gateway-route-http-2",
                route_spec=appmesh.GatewayRouteSpec.http(
                    route_target=virtual_service,
                    match=appmesh.HttpGatewayRouteMatch(
                        # This rewrites the path from '/test' to '/rewrittenPath'.
                        path=appmesh.HttpGatewayRoutePathMatch.exactly("/test", "/rewrittenPath")
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayRouteMatch.__init__)
            check_type(argname="argument headers", value=headers, expected_type=type_hints["headers"])
            check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            check_type(argname="argument method", value=method, expected_type=type_hints["method"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument query_parameters", value=query_parameters, expected_type=type_hints["query_parameters"])
            check_type(argname="argument rewrite_request_hostname", value=rewrite_request_hostname, expected_type=type_hints["rewrite_request_hostname"])
        self._values: typing.Dict[str, typing.Any] = {}
        if headers is not None:
            self._values["headers"] = headers
        if hostname is not None:
            self._values["hostname"] = hostname
        if method is not None:
            self._values["method"] = method
        if path is not None:
            self._values["path"] = path
        if query_parameters is not None:
            self._values["query_parameters"] = query_parameters
        if rewrite_request_hostname is not None:
            self._values["rewrite_request_hostname"] = rewrite_request_hostname

    @builtins.property
    def headers(self) -> typing.Optional[typing.List[HeaderMatch]]:
        '''Specifies the client request headers to match on.

        All specified headers
        must match for the gateway route to match.

        :default: - do not match on headers
        '''
        result = self._values.get("headers")
        return typing.cast(typing.Optional[typing.List[HeaderMatch]], result)

    @builtins.property
    def hostname(self) -> typing.Optional[GatewayRouteHostnameMatch]:
        '''The gateway route host name to be matched on.

        :default: - do not match on host name
        '''
        result = self._values.get("hostname")
        return typing.cast(typing.Optional[GatewayRouteHostnameMatch], result)

    @builtins.property
    def method(self) -> typing.Optional["HttpRouteMethod"]:
        '''The method to match on.

        :default: - do not match on method
        '''
        result = self._values.get("method")
        return typing.cast(typing.Optional["HttpRouteMethod"], result)

    @builtins.property
    def path(self) -> typing.Optional["HttpGatewayRoutePathMatch"]:
        '''Specify how to match requests based on the 'path' part of their URL.

        :default: - matches requests with any path
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional["HttpGatewayRoutePathMatch"], result)

    @builtins.property
    def query_parameters(self) -> typing.Optional[typing.List["QueryParameterMatch"]]:
        '''The query parameters to match on.

        All specified query parameters must match for the route to match.

        :default: - do not match on query parameters
        '''
        result = self._values.get("query_parameters")
        return typing.cast(typing.Optional[typing.List["QueryParameterMatch"]], result)

    @builtins.property
    def rewrite_request_hostname(self) -> typing.Optional[builtins.bool]:
        '''When ``true``, rewrites the original request received at the Virtual Gateway to the destination Virtual Service name.

        When ``false``, retains the original hostname from the request.

        :default: true
        '''
        result = self._values.get("rewrite_request_hostname")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpGatewayRouteMatch(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class HttpGatewayRoutePathMatch(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.HttpGatewayRoutePathMatch",
):
    '''Defines HTTP gateway route matching based on the URL path of the request.

    :exampleMetadata: infused

    Example::

        # gateway: appmesh.VirtualGateway
        # virtual_service: appmesh.VirtualService
        
        
        gateway.add_gateway_route("gateway-route-http-2",
            route_spec=appmesh.GatewayRouteSpec.http(
                route_target=virtual_service,
                match=appmesh.HttpGatewayRouteMatch(
                    # This rewrites the path from '/test' to '/rewrittenPath'.
                    path=appmesh.HttpGatewayRoutePathMatch.exactly("/test", "/rewrittenPath")
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="exactly")
    @builtins.classmethod
    def exactly(
        cls,
        path: builtins.str,
        rewrite_to: typing.Optional[builtins.str] = None,
    ) -> "HttpGatewayRoutePathMatch":
        '''The value of the path must match the specified value exactly.

        The provided ``path`` must start with the '/' character.

        :param path: the exact path to match on.
        :param rewrite_to: the value to substitute for the matched part of the path of the gateway request URL As a default, retains original request's URL path.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayRoutePathMatch.exactly)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument rewrite_to", value=rewrite_to, expected_type=type_hints["rewrite_to"])
        return typing.cast("HttpGatewayRoutePathMatch", jsii.sinvoke(cls, "exactly", [path, rewrite_to]))

    @jsii.member(jsii_name="regex")
    @builtins.classmethod
    def regex(
        cls,
        regex: builtins.str,
        rewrite_to: typing.Optional[builtins.str] = None,
    ) -> "HttpGatewayRoutePathMatch":
        '''The value of the path must match the specified regex.

        :param regex: the regex used to match the path.
        :param rewrite_to: the value to substitute for the matched part of the path of the gateway request URL As a default, retains original request's URL path.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayRoutePathMatch.regex)
            check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
            check_type(argname="argument rewrite_to", value=rewrite_to, expected_type=type_hints["rewrite_to"])
        return typing.cast("HttpGatewayRoutePathMatch", jsii.sinvoke(cls, "regex", [regex, rewrite_to]))

    @jsii.member(jsii_name="startsWith")
    @builtins.classmethod
    def starts_with(
        cls,
        prefix: builtins.str,
        rewrite_to: typing.Optional[builtins.str] = None,
    ) -> "HttpGatewayRoutePathMatch":
        '''The value of the path must match the specified prefix.

        :param prefix: the value to use to match the beginning of the path part of the URL of the request. It must start with the '/' character. When ``rewriteTo`` is provided, it must also end with the '/' character. If provided as "/", matches all 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".
        :param rewrite_to: Specify either disabling automatic rewrite or rewriting to specified prefix path. To disable automatic rewrite, provide ``''``. As a default, request's URL path is automatically rewritten to '/'.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayRoutePathMatch.starts_with)
            check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
            check_type(argname="argument rewrite_to", value=rewrite_to, expected_type=type_hints["rewrite_to"])
        return typing.cast("HttpGatewayRoutePathMatch", jsii.sinvoke(cls, "startsWith", [prefix, rewrite_to]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "HttpGatewayRoutePathMatchConfig":
        '''Returns the gateway route path match configuration.

        :param scope: -
        '''
        ...


class _HttpGatewayRoutePathMatchProxy(HttpGatewayRoutePathMatch):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "HttpGatewayRoutePathMatchConfig":
        '''Returns the gateway route path match configuration.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayRoutePathMatch.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("HttpGatewayRoutePathMatchConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, HttpGatewayRoutePathMatch).__jsii_proxy_class__ = lambda : _HttpGatewayRoutePathMatchProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpGatewayRoutePathMatchConfig",
    jsii_struct_bases=[],
    name_mapping={
        "prefix_path_match": "prefixPathMatch",
        "prefix_path_rewrite": "prefixPathRewrite",
        "whole_path_match": "wholePathMatch",
        "whole_path_rewrite": "wholePathRewrite",
    },
)
class HttpGatewayRoutePathMatchConfig:
    def __init__(
        self,
        *,
        prefix_path_match: typing.Optional[builtins.str] = None,
        prefix_path_rewrite: typing.Optional[typing.Union[CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty, typing.Dict[str, typing.Any]]] = None,
        whole_path_match: typing.Optional[typing.Union[CfnGatewayRoute.HttpPathMatchProperty, typing.Dict[str, typing.Any]]] = None,
        whole_path_rewrite: typing.Optional[typing.Union[CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''The type returned from the ``bind()`` method in {@link HttpGatewayRoutePathMatch}.

        :param prefix_path_match: Gateway route configuration for matching on the prefix of the URL path of the request. Default: - no matching will be performed on the prefix of the URL path
        :param prefix_path_rewrite: Gateway route configuration for rewriting the prefix of the URL path of the request. Default: - rewrites the request's URL path to '/'
        :param whole_path_match: Gateway route configuration for matching on the complete URL path of the request. Default: - no matching will be performed on the complete URL path
        :param whole_path_rewrite: Gateway route configuration for rewriting the complete URL path of the request.. Default: - no rewrite will be performed on the request's complete URL path

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            http_gateway_route_path_match_config = appmesh.HttpGatewayRoutePathMatchConfig(
                prefix_path_match="prefixPathMatch",
                prefix_path_rewrite=appmesh.CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(
                    default_prefix="defaultPrefix",
                    value="value"
                ),
                whole_path_match=appmesh.CfnGatewayRoute.HttpPathMatchProperty(
                    exact="exact",
                    regex="regex"
                ),
                whole_path_rewrite=appmesh.CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(
                    exact="exact"
                )
            )
        '''
        if isinstance(prefix_path_rewrite, dict):
            prefix_path_rewrite = CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty(**prefix_path_rewrite)
        if isinstance(whole_path_match, dict):
            whole_path_match = CfnGatewayRoute.HttpPathMatchProperty(**whole_path_match)
        if isinstance(whole_path_rewrite, dict):
            whole_path_rewrite = CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty(**whole_path_rewrite)
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayRoutePathMatchConfig.__init__)
            check_type(argname="argument prefix_path_match", value=prefix_path_match, expected_type=type_hints["prefix_path_match"])
            check_type(argname="argument prefix_path_rewrite", value=prefix_path_rewrite, expected_type=type_hints["prefix_path_rewrite"])
            check_type(argname="argument whole_path_match", value=whole_path_match, expected_type=type_hints["whole_path_match"])
            check_type(argname="argument whole_path_rewrite", value=whole_path_rewrite, expected_type=type_hints["whole_path_rewrite"])
        self._values: typing.Dict[str, typing.Any] = {}
        if prefix_path_match is not None:
            self._values["prefix_path_match"] = prefix_path_match
        if prefix_path_rewrite is not None:
            self._values["prefix_path_rewrite"] = prefix_path_rewrite
        if whole_path_match is not None:
            self._values["whole_path_match"] = whole_path_match
        if whole_path_rewrite is not None:
            self._values["whole_path_rewrite"] = whole_path_rewrite

    @builtins.property
    def prefix_path_match(self) -> typing.Optional[builtins.str]:
        '''Gateway route configuration for matching on the prefix of the URL path of the request.

        :default: - no matching will be performed on the prefix of the URL path
        '''
        result = self._values.get("prefix_path_match")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def prefix_path_rewrite(
        self,
    ) -> typing.Optional[CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty]:
        '''Gateway route configuration for rewriting the prefix of the URL path of the request.

        :default: - rewrites the request's URL path to '/'
        '''
        result = self._values.get("prefix_path_rewrite")
        return typing.cast(typing.Optional[CfnGatewayRoute.HttpGatewayRoutePrefixRewriteProperty], result)

    @builtins.property
    def whole_path_match(
        self,
    ) -> typing.Optional[CfnGatewayRoute.HttpPathMatchProperty]:
        '''Gateway route configuration for matching on the complete URL path of the request.

        :default: - no matching will be performed on the complete URL path
        '''
        result = self._values.get("whole_path_match")
        return typing.cast(typing.Optional[CfnGatewayRoute.HttpPathMatchProperty], result)

    @builtins.property
    def whole_path_rewrite(
        self,
    ) -> typing.Optional[CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty]:
        '''Gateway route configuration for rewriting the complete URL path of the request..

        :default: - no rewrite will be performed on the request's complete URL path
        '''
        result = self._values.get("whole_path_rewrite")
        return typing.cast(typing.Optional[CfnGatewayRoute.HttpGatewayRoutePathRewriteProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpGatewayRoutePathMatchConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpGatewayRouteSpecOptions",
    jsii_struct_bases=[CommonGatewayRouteSpecOptions],
    name_mapping={
        "priority": "priority",
        "route_target": "routeTarget",
        "match": "match",
    },
)
class HttpGatewayRouteSpecOptions(CommonGatewayRouteSpecOptions):
    def __init__(
        self,
        *,
        priority: typing.Optional[jsii.Number] = None,
        route_target: "IVirtualService",
        match: typing.Optional[typing.Union[HttpGatewayRouteMatch, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Properties specific for HTTP Based GatewayRoutes.

        :param priority: The priority for the gateway route. When a Virtual Gateway has multiple gateway routes, gateway route match is performed in the order of specified value, where 0 is the highest priority, and first matched gateway route is selected. Default: - no particular priority
        :param route_target: The VirtualService this GatewayRoute directs traffic to.
        :param match: The criterion for determining a request match for this GatewayRoute. When path match is defined, this may optionally determine the path rewrite configuration. Default: - matches any path and automatically rewrites the path to '/'

        :exampleMetadata: infused

        Example::

            # gateway: appmesh.VirtualGateway
            # virtual_service: appmesh.VirtualService
            
            
            gateway.add_gateway_route("gateway-route-http-2",
                route_spec=appmesh.GatewayRouteSpec.http(
                    route_target=virtual_service,
                    match=appmesh.HttpGatewayRouteMatch(
                        # This rewrites the path from '/test' to '/rewrittenPath'.
                        path=appmesh.HttpGatewayRoutePathMatch.exactly("/test", "/rewrittenPath")
                    )
                )
            )
        '''
        if isinstance(match, dict):
            match = HttpGatewayRouteMatch(**match)
        if __debug__:
            type_hints = typing.get_type_hints(HttpGatewayRouteSpecOptions.__init__)
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            check_type(argname="argument route_target", value=route_target, expected_type=type_hints["route_target"])
            check_type(argname="argument match", value=match, expected_type=type_hints["match"])
        self._values: typing.Dict[str, typing.Any] = {
            "route_target": route_target,
        }
        if priority is not None:
            self._values["priority"] = priority
        if match is not None:
            self._values["match"] = match

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the gateway route.

        When a Virtual Gateway has multiple gateway routes, gateway route match
        is performed in the order of specified value, where 0 is the highest priority,
        and first matched gateway route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def route_target(self) -> "IVirtualService":
        '''The VirtualService this GatewayRoute directs traffic to.'''
        result = self._values.get("route_target")
        assert result is not None, "Required property 'route_target' is missing"
        return typing.cast("IVirtualService", result)

    @builtins.property
    def match(self) -> typing.Optional[HttpGatewayRouteMatch]:
        '''The criterion for determining a request match for this GatewayRoute.

        When path match is defined, this may optionally determine the path rewrite configuration.

        :default: - matches any path and automatically rewrites the path to '/'
        '''
        result = self._values.get("match")
        return typing.cast(typing.Optional[HttpGatewayRouteMatch], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpGatewayRouteSpecOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpHealthCheckOptions",
    jsii_struct_bases=[],
    name_mapping={
        "healthy_threshold": "healthyThreshold",
        "interval": "interval",
        "path": "path",
        "timeout": "timeout",
        "unhealthy_threshold": "unhealthyThreshold",
    },
)
class HttpHealthCheckOptions:
    def __init__(
        self,
        *,
        healthy_threshold: typing.Optional[jsii.Number] = None,
        interval: typing.Optional[aws_cdk.core.Duration] = None,
        path: typing.Optional[builtins.str] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
        unhealthy_threshold: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties used to define HTTP Based healthchecks.

        :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy. Default: 2
        :param interval: The time period between each health check execution. Default: Duration.seconds(5)
        :param path: The destination path for the health check request. Default: /
        :param timeout: The amount of time to wait when receiving a response from the health check. Default: Duration.seconds(2)
        :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a listener unhealthy. Default: - 2

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            vpc = ec2.Vpc(self, "vpc")
            namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
                vpc=vpc,
                name="domain.local"
            )
            service = namespace.create_service("Svc")
            node = mesh.add_virtual_node("virtual-node",
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=8081,
                    health_check=appmesh.HealthCheck.http(
                        healthy_threshold=3,
                        interval=cdk.Duration.seconds(5),  # minimum
                        path="/health-check-path",
                        timeout=cdk.Duration.seconds(2),  # minimum
                        unhealthy_threshold=2
                    )
                )],
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpHealthCheckOptions.__init__)
            check_type(argname="argument healthy_threshold", value=healthy_threshold, expected_type=type_hints["healthy_threshold"])
            check_type(argname="argument interval", value=interval, expected_type=type_hints["interval"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            check_type(argname="argument unhealthy_threshold", value=unhealthy_threshold, expected_type=type_hints["unhealthy_threshold"])
        self._values: typing.Dict[str, typing.Any] = {}
        if healthy_threshold is not None:
            self._values["healthy_threshold"] = healthy_threshold
        if interval is not None:
            self._values["interval"] = interval
        if path is not None:
            self._values["path"] = path
        if timeout is not None:
            self._values["timeout"] = timeout
        if unhealthy_threshold is not None:
            self._values["unhealthy_threshold"] = unhealthy_threshold

    @builtins.property
    def healthy_threshold(self) -> typing.Optional[jsii.Number]:
        '''The number of consecutive successful health checks that must occur before declaring listener healthy.

        :default: 2
        '''
        result = self._values.get("healthy_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def interval(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The time period between each health check execution.

        :default: Duration.seconds(5)
        '''
        result = self._values.get("interval")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def path(self) -> typing.Optional[builtins.str]:
        '''The destination path for the health check request.

        :default: /
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The amount of time to wait when receiving a response from the health check.

        :default: Duration.seconds(2)
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def unhealthy_threshold(self) -> typing.Optional[jsii.Number]:
        '''The number of consecutive failed health checks that must occur before declaring a listener unhealthy.

        :default: - 2
        '''
        result = self._values.get("unhealthy_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpHealthCheckOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.HttpRetryEvent")
class HttpRetryEvent(enum.Enum):
    '''HTTP events on which to retry.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http2-retry",
            route_spec=appmesh.RouteSpec.http2(
                weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                retry_policy=appmesh.HttpRetryPolicy(
                    # Retry if the connection failed
                    tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                    # Retry if HTTP responds with a gateway error (502, 503, 504)
                    http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                    # Retry five times
                    retry_attempts=5,
                    # Use a 1 second timeout per retry
                    retry_timeout=cdk.Duration.seconds(1)
                )
            )
        )
    '''

    SERVER_ERROR = "SERVER_ERROR"
    '''HTTP status codes 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, and 511.'''
    GATEWAY_ERROR = "GATEWAY_ERROR"
    '''HTTP status codes 502, 503, and 504.'''
    CLIENT_ERROR = "CLIENT_ERROR"
    '''HTTP status code 409.'''
    STREAM_ERROR = "STREAM_ERROR"
    '''Retry on refused stream.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpRetryPolicy",
    jsii_struct_bases=[],
    name_mapping={
        "retry_attempts": "retryAttempts",
        "retry_timeout": "retryTimeout",
        "http_retry_events": "httpRetryEvents",
        "tcp_retry_events": "tcpRetryEvents",
    },
)
class HttpRetryPolicy:
    def __init__(
        self,
        *,
        retry_attempts: jsii.Number,
        retry_timeout: aws_cdk.core.Duration,
        http_retry_events: typing.Optional[typing.Sequence[HttpRetryEvent]] = None,
        tcp_retry_events: typing.Optional[typing.Sequence["TcpRetryEvent"]] = None,
    ) -> None:
        '''HTTP retry policy.

        :param retry_attempts: The maximum number of retry attempts.
        :param retry_timeout: The timeout for each retry attempt.
        :param http_retry_events: Specify HTTP events on which to retry. You must specify at least one value for at least one types of retry events. Default: - no retries for http events
        :param tcp_retry_events: TCP events on which to retry. The event occurs before any processing of a request has started and is encountered when the upstream is temporarily or permanently unavailable. You must specify at least one value for at least one types of retry events. Default: - no retries for tcp events

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-http2-retry",
                route_spec=appmesh.RouteSpec.http2(
                    weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                    retry_policy=appmesh.HttpRetryPolicy(
                        # Retry if the connection failed
                        tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                        # Retry if HTTP responds with a gateway error (502, 503, 504)
                        http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                        # Retry five times
                        retry_attempts=5,
                        # Use a 1 second timeout per retry
                        retry_timeout=cdk.Duration.seconds(1)
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpRetryPolicy.__init__)
            check_type(argname="argument retry_attempts", value=retry_attempts, expected_type=type_hints["retry_attempts"])
            check_type(argname="argument retry_timeout", value=retry_timeout, expected_type=type_hints["retry_timeout"])
            check_type(argname="argument http_retry_events", value=http_retry_events, expected_type=type_hints["http_retry_events"])
            check_type(argname="argument tcp_retry_events", value=tcp_retry_events, expected_type=type_hints["tcp_retry_events"])
        self._values: typing.Dict[str, typing.Any] = {
            "retry_attempts": retry_attempts,
            "retry_timeout": retry_timeout,
        }
        if http_retry_events is not None:
            self._values["http_retry_events"] = http_retry_events
        if tcp_retry_events is not None:
            self._values["tcp_retry_events"] = tcp_retry_events

    @builtins.property
    def retry_attempts(self) -> jsii.Number:
        '''The maximum number of retry attempts.'''
        result = self._values.get("retry_attempts")
        assert result is not None, "Required property 'retry_attempts' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def retry_timeout(self) -> aws_cdk.core.Duration:
        '''The timeout for each retry attempt.'''
        result = self._values.get("retry_timeout")
        assert result is not None, "Required property 'retry_timeout' is missing"
        return typing.cast(aws_cdk.core.Duration, result)

    @builtins.property
    def http_retry_events(self) -> typing.Optional[typing.List[HttpRetryEvent]]:
        '''Specify HTTP events on which to retry.

        You must specify at least one value
        for at least one types of retry events.

        :default: - no retries for http events
        '''
        result = self._values.get("http_retry_events")
        return typing.cast(typing.Optional[typing.List[HttpRetryEvent]], result)

    @builtins.property
    def tcp_retry_events(self) -> typing.Optional[typing.List["TcpRetryEvent"]]:
        '''TCP events on which to retry.

        The event occurs before any processing of a
        request has started and is encountered when the upstream is temporarily or
        permanently unavailable. You must specify at least one value for at least
        one types of retry events.

        :default: - no retries for tcp events
        '''
        result = self._values.get("tcp_retry_events")
        return typing.cast(typing.Optional[typing.List["TcpRetryEvent"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpRetryPolicy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpRouteMatch",
    jsii_struct_bases=[],
    name_mapping={
        "headers": "headers",
        "method": "method",
        "path": "path",
        "protocol": "protocol",
        "query_parameters": "queryParameters",
    },
)
class HttpRouteMatch:
    def __init__(
        self,
        *,
        headers: typing.Optional[typing.Sequence[HeaderMatch]] = None,
        method: typing.Optional["HttpRouteMethod"] = None,
        path: typing.Optional["HttpRoutePathMatch"] = None,
        protocol: typing.Optional["HttpRouteProtocol"] = None,
        query_parameters: typing.Optional[typing.Sequence["QueryParameterMatch"]] = None,
    ) -> None:
        '''The criterion for determining a request match for this Route.

        :param headers: Specifies the client request headers to match on. All specified headers must match for the route to match. Default: - do not match on headers
        :param method: The HTTP client request method to match on. Default: - do not match on request method
        :param path: Specifies how is the request matched based on the path part of its URL. Default: - matches requests with all paths
        :param protocol: The client request protocol to match on. Applicable only for HTTP2 routes. Default: - do not match on HTTP2 request protocol
        :param query_parameters: The query parameters to match on. All specified query parameters must match for the route to match. Default: - do not match on query parameters

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-http",
                route_spec=appmesh.RouteSpec.http(
                    weighted_targets=[appmesh.WeightedTarget(
                        virtual_node=node,
                        weight=50
                    ), appmesh.WeightedTarget(
                        virtual_node=node,
                        weight=50
                    )
                    ],
                    match=appmesh.HttpRouteMatch(
                        path=appmesh.HttpRoutePathMatch.starts_with("/path-to-app")
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpRouteMatch.__init__)
            check_type(argname="argument headers", value=headers, expected_type=type_hints["headers"])
            check_type(argname="argument method", value=method, expected_type=type_hints["method"])
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
            check_type(argname="argument protocol", value=protocol, expected_type=type_hints["protocol"])
            check_type(argname="argument query_parameters", value=query_parameters, expected_type=type_hints["query_parameters"])
        self._values: typing.Dict[str, typing.Any] = {}
        if headers is not None:
            self._values["headers"] = headers
        if method is not None:
            self._values["method"] = method
        if path is not None:
            self._values["path"] = path
        if protocol is not None:
            self._values["protocol"] = protocol
        if query_parameters is not None:
            self._values["query_parameters"] = query_parameters

    @builtins.property
    def headers(self) -> typing.Optional[typing.List[HeaderMatch]]:
        '''Specifies the client request headers to match on.

        All specified headers
        must match for the route to match.

        :default: - do not match on headers
        '''
        result = self._values.get("headers")
        return typing.cast(typing.Optional[typing.List[HeaderMatch]], result)

    @builtins.property
    def method(self) -> typing.Optional["HttpRouteMethod"]:
        '''The HTTP client request method to match on.

        :default: - do not match on request method
        '''
        result = self._values.get("method")
        return typing.cast(typing.Optional["HttpRouteMethod"], result)

    @builtins.property
    def path(self) -> typing.Optional["HttpRoutePathMatch"]:
        '''Specifies how is the request matched based on the path part of its URL.

        :default: - matches requests with all paths
        '''
        result = self._values.get("path")
        return typing.cast(typing.Optional["HttpRoutePathMatch"], result)

    @builtins.property
    def protocol(self) -> typing.Optional["HttpRouteProtocol"]:
        '''The client request protocol to match on.

        Applicable only for HTTP2 routes.

        :default: - do not match on HTTP2 request protocol
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional["HttpRouteProtocol"], result)

    @builtins.property
    def query_parameters(self) -> typing.Optional[typing.List["QueryParameterMatch"]]:
        '''The query parameters to match on.

        All specified query parameters must match for the route to match.

        :default: - do not match on query parameters
        '''
        result = self._values.get("query_parameters")
        return typing.cast(typing.Optional[typing.List["QueryParameterMatch"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpRouteMatch(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.HttpRouteMethod")
class HttpRouteMethod(enum.Enum):
    '''Supported values for matching routes based on the HTTP request method.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http2",
            route_spec=appmesh.RouteSpec.http2(
                weighted_targets=[appmesh.WeightedTarget(
                    virtual_node=node
                )
                ],
                match=appmesh.HttpRouteMatch(
                    path=appmesh.HttpRoutePathMatch.exactly("/exact"),
                    method=appmesh.HttpRouteMethod.POST,
                    protocol=appmesh.HttpRouteProtocol.HTTPS,
                    headers=[
                        # All specified headers must match for the route to match.
                        appmesh.HeaderMatch.value_is("Content-Type", "application/json"),
                        appmesh.HeaderMatch.value_is_not("Content-Type", "application/json")
                    ],
                    query_parameters=[
                        # All specified query parameters must match for the route to match.
                        appmesh.QueryParameterMatch.value_is("query-field", "value")
                    ]
                )
            )
        )
    '''

    GET = "GET"
    '''GET request.'''
    HEAD = "HEAD"
    '''HEAD request.'''
    POST = "POST"
    '''POST request.'''
    PUT = "PUT"
    '''PUT request.'''
    DELETE = "DELETE"
    '''DELETE request.'''
    CONNECT = "CONNECT"
    '''CONNECT request.'''
    OPTIONS = "OPTIONS"
    '''OPTIONS request.'''
    TRACE = "TRACE"
    '''TRACE request.'''
    PATCH = "PATCH"
    '''PATCH request.'''


class HttpRoutePathMatch(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.HttpRoutePathMatch",
):
    '''Defines HTTP route matching based on the URL path of the request.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http",
            route_spec=appmesh.RouteSpec.http(
                weighted_targets=[appmesh.WeightedTarget(
                    virtual_node=node,
                    weight=50
                ), appmesh.WeightedTarget(
                    virtual_node=node,
                    weight=50
                )
                ],
                match=appmesh.HttpRouteMatch(
                    path=appmesh.HttpRoutePathMatch.starts_with("/path-to-app")
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="exactly")
    @builtins.classmethod
    def exactly(cls, path: builtins.str) -> "HttpRoutePathMatch":
        '''The value of the path must match the specified value exactly.

        The provided ``path`` must start with the '/' character.

        :param path: the exact path to match on.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpRoutePathMatch.exactly)
            check_type(argname="argument path", value=path, expected_type=type_hints["path"])
        return typing.cast("HttpRoutePathMatch", jsii.sinvoke(cls, "exactly", [path]))

    @jsii.member(jsii_name="regex")
    @builtins.classmethod
    def regex(cls, regex: builtins.str) -> "HttpRoutePathMatch":
        '''The value of the path must match the specified regex.

        :param regex: the regex used to match the path.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpRoutePathMatch.regex)
            check_type(argname="argument regex", value=regex, expected_type=type_hints["regex"])
        return typing.cast("HttpRoutePathMatch", jsii.sinvoke(cls, "regex", [regex]))

    @jsii.member(jsii_name="startsWith")
    @builtins.classmethod
    def starts_with(cls, prefix: builtins.str) -> "HttpRoutePathMatch":
        '''The value of the path must match the specified prefix.

        :param prefix: the value to use to match the beginning of the path part of the URL of the request. It must start with the '/' character. If provided as "/", matches all 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 __debug__:
            type_hints = typing.get_type_hints(HttpRoutePathMatch.starts_with)
            check_type(argname="argument prefix", value=prefix, expected_type=type_hints["prefix"])
        return typing.cast("HttpRoutePathMatch", jsii.sinvoke(cls, "startsWith", [prefix]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "HttpRoutePathMatchConfig":
        '''Returns the route path match configuration.

        :param scope: -
        '''
        ...


class _HttpRoutePathMatchProxy(HttpRoutePathMatch):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "HttpRoutePathMatchConfig":
        '''Returns the route path match configuration.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpRoutePathMatch.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("HttpRoutePathMatchConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, HttpRoutePathMatch).__jsii_proxy_class__ = lambda : _HttpRoutePathMatchProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpRoutePathMatchConfig",
    jsii_struct_bases=[],
    name_mapping={
        "prefix_path_match": "prefixPathMatch",
        "whole_path_match": "wholePathMatch",
    },
)
class HttpRoutePathMatchConfig:
    def __init__(
        self,
        *,
        prefix_path_match: typing.Optional[builtins.str] = None,
        whole_path_match: typing.Optional[typing.Union[CfnRoute.HttpPathMatchProperty, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''The type returned from the ``bind()`` method in {@link HttpRoutePathMatch}.

        :param prefix_path_match: Route configuration for matching on the prefix of the URL path of the request. Default: - no matching will be performed on the prefix of the URL path
        :param whole_path_match: Route configuration for matching on the complete URL path of the request. Default: - no matching will be performed on the complete URL path

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            http_route_path_match_config = appmesh.HttpRoutePathMatchConfig(
                prefix_path_match="prefixPathMatch",
                whole_path_match=appmesh.CfnRoute.HttpPathMatchProperty(
                    exact="exact",
                    regex="regex"
                )
            )
        '''
        if isinstance(whole_path_match, dict):
            whole_path_match = CfnRoute.HttpPathMatchProperty(**whole_path_match)
        if __debug__:
            type_hints = typing.get_type_hints(HttpRoutePathMatchConfig.__init__)
            check_type(argname="argument prefix_path_match", value=prefix_path_match, expected_type=type_hints["prefix_path_match"])
            check_type(argname="argument whole_path_match", value=whole_path_match, expected_type=type_hints["whole_path_match"])
        self._values: typing.Dict[str, typing.Any] = {}
        if prefix_path_match is not None:
            self._values["prefix_path_match"] = prefix_path_match
        if whole_path_match is not None:
            self._values["whole_path_match"] = whole_path_match

    @builtins.property
    def prefix_path_match(self) -> typing.Optional[builtins.str]:
        '''Route configuration for matching on the prefix of the URL path of the request.

        :default: - no matching will be performed on the prefix of the URL path
        '''
        result = self._values.get("prefix_path_match")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def whole_path_match(self) -> typing.Optional[CfnRoute.HttpPathMatchProperty]:
        '''Route configuration for matching on the complete URL path of the request.

        :default: - no matching will be performed on the complete URL path
        '''
        result = self._values.get("whole_path_match")
        return typing.cast(typing.Optional[CfnRoute.HttpPathMatchProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpRoutePathMatchConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.HttpRouteProtocol")
class HttpRouteProtocol(enum.Enum):
    '''Supported :scheme options for HTTP2.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http2",
            route_spec=appmesh.RouteSpec.http2(
                weighted_targets=[appmesh.WeightedTarget(
                    virtual_node=node
                )
                ],
                match=appmesh.HttpRouteMatch(
                    path=appmesh.HttpRoutePathMatch.exactly("/exact"),
                    method=appmesh.HttpRouteMethod.POST,
                    protocol=appmesh.HttpRouteProtocol.HTTPS,
                    headers=[
                        # All specified headers must match for the route to match.
                        appmesh.HeaderMatch.value_is("Content-Type", "application/json"),
                        appmesh.HeaderMatch.value_is_not("Content-Type", "application/json")
                    ],
                    query_parameters=[
                        # All specified query parameters must match for the route to match.
                        appmesh.QueryParameterMatch.value_is("query-field", "value")
                    ]
                )
            )
        )
    '''

    HTTP = "HTTP"
    '''Match HTTP requests.'''
    HTTPS = "HTTPS"
    '''Match HTTPS requests.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpTimeout",
    jsii_struct_bases=[],
    name_mapping={"idle": "idle", "per_request": "perRequest"},
)
class HttpTimeout:
    def __init__(
        self,
        *,
        idle: typing.Optional[aws_cdk.core.Duration] = None,
        per_request: typing.Optional[aws_cdk.core.Duration] = None,
    ) -> None:
        '''Represents timeouts for HTTP protocols.

        :param idle: Represents an idle timeout. The amount of time that a connection may be idle. Default: - none
        :param per_request: Represents per request timeout. Default: - 15 s

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            # service: cloudmap.Service
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=8080,
                    health_check=appmesh.HealthCheck.http(
                        healthy_threshold=3,
                        interval=cdk.Duration.seconds(5),
                        path="/ping",
                        timeout=cdk.Duration.seconds(2),
                        unhealthy_threshold=2
                    ),
                    timeout=appmesh.HttpTimeout(
                        idle=cdk.Duration.seconds(5)
                    )
                )],
                backend_defaults=appmesh.BackendDefaults(
                    tls_client_policy=appmesh.TlsClientPolicy(
                        validation=appmesh.TlsValidation(
                            trust=appmesh.TlsValidationTrust.file("/keys/local_cert_chain.pem")
                        )
                    )
                ),
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
            )
            
            cdk.Tags.of(node).add("Environment", "Dev")
        '''
        if __debug__:
            type_hints = typing.get_type_hints(HttpTimeout.__init__)
            check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
            check_type(argname="argument per_request", value=per_request, expected_type=type_hints["per_request"])
        self._values: typing.Dict[str, typing.Any] = {}
        if idle is not None:
            self._values["idle"] = idle
        if per_request is not None:
            self._values["per_request"] = per_request

    @builtins.property
    def idle(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''Represents an idle timeout.

        The amount of time that a connection may be idle.

        :default: - none
        '''
        result = self._values.get("idle")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def per_request(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''Represents per request timeout.

        :default: - 15 s
        '''
        result = self._values.get("per_request")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpTimeout(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpVirtualNodeListenerOptions",
    jsii_struct_bases=[],
    name_mapping={
        "connection_pool": "connectionPool",
        "health_check": "healthCheck",
        "outlier_detection": "outlierDetection",
        "port": "port",
        "timeout": "timeout",
        "tls": "tls",
    },
)
class HttpVirtualNodeListenerOptions:
    def __init__(
        self,
        *,
        connection_pool: typing.Optional[typing.Union[HttpConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        outlier_detection: typing.Optional[typing.Union["OutlierDetection", typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union[HttpTimeout, typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union["ListenerTlsOptions", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represent the HTTP Node Listener prorperty.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for HTTP protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            vpc = ec2.Vpc(self, "vpc")
            namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
                vpc=vpc,
                name="domain.local"
            )
            service = namespace.create_service("Svc")
            node = mesh.add_virtual_node("virtual-node",
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=8081,
                    health_check=appmesh.HealthCheck.http(
                        healthy_threshold=3,
                        interval=cdk.Duration.seconds(5),  # minimum
                        path="/health-check-path",
                        timeout=cdk.Duration.seconds(2),  # minimum
                        unhealthy_threshold=2
                    )
                )],
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
            )
        '''
        if isinstance(connection_pool, dict):
            connection_pool = HttpConnectionPool(**connection_pool)
        if isinstance(outlier_detection, dict):
            outlier_detection = OutlierDetection(**outlier_detection)
        if isinstance(timeout, dict):
            timeout = HttpTimeout(**timeout)
        if isinstance(tls, dict):
            tls = ListenerTlsOptions(**tls)
        if __debug__:
            type_hints = typing.get_type_hints(HttpVirtualNodeListenerOptions.__init__)
            check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
            check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
            check_type(argname="argument outlier_detection", value=outlier_detection, expected_type=type_hints["outlier_detection"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_pool is not None:
            self._values["connection_pool"] = connection_pool
        if health_check is not None:
            self._values["health_check"] = health_check
        if outlier_detection is not None:
            self._values["outlier_detection"] = outlier_detection
        if port is not None:
            self._values["port"] = port
        if timeout is not None:
            self._values["timeout"] = timeout
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def connection_pool(self) -> typing.Optional[HttpConnectionPool]:
        '''Connection pool for http listeners.

        :default: - None
        '''
        result = self._values.get("connection_pool")
        return typing.cast(typing.Optional[HttpConnectionPool], result)

    @builtins.property
    def health_check(self) -> typing.Optional[HealthCheck]:
        '''The health check information for the listener.

        :default: - no healthcheck
        '''
        result = self._values.get("health_check")
        return typing.cast(typing.Optional[HealthCheck], result)

    @builtins.property
    def outlier_detection(self) -> typing.Optional["OutlierDetection"]:
        '''Represents the configuration for enabling outlier detection.

        :default: - none
        '''
        result = self._values.get("outlier_detection")
        return typing.cast(typing.Optional["OutlierDetection"], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''Port to listen for connections on.

        :default: - 8080
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def timeout(self) -> typing.Optional[HttpTimeout]:
        '''Timeout for HTTP protocol.

        :default: - None
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[HttpTimeout], result)

    @builtins.property
    def tls(self) -> typing.Optional["ListenerTlsOptions"]:
        '''Represents the configuration for enabling TLS on a listener.

        :default: - none
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional["ListenerTlsOptions"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpVirtualNodeListenerOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.interface(jsii_type="@aws-cdk/aws-appmesh.IGatewayRoute")
class IGatewayRoute(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface for which all GatewayRoute based classes MUST implement.'''

    @builtins.property
    @jsii.member(jsii_name="gatewayRouteArn")
    def gateway_route_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the GatewayRoute.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="gatewayRouteName")
    def gateway_route_name(self) -> builtins.str:
        '''The name of the GatewayRoute.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualGateway")
    def virtual_gateway(self) -> "IVirtualGateway":
        '''The VirtualGateway the GatewayRoute belongs to.'''
        ...


class _IGatewayRouteProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
):
    '''Interface for which all GatewayRoute based classes MUST implement.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-appmesh.IGatewayRoute"

    @builtins.property
    @jsii.member(jsii_name="gatewayRouteArn")
    def gateway_route_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the GatewayRoute.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "gatewayRouteArn"))

    @builtins.property
    @jsii.member(jsii_name="gatewayRouteName")
    def gateway_route_name(self) -> builtins.str:
        '''The name of the GatewayRoute.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "gatewayRouteName"))

    @builtins.property
    @jsii.member(jsii_name="virtualGateway")
    def virtual_gateway(self) -> "IVirtualGateway":
        '''The VirtualGateway the GatewayRoute belongs to.'''
        return typing.cast("IVirtualGateway", jsii.get(self, "virtualGateway"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IGatewayRoute).__jsii_proxy_class__ = lambda : _IGatewayRouteProxy


@jsii.interface(jsii_type="@aws-cdk/aws-appmesh.IMesh")
class IMesh(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface which all Mesh based classes MUST implement.'''

    @builtins.property
    @jsii.member(jsii_name="meshArn")
    def mesh_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) of the AppMesh mesh.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the AppMesh mesh.

        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="addVirtualGateway")
    def add_virtual_gateway(
        self,
        id: builtins.str,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualGatewayListener"]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualGateway":
        '''Creates a new VirtualGateway in this Mesh.

        Note that the Gateway is created in the same Stack that this Mesh belongs to,
        which might be different than the current stack.

        :param id: -
        :param access_log: Access Logging Configuration for the VirtualGateway. Default: - no access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param listeners: Listeners for the VirtualGateway. Only one is supported. Default: - Single HTTP listener on port 8080
        :param virtual_gateway_name: Name of the VirtualGateway. Default: - A name is automatically determined
        '''
        ...

    @jsii.member(jsii_name="addVirtualNode")
    def add_virtual_node(
        self,
        id: builtins.str,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        backends: typing.Optional[typing.Sequence[Backend]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualNodeListener"]] = None,
        service_discovery: typing.Optional["ServiceDiscovery"] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualNode":
        '''Creates a new VirtualNode in this Mesh.

        Note that the Node is created in the same Stack that this Mesh belongs to,
        which might be different than the current stack.

        :param id: -
        :param access_log: Access Logging Configuration for the virtual node. Default: - No access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param backends: Virtual Services that this is node expected to send outbound traffic to. Default: - No backends
        :param listeners: Initial listener for the virtual node. Default: - No listeners
        :param service_discovery: Defines how upstream clients will discover this VirtualNode. Default: - No Service Discovery
        :param virtual_node_name: The name of the VirtualNode. Default: - A name is automatically determined
        '''
        ...

    @jsii.member(jsii_name="addVirtualRouter")
    def add_virtual_router(
        self,
        id: builtins.str,
        *,
        listeners: typing.Optional[typing.Sequence["VirtualRouterListener"]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualRouter":
        '''Creates a new VirtualRouter in this Mesh.

        Note that the Router is created in the same Stack that this Mesh belongs to,
        which might be different than the current stack.

        :param id: -
        :param listeners: Listener specification for the VirtualRouter. Default: - A listener on HTTP port 8080
        :param virtual_router_name: The name of the VirtualRouter. Default: - A name is automatically determined
        '''
        ...


class _IMeshProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
):
    '''Interface which all Mesh based classes MUST implement.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-appmesh.IMesh"

    @builtins.property
    @jsii.member(jsii_name="meshArn")
    def mesh_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) of the AppMesh mesh.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshArn"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the AppMesh mesh.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))

    @jsii.member(jsii_name="addVirtualGateway")
    def add_virtual_gateway(
        self,
        id: builtins.str,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualGatewayListener"]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualGateway":
        '''Creates a new VirtualGateway in this Mesh.

        Note that the Gateway is created in the same Stack that this Mesh belongs to,
        which might be different than the current stack.

        :param id: -
        :param access_log: Access Logging Configuration for the VirtualGateway. Default: - no access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param listeners: Listeners for the VirtualGateway. Only one is supported. Default: - Single HTTP listener on port 8080
        :param virtual_gateway_name: Name of the VirtualGateway. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(IMesh.add_virtual_gateway)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualGatewayBaseProps(
            access_log=access_log,
            backend_defaults=backend_defaults,
            listeners=listeners,
            virtual_gateway_name=virtual_gateway_name,
        )

        return typing.cast("VirtualGateway", jsii.invoke(self, "addVirtualGateway", [id, props]))

    @jsii.member(jsii_name="addVirtualNode")
    def add_virtual_node(
        self,
        id: builtins.str,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        backends: typing.Optional[typing.Sequence[Backend]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualNodeListener"]] = None,
        service_discovery: typing.Optional["ServiceDiscovery"] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualNode":
        '''Creates a new VirtualNode in this Mesh.

        Note that the Node is created in the same Stack that this Mesh belongs to,
        which might be different than the current stack.

        :param id: -
        :param access_log: Access Logging Configuration for the virtual node. Default: - No access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param backends: Virtual Services that this is node expected to send outbound traffic to. Default: - No backends
        :param listeners: Initial listener for the virtual node. Default: - No listeners
        :param service_discovery: Defines how upstream clients will discover this VirtualNode. Default: - No Service Discovery
        :param virtual_node_name: The name of the VirtualNode. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(IMesh.add_virtual_node)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualNodeBaseProps(
            access_log=access_log,
            backend_defaults=backend_defaults,
            backends=backends,
            listeners=listeners,
            service_discovery=service_discovery,
            virtual_node_name=virtual_node_name,
        )

        return typing.cast("VirtualNode", jsii.invoke(self, "addVirtualNode", [id, props]))

    @jsii.member(jsii_name="addVirtualRouter")
    def add_virtual_router(
        self,
        id: builtins.str,
        *,
        listeners: typing.Optional[typing.Sequence["VirtualRouterListener"]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualRouter":
        '''Creates a new VirtualRouter in this Mesh.

        Note that the Router is created in the same Stack that this Mesh belongs to,
        which might be different than the current stack.

        :param id: -
        :param listeners: Listener specification for the VirtualRouter. Default: - A listener on HTTP port 8080
        :param virtual_router_name: The name of the VirtualRouter. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(IMesh.add_virtual_router)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualRouterBaseProps(
            listeners=listeners, virtual_router_name=virtual_router_name
        )

        return typing.cast("VirtualRouter", jsii.invoke(self, "addVirtualRouter", [id, props]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IMesh).__jsii_proxy_class__ = lambda : _IMeshProxy


@jsii.interface(jsii_type="@aws-cdk/aws-appmesh.IRoute")
class IRoute(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface for which all Route based classes MUST implement.'''

    @builtins.property
    @jsii.member(jsii_name="routeArn")
    def route_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the route.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="routeName")
    def route_name(self) -> builtins.str:
        '''The name of the route.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualRouter")
    def virtual_router(self) -> "IVirtualRouter":
        '''The VirtualRouter the Route belongs to.'''
        ...


class _IRouteProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
):
    '''Interface for which all Route based classes MUST implement.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-appmesh.IRoute"

    @builtins.property
    @jsii.member(jsii_name="routeArn")
    def route_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the route.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "routeArn"))

    @builtins.property
    @jsii.member(jsii_name="routeName")
    def route_name(self) -> builtins.str:
        '''The name of the route.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "routeName"))

    @builtins.property
    @jsii.member(jsii_name="virtualRouter")
    def virtual_router(self) -> "IVirtualRouter":
        '''The VirtualRouter the Route belongs to.'''
        return typing.cast("IVirtualRouter", jsii.get(self, "virtualRouter"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IRoute).__jsii_proxy_class__ = lambda : _IRouteProxy


@jsii.interface(jsii_type="@aws-cdk/aws-appmesh.IVirtualGateway")
class IVirtualGateway(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface which all Virtual Gateway based classes must implement.'''

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualGateway belongs to.'''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayArn")
    def virtual_gateway_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the VirtualGateway.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayName")
    def virtual_gateway_name(self) -> builtins.str:
        '''Name of the VirtualGateway.

        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="addGatewayRoute")
    def add_gateway_route(
        self,
        id: builtins.str,
        *,
        route_spec: GatewayRouteSpec,
        gateway_route_name: typing.Optional[builtins.str] = None,
    ) -> "GatewayRoute":
        '''Utility method to add a new GatewayRoute to the VirtualGateway.

        :param id: -
        :param route_spec: What protocol the route uses.
        :param gateway_route_name: The name of the GatewayRoute. Default: - an automatically generated name
        '''
        ...

    @jsii.member(jsii_name="grantStreamAggregatedResources")
    def grant_stream_aggregated_resources(
        self,
        identity: aws_cdk.aws_iam.IGrantable,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants the given entity ``appmesh:StreamAggregatedResources``.

        :param identity: -
        '''
        ...


class _IVirtualGatewayProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
):
    '''Interface which all Virtual Gateway based classes must implement.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-appmesh.IVirtualGateway"

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualGateway belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayArn")
    def virtual_gateway_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the VirtualGateway.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualGatewayArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayName")
    def virtual_gateway_name(self) -> builtins.str:
        '''Name of the VirtualGateway.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualGatewayName"))

    @jsii.member(jsii_name="addGatewayRoute")
    def add_gateway_route(
        self,
        id: builtins.str,
        *,
        route_spec: GatewayRouteSpec,
        gateway_route_name: typing.Optional[builtins.str] = None,
    ) -> "GatewayRoute":
        '''Utility method to add a new GatewayRoute to the VirtualGateway.

        :param id: -
        :param route_spec: What protocol the route uses.
        :param gateway_route_name: The name of the GatewayRoute. Default: - an automatically generated name
        '''
        if __debug__:
            type_hints = typing.get_type_hints(IVirtualGateway.add_gateway_route)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        route = GatewayRouteBaseProps(
            route_spec=route_spec, gateway_route_name=gateway_route_name
        )

        return typing.cast("GatewayRoute", jsii.invoke(self, "addGatewayRoute", [id, route]))

    @jsii.member(jsii_name="grantStreamAggregatedResources")
    def grant_stream_aggregated_resources(
        self,
        identity: aws_cdk.aws_iam.IGrantable,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants the given entity ``appmesh:StreamAggregatedResources``.

        :param identity: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(IVirtualGateway.grant_stream_aggregated_resources)
            check_type(argname="argument identity", value=identity, expected_type=type_hints["identity"])
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantStreamAggregatedResources", [identity]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IVirtualGateway).__jsii_proxy_class__ = lambda : _IVirtualGatewayProxy


@jsii.interface(jsii_type="@aws-cdk/aws-appmesh.IVirtualNode")
class IVirtualNode(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface which all VirtualNode based classes must implement.'''

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualNode belongs to.'''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualNodeArn")
    def virtual_node_arn(self) -> builtins.str:
        '''The Amazon Resource Name belonging to the VirtualNode.

        Set this value as the APPMESH_VIRTUAL_NODE_NAME environment variable for
        your task group's Envoy proxy container in your task definition or pod
        spec.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualNodeName")
    def virtual_node_name(self) -> builtins.str:
        '''The name of the VirtualNode.

        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="grantStreamAggregatedResources")
    def grant_stream_aggregated_resources(
        self,
        identity: aws_cdk.aws_iam.IGrantable,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants the given entity ``appmesh:StreamAggregatedResources``.

        :param identity: -
        '''
        ...


class _IVirtualNodeProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
):
    '''Interface which all VirtualNode based classes must implement.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-appmesh.IVirtualNode"

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualNode belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualNodeArn")
    def virtual_node_arn(self) -> builtins.str:
        '''The Amazon Resource Name belonging to the VirtualNode.

        Set this value as the APPMESH_VIRTUAL_NODE_NAME environment variable for
        your task group's Envoy proxy container in your task definition or pod
        spec.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualNodeArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualNodeName")
    def virtual_node_name(self) -> builtins.str:
        '''The name of the VirtualNode.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualNodeName"))

    @jsii.member(jsii_name="grantStreamAggregatedResources")
    def grant_stream_aggregated_resources(
        self,
        identity: aws_cdk.aws_iam.IGrantable,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants the given entity ``appmesh:StreamAggregatedResources``.

        :param identity: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(IVirtualNode.grant_stream_aggregated_resources)
            check_type(argname="argument identity", value=identity, expected_type=type_hints["identity"])
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantStreamAggregatedResources", [identity]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IVirtualNode).__jsii_proxy_class__ = lambda : _IVirtualNodeProxy


@jsii.interface(jsii_type="@aws-cdk/aws-appmesh.IVirtualRouter")
class IVirtualRouter(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface which all VirtualRouter based classes MUST implement.'''

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualRouter belongs to.'''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualRouterArn")
    def virtual_router_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the VirtualRouter.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualRouterName")
    def virtual_router_name(self) -> builtins.str:
        '''The name of the VirtualRouter.

        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="addRoute")
    def add_route(
        self,
        id: builtins.str,
        *,
        route_spec: "RouteSpec",
        route_name: typing.Optional[builtins.str] = None,
    ) -> "Route":
        '''Add a single route to the router.

        :param id: -
        :param route_spec: Protocol specific spec.
        :param route_name: The name of the route. Default: - An automatically generated name
        '''
        ...


class _IVirtualRouterProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
):
    '''Interface which all VirtualRouter based classes MUST implement.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-appmesh.IVirtualRouter"

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualRouter belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualRouterArn")
    def virtual_router_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the VirtualRouter.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualRouterArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualRouterName")
    def virtual_router_name(self) -> builtins.str:
        '''The name of the VirtualRouter.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualRouterName"))

    @jsii.member(jsii_name="addRoute")
    def add_route(
        self,
        id: builtins.str,
        *,
        route_spec: "RouteSpec",
        route_name: typing.Optional[builtins.str] = None,
    ) -> "Route":
        '''Add a single route to the router.

        :param id: -
        :param route_spec: Protocol specific spec.
        :param route_name: The name of the route. Default: - An automatically generated name
        '''
        if __debug__:
            type_hints = typing.get_type_hints(IVirtualRouter.add_route)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = RouteBaseProps(route_spec=route_spec, route_name=route_name)

        return typing.cast("Route", jsii.invoke(self, "addRoute", [id, props]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IVirtualRouter).__jsii_proxy_class__ = lambda : _IVirtualRouterProxy


@jsii.interface(jsii_type="@aws-cdk/aws-appmesh.IVirtualService")
class IVirtualService(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Represents the interface which all VirtualService based classes MUST implement.'''

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualService belongs to.'''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualServiceArn")
    def virtual_service_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the virtual service.

        :attribute: true
        '''
        ...

    @builtins.property
    @jsii.member(jsii_name="virtualServiceName")
    def virtual_service_name(self) -> builtins.str:
        '''The name of the VirtualService.

        :attribute: true
        '''
        ...


class _IVirtualServiceProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
):
    '''Represents the interface which all VirtualService based classes MUST implement.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-appmesh.IVirtualService"

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualService belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualServiceArn")
    def virtual_service_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the virtual service.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualServiceArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualServiceName")
    def virtual_service_name(self) -> builtins.str:
        '''The name of the VirtualService.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "virtualServiceName"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IVirtualService).__jsii_proxy_class__ = lambda : _IVirtualServiceProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.ListenerTlsOptions",
    jsii_struct_bases=[],
    name_mapping={
        "certificate": "certificate",
        "mode": "mode",
        "mutual_tls_validation": "mutualTlsValidation",
    },
)
class ListenerTlsOptions:
    def __init__(
        self,
        *,
        certificate: "TlsCertificate",
        mode: "TlsMode",
        mutual_tls_validation: typing.Optional[typing.Union["MutualTlsValidation", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents TLS properties for listener.

        :param certificate: Represents TLS certificate.
        :param mode: The TLS mode.
        :param mutual_tls_validation: Represents a listener's TLS validation context. The client certificate will only be validated if the client provides it, enabling mutual TLS. Default: - client TLS certificate is not required

        :exampleMetadata: infused

        Example::

            # A Virtual Node with listener TLS from an ACM provided certificate
            # cert: certificatemanager.Certificate
            # mesh: appmesh.Mesh
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.dns("node"),
                listeners=[appmesh.VirtualNodeListener.grpc(
                    port=80,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.acm(cert)
                    )
                )]
            )
            
            # A Virtual Gateway with listener TLS from a customer provided file certificate
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.grpc(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey")
                    )
                )],
                virtual_gateway_name="gateway"
            )
            
            # A Virtual Gateway with listener TLS from a SDS provided certificate
            gateway2 = appmesh.VirtualGateway(self, "gateway2",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.http2(
                    port=8080,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.sds("secrete_certificate")
                    )
                )],
                virtual_gateway_name="gateway2"
            )
        '''
        if isinstance(mutual_tls_validation, dict):
            mutual_tls_validation = MutualTlsValidation(**mutual_tls_validation)
        if __debug__:
            type_hints = typing.get_type_hints(ListenerTlsOptions.__init__)
            check_type(argname="argument certificate", value=certificate, expected_type=type_hints["certificate"])
            check_type(argname="argument mode", value=mode, expected_type=type_hints["mode"])
            check_type(argname="argument mutual_tls_validation", value=mutual_tls_validation, expected_type=type_hints["mutual_tls_validation"])
        self._values: typing.Dict[str, typing.Any] = {
            "certificate": certificate,
            "mode": mode,
        }
        if mutual_tls_validation is not None:
            self._values["mutual_tls_validation"] = mutual_tls_validation

    @builtins.property
    def certificate(self) -> "TlsCertificate":
        '''Represents TLS certificate.'''
        result = self._values.get("certificate")
        assert result is not None, "Required property 'certificate' is missing"
        return typing.cast("TlsCertificate", result)

    @builtins.property
    def mode(self) -> "TlsMode":
        '''The TLS mode.'''
        result = self._values.get("mode")
        assert result is not None, "Required property 'mode' is missing"
        return typing.cast("TlsMode", result)

    @builtins.property
    def mutual_tls_validation(self) -> typing.Optional["MutualTlsValidation"]:
        '''Represents a listener's TLS validation context.

        The client certificate will only be validated if the client provides it, enabling mutual TLS.

        :default: - client TLS certificate is not required
        '''
        result = self._values.get("mutual_tls_validation")
        return typing.cast(typing.Optional["MutualTlsValidation"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ListenerTlsOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IMesh)
class Mesh(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.Mesh",
):
    '''Define a new AppMesh mesh.

    :see: https://docs.aws.amazon.com/app-mesh/latest/userguide/meshes.html
    :exampleMetadata: infused

    Example::

        # This is the ARN for the mesh from different AWS IAM account ID.
        # Ensure mesh is properly shared with your account. For more details, see: https://github.com/aws/aws-cdk/issues/15404
        arn = "arn:aws:appmesh:us-east-1:123456789012:mesh/testMesh"
        shared_mesh = appmesh.Mesh.from_mesh_arn(self, "imported-mesh", arn)
        
        # This VirtualNode resource can communicate with the resources in the mesh from different AWS IAM account ID.
        appmesh.VirtualNode(self, "test-node",
            mesh=shared_mesh
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        egress_filter: typing.Optional["MeshFilterType"] = None,
        mesh_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param egress_filter: Egress filter to be applied to the Mesh. Default: DROP_ALL
        :param mesh_name: The name of the Mesh being defined. Default: - A name is automatically generated
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Mesh.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = MeshProps(egress_filter=egress_filter, mesh_name=mesh_name)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromMeshArn")
    @builtins.classmethod
    def from_mesh_arn(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        mesh_arn: builtins.str,
    ) -> IMesh:
        '''Import an existing mesh by arn.

        :param scope: -
        :param id: -
        :param mesh_arn: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Mesh.from_mesh_arn)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument mesh_arn", value=mesh_arn, expected_type=type_hints["mesh_arn"])
        return typing.cast(IMesh, jsii.sinvoke(cls, "fromMeshArn", [scope, id, mesh_arn]))

    @jsii.member(jsii_name="fromMeshName")
    @builtins.classmethod
    def from_mesh_name(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        mesh_name: builtins.str,
    ) -> IMesh:
        '''Import an existing mesh by name.

        :param scope: -
        :param id: -
        :param mesh_name: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Mesh.from_mesh_name)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
        return typing.cast(IMesh, jsii.sinvoke(cls, "fromMeshName", [scope, id, mesh_name]))

    @jsii.member(jsii_name="addVirtualGateway")
    def add_virtual_gateway(
        self,
        id: builtins.str,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualGatewayListener"]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualGateway":
        '''Adds a VirtualGateway to the Mesh.

        :param id: -
        :param access_log: Access Logging Configuration for the VirtualGateway. Default: - no access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param listeners: Listeners for the VirtualGateway. Only one is supported. Default: - Single HTTP listener on port 8080
        :param virtual_gateway_name: Name of the VirtualGateway. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Mesh.add_virtual_gateway)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualGatewayBaseProps(
            access_log=access_log,
            backend_defaults=backend_defaults,
            listeners=listeners,
            virtual_gateway_name=virtual_gateway_name,
        )

        return typing.cast("VirtualGateway", jsii.invoke(self, "addVirtualGateway", [id, props]))

    @jsii.member(jsii_name="addVirtualNode")
    def add_virtual_node(
        self,
        id: builtins.str,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        backends: typing.Optional[typing.Sequence[Backend]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualNodeListener"]] = None,
        service_discovery: typing.Optional["ServiceDiscovery"] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualNode":
        '''Adds a VirtualNode to the Mesh.

        :param id: -
        :param access_log: Access Logging Configuration for the virtual node. Default: - No access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param backends: Virtual Services that this is node expected to send outbound traffic to. Default: - No backends
        :param listeners: Initial listener for the virtual node. Default: - No listeners
        :param service_discovery: Defines how upstream clients will discover this VirtualNode. Default: - No Service Discovery
        :param virtual_node_name: The name of the VirtualNode. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Mesh.add_virtual_node)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualNodeBaseProps(
            access_log=access_log,
            backend_defaults=backend_defaults,
            backends=backends,
            listeners=listeners,
            service_discovery=service_discovery,
            virtual_node_name=virtual_node_name,
        )

        return typing.cast("VirtualNode", jsii.invoke(self, "addVirtualNode", [id, props]))

    @jsii.member(jsii_name="addVirtualRouter")
    def add_virtual_router(
        self,
        id: builtins.str,
        *,
        listeners: typing.Optional[typing.Sequence["VirtualRouterListener"]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
    ) -> "VirtualRouter":
        '''Adds a VirtualRouter to the Mesh with the given id and props.

        :param id: -
        :param listeners: Listener specification for the VirtualRouter. Default: - A listener on HTTP port 8080
        :param virtual_router_name: The name of the VirtualRouter. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Mesh.add_virtual_router)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualRouterBaseProps(
            listeners=listeners, virtual_router_name=virtual_router_name
        )

        return typing.cast("VirtualRouter", jsii.invoke(self, "addVirtualRouter", [id, props]))

    @builtins.property
    @jsii.member(jsii_name="meshArn")
    def mesh_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) of the AppMesh mesh.'''
        return typing.cast(builtins.str, jsii.get(self, "meshArn"))

    @builtins.property
    @jsii.member(jsii_name="meshName")
    def mesh_name(self) -> builtins.str:
        '''The name of the AppMesh mesh.'''
        return typing.cast(builtins.str, jsii.get(self, "meshName"))


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.MeshFilterType")
class MeshFilterType(enum.Enum):
    '''A utility enum defined for the egressFilter type property, the default of DROP_ALL, allows traffic only to other resources inside the mesh, or API calls to amazon resources.

    :default: DROP_ALL

    :exampleMetadata: infused

    Example::

        mesh = appmesh.Mesh(self, "AppMesh",
            mesh_name="myAwsMesh",
            egress_filter=appmesh.MeshFilterType.ALLOW_ALL
        )
    '''

    ALLOW_ALL = "ALLOW_ALL"
    '''Allows all outbound traffic.'''
    DROP_ALL = "DROP_ALL"
    '''Allows traffic only to other resources inside the mesh, or API calls to amazon resources.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.MeshProps",
    jsii_struct_bases=[],
    name_mapping={"egress_filter": "egressFilter", "mesh_name": "meshName"},
)
class MeshProps:
    def __init__(
        self,
        *,
        egress_filter: typing.Optional[MeshFilterType] = None,
        mesh_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''The set of properties used when creating a Mesh.

        :param egress_filter: Egress filter to be applied to the Mesh. Default: DROP_ALL
        :param mesh_name: The name of the Mesh being defined. Default: - A name is automatically generated

        :exampleMetadata: infused

        Example::

            mesh = appmesh.Mesh(self, "AppMesh",
                mesh_name="myAwsMesh",
                egress_filter=appmesh.MeshFilterType.ALLOW_ALL
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(MeshProps.__init__)
            check_type(argname="argument egress_filter", value=egress_filter, expected_type=type_hints["egress_filter"])
            check_type(argname="argument mesh_name", value=mesh_name, expected_type=type_hints["mesh_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if egress_filter is not None:
            self._values["egress_filter"] = egress_filter
        if mesh_name is not None:
            self._values["mesh_name"] = mesh_name

    @builtins.property
    def egress_filter(self) -> typing.Optional[MeshFilterType]:
        '''Egress filter to be applied to the Mesh.

        :default: DROP_ALL
        '''
        result = self._values.get("egress_filter")
        return typing.cast(typing.Optional[MeshFilterType], result)

    @builtins.property
    def mesh_name(self) -> typing.Optional[builtins.str]:
        '''The name of the Mesh being defined.

        :default: - A name is automatically generated
        '''
        result = self._values.get("mesh_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MeshProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.MutualTlsValidation",
    jsii_struct_bases=[],
    name_mapping={
        "trust": "trust",
        "subject_alternative_names": "subjectAlternativeNames",
    },
)
class MutualTlsValidation:
    def __init__(
        self,
        *,
        trust: "MutualTlsValidationTrust",
        subject_alternative_names: typing.Optional["SubjectAlternativeNames"] = None,
    ) -> None:
        '''Represents the properties needed to define TLS Validation context that is supported for mutual TLS authentication.

        :param trust: Reference to where to retrieve the trust chain.
        :param subject_alternative_names: Represents the subject alternative names (SANs) secured by the certificate. SANs must be in the FQDN or URI format. Default: - If you don't specify SANs on the terminating mesh endpoint, the Envoy proxy for that node doesn't verify the SAN on a peer client certificate. If you don't specify SANs on the originating mesh endpoint, the SAN on the certificate provided by the terminating endpoint must match the mesh endpoint service discovery configuration.

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            
            
            node1 = appmesh.VirtualNode(self, "node1",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.dns("node"),
                listeners=[appmesh.VirtualNodeListener.grpc(
                    port=80,
                    tls=appmesh.ListenerTlsOptions(
                        mode=appmesh.TlsMode.STRICT,
                        certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey"),
                        # Validate a file client certificates to enable mutual TLS authentication when a client provides a certificate.
                        mutual_tls_validation=appmesh.MutualTlsValidation(
                            trust=appmesh.TlsValidationTrust.file("path-to-certificate")
                        )
                    )
                )]
            )
            
            certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
            node2 = appmesh.VirtualNode(self, "node2",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.dns("node2"),
                backend_defaults=appmesh.BackendDefaults(
                    tls_client_policy=appmesh.TlsClientPolicy(
                        ports=[8080, 8081],
                        validation=appmesh.TlsValidation(
                            subject_alternative_names=appmesh.SubjectAlternativeNames.matching_exactly("mesh-endpoint.apps.local"),
                            trust=appmesh.TlsValidationTrust.acm([
                                acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                            ])
                        ),
                        # Provide a SDS client certificate when a server requests it and enable mutual TLS authentication.
                        mutual_tls_certificate=appmesh.TlsCertificate.sds("secret_certificate")
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(MutualTlsValidation.__init__)
            check_type(argname="argument trust", value=trust, expected_type=type_hints["trust"])
            check_type(argname="argument subject_alternative_names", value=subject_alternative_names, expected_type=type_hints["subject_alternative_names"])
        self._values: typing.Dict[str, typing.Any] = {
            "trust": trust,
        }
        if subject_alternative_names is not None:
            self._values["subject_alternative_names"] = subject_alternative_names

    @builtins.property
    def trust(self) -> "MutualTlsValidationTrust":
        '''Reference to where to retrieve the trust chain.'''
        result = self._values.get("trust")
        assert result is not None, "Required property 'trust' is missing"
        return typing.cast("MutualTlsValidationTrust", result)

    @builtins.property
    def subject_alternative_names(self) -> typing.Optional["SubjectAlternativeNames"]:
        '''Represents the subject alternative names (SANs) secured by the certificate.

        SANs must be in the FQDN or URI format.

        :default:

        - If you don't specify SANs on the terminating mesh endpoint,
        the Envoy proxy for that node doesn't verify the SAN on a peer client certificate.
        If you don't specify SANs on the originating mesh endpoint,
        the SAN on the certificate provided by the terminating endpoint must match the mesh endpoint service discovery configuration.
        '''
        result = self._values.get("subject_alternative_names")
        return typing.cast(typing.Optional["SubjectAlternativeNames"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MutualTlsValidation(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.OutlierDetection",
    jsii_struct_bases=[],
    name_mapping={
        "base_ejection_duration": "baseEjectionDuration",
        "interval": "interval",
        "max_ejection_percent": "maxEjectionPercent",
        "max_server_errors": "maxServerErrors",
    },
)
class OutlierDetection:
    def __init__(
        self,
        *,
        base_ejection_duration: aws_cdk.core.Duration,
        interval: aws_cdk.core.Duration,
        max_ejection_percent: jsii.Number,
        max_server_errors: jsii.Number,
    ) -> None:
        '''Represents the outlier detection for a listener.

        :param base_ejection_duration: The base amount of time for which a host is ejected.
        :param interval: The time interval between ejection sweep analysis.
        :param max_ejection_percent: Maximum percentage of hosts in load balancing pool for upstream service that can be ejected. Will eject at least one host regardless of the value.
        :param max_server_errors: Number of consecutive 5xx errors required for ejection.

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            # Cloud Map service discovery is currently required for host ejection by outlier detection
            vpc = ec2.Vpc(self, "vpc")
            namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
                vpc=vpc,
                name="domain.local"
            )
            service = namespace.create_service("Svc")
            node = mesh.add_virtual_node("virtual-node",
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    outlier_detection=appmesh.OutlierDetection(
                        base_ejection_duration=cdk.Duration.seconds(10),
                        interval=cdk.Duration.seconds(30),
                        max_ejection_percent=50,
                        max_server_errors=5
                    )
                )]
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(OutlierDetection.__init__)
            check_type(argname="argument base_ejection_duration", value=base_ejection_duration, expected_type=type_hints["base_ejection_duration"])
            check_type(argname="argument interval", value=interval, expected_type=type_hints["interval"])
            check_type(argname="argument max_ejection_percent", value=max_ejection_percent, expected_type=type_hints["max_ejection_percent"])
            check_type(argname="argument max_server_errors", value=max_server_errors, expected_type=type_hints["max_server_errors"])
        self._values: typing.Dict[str, typing.Any] = {
            "base_ejection_duration": base_ejection_duration,
            "interval": interval,
            "max_ejection_percent": max_ejection_percent,
            "max_server_errors": max_server_errors,
        }

    @builtins.property
    def base_ejection_duration(self) -> aws_cdk.core.Duration:
        '''The base amount of time for which a host is ejected.'''
        result = self._values.get("base_ejection_duration")
        assert result is not None, "Required property 'base_ejection_duration' is missing"
        return typing.cast(aws_cdk.core.Duration, result)

    @builtins.property
    def interval(self) -> aws_cdk.core.Duration:
        '''The time interval between ejection sweep analysis.'''
        result = self._values.get("interval")
        assert result is not None, "Required property 'interval' is missing"
        return typing.cast(aws_cdk.core.Duration, result)

    @builtins.property
    def max_ejection_percent(self) -> jsii.Number:
        '''Maximum percentage of hosts in load balancing pool for upstream service that can be ejected.

        Will eject at
        least one host regardless of the value.
        '''
        result = self._values.get("max_ejection_percent")
        assert result is not None, "Required property 'max_ejection_percent' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def max_server_errors(self) -> jsii.Number:
        '''Number of consecutive 5xx errors required for ejection.'''
        result = self._values.get("max_server_errors")
        assert result is not None, "Required property 'max_server_errors' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OutlierDetection(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.Protocol")
class Protocol(enum.Enum):
    '''(deprecated) Enum of supported AppMesh protocols.

    :deprecated: not for use outside package

    :stability: deprecated
    '''

    HTTP = "HTTP"
    '''
    :stability: deprecated
    '''
    TCP = "TCP"
    '''
    :stability: deprecated
    '''
    HTTP2 = "HTTP2"
    '''
    :stability: deprecated
    '''
    GRPC = "GRPC"
    '''
    :stability: deprecated
    '''


class QueryParameterMatch(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.QueryParameterMatch",
):
    '''Used to generate query parameter matching methods.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http2",
            route_spec=appmesh.RouteSpec.http2(
                weighted_targets=[appmesh.WeightedTarget(
                    virtual_node=node
                )
                ],
                match=appmesh.HttpRouteMatch(
                    path=appmesh.HttpRoutePathMatch.exactly("/exact"),
                    method=appmesh.HttpRouteMethod.POST,
                    protocol=appmesh.HttpRouteProtocol.HTTPS,
                    headers=[
                        # All specified headers must match for the route to match.
                        appmesh.HeaderMatch.value_is("Content-Type", "application/json"),
                        appmesh.HeaderMatch.value_is_not("Content-Type", "application/json")
                    ],
                    query_parameters=[
                        # All specified query parameters must match for the route to match.
                        appmesh.QueryParameterMatch.value_is("query-field", "value")
                    ]
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="valueIs")
    @builtins.classmethod
    def value_is(
        cls,
        query_parameter_name: builtins.str,
        query_parameter_value: builtins.str,
    ) -> "QueryParameterMatch":
        '''The value of the query parameter with the given name in the request must match the specified value exactly.

        :param query_parameter_name: the name of the query parameter to match against.
        :param query_parameter_value: The exact value to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(QueryParameterMatch.value_is)
            check_type(argname="argument query_parameter_name", value=query_parameter_name, expected_type=type_hints["query_parameter_name"])
            check_type(argname="argument query_parameter_value", value=query_parameter_value, expected_type=type_hints["query_parameter_value"])
        return typing.cast("QueryParameterMatch", jsii.sinvoke(cls, "valueIs", [query_parameter_name, query_parameter_value]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "QueryParameterMatchConfig":
        '''Returns the query parameter match configuration.

        :param scope: -
        '''
        ...


class _QueryParameterMatchProxy(QueryParameterMatch):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "QueryParameterMatchConfig":
        '''Returns the query parameter match configuration.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(QueryParameterMatch.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("QueryParameterMatchConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, QueryParameterMatch).__jsii_proxy_class__ = lambda : _QueryParameterMatchProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.QueryParameterMatchConfig",
    jsii_struct_bases=[],
    name_mapping={"query_parameter_match": "queryParameterMatch"},
)
class QueryParameterMatchConfig:
    def __init__(
        self,
        *,
        query_parameter_match: typing.Union[CfnRoute.QueryParameterProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''Configuration for ``QueryParameterMatch``.

        :param query_parameter_match: Route CFN configuration for route query parameter match.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            query_parameter_match_config = appmesh.QueryParameterMatchConfig(
                query_parameter_match=appmesh.CfnRoute.QueryParameterProperty(
                    name="name",
            
                    # the properties below are optional
                    match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                        exact="exact"
                    )
                )
            )
        '''
        if isinstance(query_parameter_match, dict):
            query_parameter_match = CfnRoute.QueryParameterProperty(**query_parameter_match)
        if __debug__:
            type_hints = typing.get_type_hints(QueryParameterMatchConfig.__init__)
            check_type(argname="argument query_parameter_match", value=query_parameter_match, expected_type=type_hints["query_parameter_match"])
        self._values: typing.Dict[str, typing.Any] = {
            "query_parameter_match": query_parameter_match,
        }

    @builtins.property
    def query_parameter_match(self) -> CfnRoute.QueryParameterProperty:
        '''Route CFN configuration for route query parameter match.'''
        result = self._values.get("query_parameter_match")
        assert result is not None, "Required property 'query_parameter_match' is missing"
        return typing.cast(CfnRoute.QueryParameterProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "QueryParameterMatchConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IRoute)
class Route(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.Route",
):
    '''Route represents a new or existing route attached to a VirtualRouter and Mesh.

    :see: https://docs.aws.amazon.com/app-mesh/latest/userguide/routes.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        # mesh: appmesh.Mesh
        # route_spec: appmesh.RouteSpec
        # virtual_router: appmesh.VirtualRouter
        
        route = appmesh.Route(self, "MyRoute",
            mesh=mesh,
            route_spec=route_spec,
            virtual_router=virtual_router,
        
            # the properties below are optional
            route_name="routeName"
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        virtual_router: IVirtualRouter,
        route_spec: "RouteSpec",
        route_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param mesh: The service mesh to define the route in.
        :param virtual_router: The VirtualRouter the Route belongs to.
        :param route_spec: Protocol specific spec.
        :param route_name: The name of the route. Default: - An automatically generated name
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Route.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = RouteProps(
            mesh=mesh,
            virtual_router=virtual_router,
            route_spec=route_spec,
            route_name=route_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromRouteArn")
    @builtins.classmethod
    def from_route_arn(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        route_arn: builtins.str,
    ) -> IRoute:
        '''Import an existing Route given an ARN.

        :param scope: -
        :param id: -
        :param route_arn: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Route.from_route_arn)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument route_arn", value=route_arn, expected_type=type_hints["route_arn"])
        return typing.cast(IRoute, jsii.sinvoke(cls, "fromRouteArn", [scope, id, route_arn]))

    @jsii.member(jsii_name="fromRouteAttributes")
    @builtins.classmethod
    def from_route_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        route_name: builtins.str,
        virtual_router: IVirtualRouter,
    ) -> IRoute:
        '''Import an existing Route given attributes.

        :param scope: -
        :param id: -
        :param route_name: The name of the Route.
        :param virtual_router: The VirtualRouter the Route belongs to.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(Route.from_route_attributes)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        attrs = RouteAttributes(route_name=route_name, virtual_router=virtual_router)

        return typing.cast(IRoute, jsii.sinvoke(cls, "fromRouteAttributes", [scope, id, attrs]))

    @builtins.property
    @jsii.member(jsii_name="routeArn")
    def route_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the route.'''
        return typing.cast(builtins.str, jsii.get(self, "routeArn"))

    @builtins.property
    @jsii.member(jsii_name="routeName")
    def route_name(self) -> builtins.str:
        '''The name of the Route.'''
        return typing.cast(builtins.str, jsii.get(self, "routeName"))

    @builtins.property
    @jsii.member(jsii_name="virtualRouter")
    def virtual_router(self) -> IVirtualRouter:
        '''The VirtualRouter the Route belongs to.'''
        return typing.cast(IVirtualRouter, jsii.get(self, "virtualRouter"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.RouteAttributes",
    jsii_struct_bases=[],
    name_mapping={"route_name": "routeName", "virtual_router": "virtualRouter"},
)
class RouteAttributes:
    def __init__(
        self,
        *,
        route_name: builtins.str,
        virtual_router: IVirtualRouter,
    ) -> None:
        '''Interface with properties ncecessary to import a reusable Route.

        :param route_name: The name of the Route.
        :param virtual_router: The VirtualRouter the Route belongs to.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # virtual_router: appmesh.VirtualRouter
            
            route_attributes = appmesh.RouteAttributes(
                route_name="routeName",
                virtual_router=virtual_router
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(RouteAttributes.__init__)
            check_type(argname="argument route_name", value=route_name, expected_type=type_hints["route_name"])
            check_type(argname="argument virtual_router", value=virtual_router, expected_type=type_hints["virtual_router"])
        self._values: typing.Dict[str, typing.Any] = {
            "route_name": route_name,
            "virtual_router": virtual_router,
        }

    @builtins.property
    def route_name(self) -> builtins.str:
        '''The name of the Route.'''
        result = self._values.get("route_name")
        assert result is not None, "Required property 'route_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def virtual_router(self) -> IVirtualRouter:
        '''The VirtualRouter the Route belongs to.'''
        result = self._values.get("virtual_router")
        assert result is not None, "Required property 'virtual_router' is missing"
        return typing.cast(IVirtualRouter, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RouteAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.RouteBaseProps",
    jsii_struct_bases=[],
    name_mapping={"route_spec": "routeSpec", "route_name": "routeName"},
)
class RouteBaseProps:
    def __init__(
        self,
        *,
        route_spec: "RouteSpec",
        route_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Base interface properties for all Routes.

        :param route_spec: Protocol specific spec.
        :param route_name: The name of the route. Default: - An automatically generated name

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-http2-retry",
                route_spec=appmesh.RouteSpec.http2(
                    weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                    retry_policy=appmesh.HttpRetryPolicy(
                        # Retry if the connection failed
                        tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                        # Retry if HTTP responds with a gateway error (502, 503, 504)
                        http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                        # Retry five times
                        retry_attempts=5,
                        # Use a 1 second timeout per retry
                        retry_timeout=cdk.Duration.seconds(1)
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(RouteBaseProps.__init__)
            check_type(argname="argument route_spec", value=route_spec, expected_type=type_hints["route_spec"])
            check_type(argname="argument route_name", value=route_name, expected_type=type_hints["route_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "route_spec": route_spec,
        }
        if route_name is not None:
            self._values["route_name"] = route_name

    @builtins.property
    def route_spec(self) -> "RouteSpec":
        '''Protocol specific spec.'''
        result = self._values.get("route_spec")
        assert result is not None, "Required property 'route_spec' is missing"
        return typing.cast("RouteSpec", result)

    @builtins.property
    def route_name(self) -> typing.Optional[builtins.str]:
        '''The name of the route.

        :default: - An automatically generated name
        '''
        result = self._values.get("route_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RouteBaseProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.RouteProps",
    jsii_struct_bases=[RouteBaseProps],
    name_mapping={
        "route_spec": "routeSpec",
        "route_name": "routeName",
        "mesh": "mesh",
        "virtual_router": "virtualRouter",
    },
)
class RouteProps(RouteBaseProps):
    def __init__(
        self,
        *,
        route_spec: "RouteSpec",
        route_name: typing.Optional[builtins.str] = None,
        mesh: IMesh,
        virtual_router: IVirtualRouter,
    ) -> None:
        '''Properties to define new Routes.

        :param route_spec: Protocol specific spec.
        :param route_name: The name of the route. Default: - An automatically generated name
        :param mesh: The service mesh to define the route in.
        :param virtual_router: The VirtualRouter the Route belongs to.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # mesh: appmesh.Mesh
            # route_spec: appmesh.RouteSpec
            # virtual_router: appmesh.VirtualRouter
            
            route_props = appmesh.RouteProps(
                mesh=mesh,
                route_spec=route_spec,
                virtual_router=virtual_router,
            
                # the properties below are optional
                route_name="routeName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(RouteProps.__init__)
            check_type(argname="argument route_spec", value=route_spec, expected_type=type_hints["route_spec"])
            check_type(argname="argument route_name", value=route_name, expected_type=type_hints["route_name"])
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
            check_type(argname="argument virtual_router", value=virtual_router, expected_type=type_hints["virtual_router"])
        self._values: typing.Dict[str, typing.Any] = {
            "route_spec": route_spec,
            "mesh": mesh,
            "virtual_router": virtual_router,
        }
        if route_name is not None:
            self._values["route_name"] = route_name

    @builtins.property
    def route_spec(self) -> "RouteSpec":
        '''Protocol specific spec.'''
        result = self._values.get("route_spec")
        assert result is not None, "Required property 'route_spec' is missing"
        return typing.cast("RouteSpec", result)

    @builtins.property
    def route_name(self) -> typing.Optional[builtins.str]:
        '''The name of the route.

        :default: - An automatically generated name
        '''
        result = self._values.get("route_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def mesh(self) -> IMesh:
        '''The service mesh to define the route in.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    @builtins.property
    def virtual_router(self) -> IVirtualRouter:
        '''The VirtualRouter the Route belongs to.'''
        result = self._values.get("virtual_router")
        assert result is not None, "Required property 'virtual_router' is missing"
        return typing.cast(IVirtualRouter, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class RouteSpec(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.RouteSpec",
):
    '''Used to generate specs with different protocols for a RouteSpec.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http2-retry",
            route_spec=appmesh.RouteSpec.http2(
                weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                retry_policy=appmesh.HttpRetryPolicy(
                    # Retry if the connection failed
                    tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                    # Retry if HTTP responds with a gateway error (502, 503, 504)
                    http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                    # Retry five times
                    retry_attempts=5,
                    # Use a 1 second timeout per retry
                    retry_timeout=cdk.Duration.seconds(1)
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="grpc")
    @builtins.classmethod
    def grpc(
        cls,
        *,
        match: typing.Union[GrpcRouteMatch, typing.Dict[str, typing.Any]],
        weighted_targets: typing.Sequence[typing.Union["WeightedTarget", typing.Dict[str, typing.Any]]],
        retry_policy: typing.Optional[typing.Union["GrpcRetryPolicy", typing.Dict[str, typing.Any]]] = None,
        timeout: typing.Optional[typing.Union[GrpcTimeout, typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> "RouteSpec":
        '''Creates a GRPC Based RouteSpec.

        :param match: The criterion for determining a request match for this Route.
        :param weighted_targets: List of targets that traffic is routed to when a request matches the route.
        :param retry_policy: The retry policy. Default: - no retry policy
        :param timeout: An object that represents a grpc timeout. Default: - None
        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        '''
        options = GrpcRouteSpecOptions(
            match=match,
            weighted_targets=weighted_targets,
            retry_policy=retry_policy,
            timeout=timeout,
            priority=priority,
        )

        return typing.cast("RouteSpec", jsii.sinvoke(cls, "grpc", [options]))

    @jsii.member(jsii_name="http")
    @builtins.classmethod
    def http(
        cls,
        *,
        weighted_targets: typing.Sequence[typing.Union["WeightedTarget", typing.Dict[str, typing.Any]]],
        match: typing.Optional[typing.Union[HttpRouteMatch, typing.Dict[str, typing.Any]]] = None,
        retry_policy: typing.Optional[typing.Union[HttpRetryPolicy, typing.Dict[str, typing.Any]]] = None,
        timeout: typing.Optional[typing.Union[HttpTimeout, typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> "RouteSpec":
        '''Creates an HTTP Based RouteSpec.

        :param weighted_targets: List of targets that traffic is routed to when a request matches the route.
        :param match: The criterion for determining a request match for this Route. Default: - matches on '/'
        :param retry_policy: The retry policy. Default: - no retry policy
        :param timeout: An object that represents a http timeout. Default: - None
        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        '''
        options = HttpRouteSpecOptions(
            weighted_targets=weighted_targets,
            match=match,
            retry_policy=retry_policy,
            timeout=timeout,
            priority=priority,
        )

        return typing.cast("RouteSpec", jsii.sinvoke(cls, "http", [options]))

    @jsii.member(jsii_name="http2")
    @builtins.classmethod
    def http2(
        cls,
        *,
        weighted_targets: typing.Sequence[typing.Union["WeightedTarget", typing.Dict[str, typing.Any]]],
        match: typing.Optional[typing.Union[HttpRouteMatch, typing.Dict[str, typing.Any]]] = None,
        retry_policy: typing.Optional[typing.Union[HttpRetryPolicy, typing.Dict[str, typing.Any]]] = None,
        timeout: typing.Optional[typing.Union[HttpTimeout, typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> "RouteSpec":
        '''Creates an HTTP2 Based RouteSpec.

        :param weighted_targets: List of targets that traffic is routed to when a request matches the route.
        :param match: The criterion for determining a request match for this Route. Default: - matches on '/'
        :param retry_policy: The retry policy. Default: - no retry policy
        :param timeout: An object that represents a http timeout. Default: - None
        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        '''
        options = HttpRouteSpecOptions(
            weighted_targets=weighted_targets,
            match=match,
            retry_policy=retry_policy,
            timeout=timeout,
            priority=priority,
        )

        return typing.cast("RouteSpec", jsii.sinvoke(cls, "http2", [options]))

    @jsii.member(jsii_name="tcp")
    @builtins.classmethod
    def tcp(
        cls,
        *,
        weighted_targets: typing.Sequence[typing.Union["WeightedTarget", typing.Dict[str, typing.Any]]],
        timeout: typing.Optional[typing.Union["TcpTimeout", typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
    ) -> "RouteSpec":
        '''Creates a TCP Based RouteSpec.

        :param weighted_targets: List of targets that traffic is routed to when a request matches the route.
        :param timeout: An object that represents a tcp timeout. Default: - None
        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        '''
        options = TcpRouteSpecOptions(
            weighted_targets=weighted_targets, timeout=timeout, priority=priority
        )

        return typing.cast("RouteSpec", jsii.sinvoke(cls, "tcp", [options]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "RouteSpecConfig":
        '''Called when the RouteSpec type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        '''
        ...


class _RouteSpecProxy(RouteSpec):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "RouteSpecConfig":
        '''Called when the RouteSpec type is initialized.

        Can be used to enforce
        mutual exclusivity with future properties

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(RouteSpec.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("RouteSpecConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, RouteSpec).__jsii_proxy_class__ = lambda : _RouteSpecProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.RouteSpecConfig",
    jsii_struct_bases=[],
    name_mapping={
        "grpc_route_spec": "grpcRouteSpec",
        "http2_route_spec": "http2RouteSpec",
        "http_route_spec": "httpRouteSpec",
        "priority": "priority",
        "tcp_route_spec": "tcpRouteSpec",
    },
)
class RouteSpecConfig:
    def __init__(
        self,
        *,
        grpc_route_spec: typing.Optional[typing.Union[CfnRoute.GrpcRouteProperty, typing.Dict[str, typing.Any]]] = None,
        http2_route_spec: typing.Optional[typing.Union[CfnRoute.HttpRouteProperty, typing.Dict[str, typing.Any]]] = None,
        http_route_spec: typing.Optional[typing.Union[CfnRoute.HttpRouteProperty, typing.Dict[str, typing.Any]]] = None,
        priority: typing.Optional[jsii.Number] = None,
        tcp_route_spec: typing.Optional[typing.Union[CfnRoute.TcpRouteProperty, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''All Properties for Route Specs.

        :param grpc_route_spec: The spec for a grpc route. Default: - no grpc spec
        :param http2_route_spec: The spec for an http2 route. Default: - no http2 spec
        :param http_route_spec: The spec for an http route. Default: - no http spec
        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        :param tcp_route_spec: The spec for a tcp route. Default: - no tcp spec

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            route_spec_config = appmesh.RouteSpecConfig(
                grpc_route_spec=appmesh.CfnRoute.GrpcRouteProperty(
                    action=appmesh.CfnRoute.GrpcRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
            
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.GrpcRouteMatchProperty(
                        metadata=[appmesh.CfnRoute.GrpcRouteMetadataProperty(
                            name="name",
            
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.GrpcRouteMetadataMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method_name="methodName",
                        port=123,
                        service_name="serviceName"
                    ),
            
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.GrpcRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
            
                        # the properties below are optional
                        grpc_retry_events=["grpcRetryEvents"],
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.GrpcTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                ),
                http2_route_spec=appmesh.CfnRoute.HttpRouteProperty(
                    action=appmesh.CfnRoute.HttpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
            
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.HttpRouteMatchProperty(
                        headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                            name="name",
            
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method="method",
                        path=appmesh.CfnRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                            name="name",
            
                            # the properties below are optional
                            match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )],
                        scheme="scheme"
                    ),
            
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
            
                        # the properties below are optional
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                ),
                http_route_spec=appmesh.CfnRoute.HttpRouteProperty(
                    action=appmesh.CfnRoute.HttpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
            
                            # the properties below are optional
                            port=123
                        )]
                    ),
                    match=appmesh.CfnRoute.HttpRouteMatchProperty(
                        headers=[appmesh.CfnRoute.HttpRouteHeaderProperty(
                            name="name",
            
                            # the properties below are optional
                            invert=False,
                            match=appmesh.CfnRoute.HeaderMatchMethodProperty(
                                exact="exact",
                                prefix="prefix",
                                range=appmesh.CfnRoute.MatchRangeProperty(
                                    end=123,
                                    start=123
                                ),
                                regex="regex",
                                suffix="suffix"
                            )
                        )],
                        method="method",
                        path=appmesh.CfnRoute.HttpPathMatchProperty(
                            exact="exact",
                            regex="regex"
                        ),
                        port=123,
                        prefix="prefix",
                        query_parameters=[appmesh.CfnRoute.QueryParameterProperty(
                            name="name",
            
                            # the properties below are optional
                            match=appmesh.CfnRoute.HttpQueryParameterMatchProperty(
                                exact="exact"
                            )
                        )],
                        scheme="scheme"
                    ),
            
                    # the properties below are optional
                    retry_policy=appmesh.CfnRoute.HttpRetryPolicyProperty(
                        max_retries=123,
                        per_retry_timeout=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
            
                        # the properties below are optional
                        http_retry_events=["httpRetryEvents"],
                        tcp_retry_events=["tcpRetryEvents"]
                    ),
                    timeout=appmesh.CfnRoute.HttpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        per_request=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                ),
                priority=123,
                tcp_route_spec=appmesh.CfnRoute.TcpRouteProperty(
                    action=appmesh.CfnRoute.TcpRouteActionProperty(
                        weighted_targets=[appmesh.CfnRoute.WeightedTargetProperty(
                            virtual_node="virtualNode",
                            weight=123,
            
                            # the properties below are optional
                            port=123
                        )]
                    ),
            
                    # the properties below are optional
                    match=appmesh.CfnRoute.TcpRouteMatchProperty(
                        port=123
                    ),
                    timeout=appmesh.CfnRoute.TcpTimeoutProperty(
                        idle=appmesh.CfnRoute.DurationProperty(
                            unit="unit",
                            value=123
                        )
                    )
                )
            )
        '''
        if isinstance(grpc_route_spec, dict):
            grpc_route_spec = CfnRoute.GrpcRouteProperty(**grpc_route_spec)
        if isinstance(http2_route_spec, dict):
            http2_route_spec = CfnRoute.HttpRouteProperty(**http2_route_spec)
        if isinstance(http_route_spec, dict):
            http_route_spec = CfnRoute.HttpRouteProperty(**http_route_spec)
        if isinstance(tcp_route_spec, dict):
            tcp_route_spec = CfnRoute.TcpRouteProperty(**tcp_route_spec)
        if __debug__:
            type_hints = typing.get_type_hints(RouteSpecConfig.__init__)
            check_type(argname="argument grpc_route_spec", value=grpc_route_spec, expected_type=type_hints["grpc_route_spec"])
            check_type(argname="argument http2_route_spec", value=http2_route_spec, expected_type=type_hints["http2_route_spec"])
            check_type(argname="argument http_route_spec", value=http_route_spec, expected_type=type_hints["http_route_spec"])
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            check_type(argname="argument tcp_route_spec", value=tcp_route_spec, expected_type=type_hints["tcp_route_spec"])
        self._values: typing.Dict[str, typing.Any] = {}
        if grpc_route_spec is not None:
            self._values["grpc_route_spec"] = grpc_route_spec
        if http2_route_spec is not None:
            self._values["http2_route_spec"] = http2_route_spec
        if http_route_spec is not None:
            self._values["http_route_spec"] = http_route_spec
        if priority is not None:
            self._values["priority"] = priority
        if tcp_route_spec is not None:
            self._values["tcp_route_spec"] = tcp_route_spec

    @builtins.property
    def grpc_route_spec(self) -> typing.Optional[CfnRoute.GrpcRouteProperty]:
        '''The spec for a grpc route.

        :default: - no grpc spec
        '''
        result = self._values.get("grpc_route_spec")
        return typing.cast(typing.Optional[CfnRoute.GrpcRouteProperty], result)

    @builtins.property
    def http2_route_spec(self) -> typing.Optional[CfnRoute.HttpRouteProperty]:
        '''The spec for an http2 route.

        :default: - no http2 spec
        '''
        result = self._values.get("http2_route_spec")
        return typing.cast(typing.Optional[CfnRoute.HttpRouteProperty], result)

    @builtins.property
    def http_route_spec(self) -> typing.Optional[CfnRoute.HttpRouteProperty]:
        '''The spec for an http route.

        :default: - no http spec
        '''
        result = self._values.get("http_route_spec")
        return typing.cast(typing.Optional[CfnRoute.HttpRouteProperty], result)

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the route.

        When a Virtual Router has multiple routes, route match is performed in the
        order of specified value, where 0 is the highest priority, and first matched route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tcp_route_spec(self) -> typing.Optional[CfnRoute.TcpRouteProperty]:
        '''The spec for a tcp route.

        :default: - no tcp spec
        '''
        result = self._values.get("tcp_route_spec")
        return typing.cast(typing.Optional[CfnRoute.TcpRouteProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RouteSpecConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.RouteSpecOptionsBase",
    jsii_struct_bases=[],
    name_mapping={"priority": "priority"},
)
class RouteSpecOptionsBase:
    def __init__(self, *, priority: typing.Optional[jsii.Number] = None) -> None:
        '''Base options for all route specs.

        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            route_spec_options_base = appmesh.RouteSpecOptionsBase(
                priority=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(RouteSpecOptionsBase.__init__)
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
        self._values: typing.Dict[str, typing.Any] = {}
        if priority is not None:
            self._values["priority"] = priority

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the route.

        When a Virtual Router has multiple routes, route match is performed in the
        order of specified value, where 0 is the highest priority, and first matched route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "RouteSpecOptionsBase(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class ServiceDiscovery(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.ServiceDiscovery",
):
    '''Provides the Service Discovery method a VirtualNode uses.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        vpc = ec2.Vpc(self, "vpc")
        namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
            vpc=vpc,
            name="domain.local"
        )
        service = namespace.create_service("Svc")
        node = mesh.add_virtual_node("virtual-node",
            service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
            listeners=[appmesh.VirtualNodeListener.http(
                port=8081,
                health_check=appmesh.HealthCheck.http(
                    healthy_threshold=3,
                    interval=cdk.Duration.seconds(5),  # minimum
                    path="/health-check-path",
                    timeout=cdk.Duration.seconds(2),  # minimum
                    unhealthy_threshold=2
                )
            )],
            access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="cloudMap")
    @builtins.classmethod
    def cloud_map(
        cls,
        service: aws_cdk.aws_servicediscovery.IService,
        instance_attributes: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
    ) -> "ServiceDiscovery":
        '''Returns Cloud Map based service discovery.

        :param service: The AWS Cloud Map Service to use for service discovery.
        :param instance_attributes: A string map that contains attributes with values that you can use to filter instances by any custom attribute that you specified when you registered the instance. Only instances that match all of the specified key/value pairs will be returned.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(ServiceDiscovery.cloud_map)
            check_type(argname="argument service", value=service, expected_type=type_hints["service"])
            check_type(argname="argument instance_attributes", value=instance_attributes, expected_type=type_hints["instance_attributes"])
        return typing.cast("ServiceDiscovery", jsii.sinvoke(cls, "cloudMap", [service, instance_attributes]))

    @jsii.member(jsii_name="dns")
    @builtins.classmethod
    def dns(
        cls,
        hostname: builtins.str,
        response_type: typing.Optional[DnsResponseType] = None,
    ) -> "ServiceDiscovery":
        '''Returns DNS based service discovery.

        :param hostname: -
        :param response_type: Specifies the DNS response type for the virtual node. The default is ``DnsResponseType.LOAD_BALANCER``.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(ServiceDiscovery.dns)
            check_type(argname="argument hostname", value=hostname, expected_type=type_hints["hostname"])
            check_type(argname="argument response_type", value=response_type, expected_type=type_hints["response_type"])
        return typing.cast("ServiceDiscovery", jsii.sinvoke(cls, "dns", [hostname, response_type]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "ServiceDiscoveryConfig":
        '''Binds the current object when adding Service Discovery to a VirtualNode.

        :param scope: -
        '''
        ...


class _ServiceDiscoveryProxy(ServiceDiscovery):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "ServiceDiscoveryConfig":
        '''Binds the current object when adding Service Discovery to a VirtualNode.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(ServiceDiscovery.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("ServiceDiscoveryConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, ServiceDiscovery).__jsii_proxy_class__ = lambda : _ServiceDiscoveryProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.ServiceDiscoveryConfig",
    jsii_struct_bases=[],
    name_mapping={"cloudmap": "cloudmap", "dns": "dns"},
)
class ServiceDiscoveryConfig:
    def __init__(
        self,
        *,
        cloudmap: typing.Optional[typing.Union[CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty, typing.Dict[str, typing.Any]]] = None,
        dns: typing.Optional[typing.Union[CfnVirtualNode.DnsServiceDiscoveryProperty, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Properties for VirtualNode Service Discovery.

        :param cloudmap: Cloud Map based Service Discovery. Default: - no Cloud Map based service discovery
        :param dns: DNS based Service Discovery. Default: - no DNS based service discovery

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            service_discovery_config = appmesh.ServiceDiscoveryConfig(
                cloudmap=appmesh.CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty(
                    namespace_name="namespaceName",
                    service_name="serviceName",
            
                    # the properties below are optional
                    attributes=[appmesh.CfnVirtualNode.AwsCloudMapInstanceAttributeProperty(
                        key="key",
                        value="value"
                    )],
                    ip_preference="ipPreference"
                ),
                dns=appmesh.CfnVirtualNode.DnsServiceDiscoveryProperty(
                    hostname="hostname",
            
                    # the properties below are optional
                    ip_preference="ipPreference",
                    response_type="responseType"
                )
            )
        '''
        if isinstance(cloudmap, dict):
            cloudmap = CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty(**cloudmap)
        if isinstance(dns, dict):
            dns = CfnVirtualNode.DnsServiceDiscoveryProperty(**dns)
        if __debug__:
            type_hints = typing.get_type_hints(ServiceDiscoveryConfig.__init__)
            check_type(argname="argument cloudmap", value=cloudmap, expected_type=type_hints["cloudmap"])
            check_type(argname="argument dns", value=dns, expected_type=type_hints["dns"])
        self._values: typing.Dict[str, typing.Any] = {}
        if cloudmap is not None:
            self._values["cloudmap"] = cloudmap
        if dns is not None:
            self._values["dns"] = dns

    @builtins.property
    def cloudmap(
        self,
    ) -> typing.Optional[CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty]:
        '''Cloud Map based Service Discovery.

        :default: - no Cloud Map based service discovery
        '''
        result = self._values.get("cloudmap")
        return typing.cast(typing.Optional[CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty], result)

    @builtins.property
    def dns(self) -> typing.Optional[CfnVirtualNode.DnsServiceDiscoveryProperty]:
        '''DNS based Service Discovery.

        :default: - no DNS based service discovery
        '''
        result = self._values.get("dns")
        return typing.cast(typing.Optional[CfnVirtualNode.DnsServiceDiscoveryProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceDiscoveryConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class SubjectAlternativeNames(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.SubjectAlternativeNames",
):
    '''Used to generate Subject Alternative Names Matchers.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        
        node1 = appmesh.VirtualNode(self, "node1",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node"),
            listeners=[appmesh.VirtualNodeListener.grpc(
                port=80,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey"),
                    # Validate a file client certificates to enable mutual TLS authentication when a client provides a certificate.
                    mutual_tls_validation=appmesh.MutualTlsValidation(
                        trust=appmesh.TlsValidationTrust.file("path-to-certificate")
                    )
                )
            )]
        )
        
        certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
        node2 = appmesh.VirtualNode(self, "node2",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node2"),
            backend_defaults=appmesh.BackendDefaults(
                tls_client_policy=appmesh.TlsClientPolicy(
                    ports=[8080, 8081],
                    validation=appmesh.TlsValidation(
                        subject_alternative_names=appmesh.SubjectAlternativeNames.matching_exactly("mesh-endpoint.apps.local"),
                        trust=appmesh.TlsValidationTrust.acm([
                            acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                        ])
                    ),
                    # Provide a SDS client certificate when a server requests it and enable mutual TLS authentication.
                    mutual_tls_certificate=appmesh.TlsCertificate.sds("secret_certificate")
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="matchingExactly")
    @builtins.classmethod
    def matching_exactly(cls, *names: builtins.str) -> "SubjectAlternativeNames":
        '''The values of the SAN must match the specified values exactly.

        :param names: The exact values to test against.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(SubjectAlternativeNames.matching_exactly)
            check_type(argname="argument names", value=names, expected_type=typing.Tuple[type_hints["names"], ...]) # pyright: ignore [reportGeneralTypeIssues]
        return typing.cast("SubjectAlternativeNames", jsii.sinvoke(cls, "matchingExactly", [*names]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(
        self,
        scope: aws_cdk.core.Construct,
    ) -> "SubjectAlternativeNamesMatcherConfig":
        '''Returns Subject Alternative Names Matcher based on method type.

        :param scope: -
        '''
        ...


class _SubjectAlternativeNamesProxy(SubjectAlternativeNames):
    @jsii.member(jsii_name="bind")
    def bind(
        self,
        scope: aws_cdk.core.Construct,
    ) -> "SubjectAlternativeNamesMatcherConfig":
        '''Returns Subject Alternative Names Matcher based on method type.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(SubjectAlternativeNames.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("SubjectAlternativeNamesMatcherConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, SubjectAlternativeNames).__jsii_proxy_class__ = lambda : _SubjectAlternativeNamesProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.SubjectAlternativeNamesMatcherConfig",
    jsii_struct_bases=[],
    name_mapping={"subject_alternative_names_match": "subjectAlternativeNamesMatch"},
)
class SubjectAlternativeNamesMatcherConfig:
    def __init__(
        self,
        *,
        subject_alternative_names_match: typing.Union[CfnVirtualNode.SubjectAlternativeNameMatchersProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''All Properties for Subject Alternative Names Matcher for both Client Policy and Listener.

        :param subject_alternative_names_match: VirtualNode CFN configuration for subject alternative names secured by the certificate.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            subject_alternative_names_matcher_config = appmesh.SubjectAlternativeNamesMatcherConfig(
                subject_alternative_names_match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                    exact=["exact"]
                )
            )
        '''
        if isinstance(subject_alternative_names_match, dict):
            subject_alternative_names_match = CfnVirtualNode.SubjectAlternativeNameMatchersProperty(**subject_alternative_names_match)
        if __debug__:
            type_hints = typing.get_type_hints(SubjectAlternativeNamesMatcherConfig.__init__)
            check_type(argname="argument subject_alternative_names_match", value=subject_alternative_names_match, expected_type=type_hints["subject_alternative_names_match"])
        self._values: typing.Dict[str, typing.Any] = {
            "subject_alternative_names_match": subject_alternative_names_match,
        }

    @builtins.property
    def subject_alternative_names_match(
        self,
    ) -> CfnVirtualNode.SubjectAlternativeNameMatchersProperty:
        '''VirtualNode CFN configuration for subject alternative names secured by the certificate.'''
        result = self._values.get("subject_alternative_names_match")
        assert result is not None, "Required property 'subject_alternative_names_match' is missing"
        return typing.cast(CfnVirtualNode.SubjectAlternativeNameMatchersProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubjectAlternativeNamesMatcherConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TcpConnectionPool",
    jsii_struct_bases=[],
    name_mapping={"max_connections": "maxConnections"},
)
class TcpConnectionPool:
    def __init__(self, *, max_connections: jsii.Number) -> None:
        '''Connection pool properties for TCP listeners.

        :param max_connections: The maximum connections in the pool. Default: - none

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            tcp_connection_pool = appmesh.TcpConnectionPool(
                max_connections=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TcpConnectionPool.__init__)
            check_type(argname="argument max_connections", value=max_connections, expected_type=type_hints["max_connections"])
        self._values: typing.Dict[str, typing.Any] = {
            "max_connections": max_connections,
        }

    @builtins.property
    def max_connections(self) -> jsii.Number:
        '''The maximum connections in the pool.

        :default: - none
        '''
        result = self._values.get("max_connections")
        assert result is not None, "Required property 'max_connections' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TcpConnectionPool(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TcpHealthCheckOptions",
    jsii_struct_bases=[],
    name_mapping={
        "healthy_threshold": "healthyThreshold",
        "interval": "interval",
        "timeout": "timeout",
        "unhealthy_threshold": "unhealthyThreshold",
    },
)
class TcpHealthCheckOptions:
    def __init__(
        self,
        *,
        healthy_threshold: typing.Optional[jsii.Number] = None,
        interval: typing.Optional[aws_cdk.core.Duration] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
        unhealthy_threshold: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties used to define TCP Based healthchecks.

        :param healthy_threshold: The number of consecutive successful health checks that must occur before declaring listener healthy. Default: 2
        :param interval: The time period between each health check execution. Default: Duration.seconds(5)
        :param timeout: The amount of time to wait when receiving a response from the health check. Default: Duration.seconds(2)
        :param unhealthy_threshold: The number of consecutive failed health checks that must occur before declaring a listener unhealthy. Default: - 2

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            import aws_cdk.core as cdk
            
            tcp_health_check_options = appmesh.TcpHealthCheckOptions(
                healthy_threshold=123,
                interval=cdk.Duration.minutes(30),
                timeout=cdk.Duration.minutes(30),
                unhealthy_threshold=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TcpHealthCheckOptions.__init__)
            check_type(argname="argument healthy_threshold", value=healthy_threshold, expected_type=type_hints["healthy_threshold"])
            check_type(argname="argument interval", value=interval, expected_type=type_hints["interval"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            check_type(argname="argument unhealthy_threshold", value=unhealthy_threshold, expected_type=type_hints["unhealthy_threshold"])
        self._values: typing.Dict[str, typing.Any] = {}
        if healthy_threshold is not None:
            self._values["healthy_threshold"] = healthy_threshold
        if interval is not None:
            self._values["interval"] = interval
        if timeout is not None:
            self._values["timeout"] = timeout
        if unhealthy_threshold is not None:
            self._values["unhealthy_threshold"] = unhealthy_threshold

    @builtins.property
    def healthy_threshold(self) -> typing.Optional[jsii.Number]:
        '''The number of consecutive successful health checks that must occur before declaring listener healthy.

        :default: 2
        '''
        result = self._values.get("healthy_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def interval(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The time period between each health check execution.

        :default: Duration.seconds(5)
        '''
        result = self._values.get("interval")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The amount of time to wait when receiving a response from the health check.

        :default: Duration.seconds(2)
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def unhealthy_threshold(self) -> typing.Optional[jsii.Number]:
        '''The number of consecutive failed health checks that must occur before declaring a listener unhealthy.

        :default: - 2
        '''
        result = self._values.get("unhealthy_threshold")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TcpHealthCheckOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.TcpRetryEvent")
class TcpRetryEvent(enum.Enum):
    '''TCP events on which you may retry.

    :exampleMetadata: infused

    Example::

        # router: appmesh.VirtualRouter
        # node: appmesh.VirtualNode
        
        
        router.add_route("route-http2-retry",
            route_spec=appmesh.RouteSpec.http2(
                weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                retry_policy=appmesh.HttpRetryPolicy(
                    # Retry if the connection failed
                    tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                    # Retry if HTTP responds with a gateway error (502, 503, 504)
                    http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                    # Retry five times
                    retry_attempts=5,
                    # Use a 1 second timeout per retry
                    retry_timeout=cdk.Duration.seconds(1)
                )
            )
        )
    '''

    CONNECTION_ERROR = "CONNECTION_ERROR"
    '''A connection error.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TcpRouteSpecOptions",
    jsii_struct_bases=[RouteSpecOptionsBase],
    name_mapping={
        "priority": "priority",
        "weighted_targets": "weightedTargets",
        "timeout": "timeout",
    },
)
class TcpRouteSpecOptions(RouteSpecOptionsBase):
    def __init__(
        self,
        *,
        priority: typing.Optional[jsii.Number] = None,
        weighted_targets: typing.Sequence[typing.Union["WeightedTarget", typing.Dict[str, typing.Any]]],
        timeout: typing.Optional[typing.Union["TcpTimeout", typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Properties specific for a TCP Based Routes.

        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        :param weighted_targets: List of targets that traffic is routed to when a request matches the route.
        :param timeout: An object that represents a tcp timeout. Default: - None

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            import aws_cdk.core as cdk
            
            # virtual_node: appmesh.VirtualNode
            
            tcp_route_spec_options = appmesh.TcpRouteSpecOptions(
                weighted_targets=[appmesh.WeightedTarget(
                    virtual_node=virtual_node,
            
                    # the properties below are optional
                    weight=123
                )],
            
                # the properties below are optional
                priority=123,
                timeout=appmesh.TcpTimeout(
                    idle=cdk.Duration.minutes(30)
                )
            )
        '''
        if isinstance(timeout, dict):
            timeout = TcpTimeout(**timeout)
        if __debug__:
            type_hints = typing.get_type_hints(TcpRouteSpecOptions.__init__)
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            check_type(argname="argument weighted_targets", value=weighted_targets, expected_type=type_hints["weighted_targets"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
        self._values: typing.Dict[str, typing.Any] = {
            "weighted_targets": weighted_targets,
        }
        if priority is not None:
            self._values["priority"] = priority
        if timeout is not None:
            self._values["timeout"] = timeout

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the route.

        When a Virtual Router has multiple routes, route match is performed in the
        order of specified value, where 0 is the highest priority, and first matched route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def weighted_targets(self) -> typing.List["WeightedTarget"]:
        '''List of targets that traffic is routed to when a request matches the route.'''
        result = self._values.get("weighted_targets")
        assert result is not None, "Required property 'weighted_targets' is missing"
        return typing.cast(typing.List["WeightedTarget"], result)

    @builtins.property
    def timeout(self) -> typing.Optional["TcpTimeout"]:
        '''An object that represents a tcp timeout.

        :default: - None
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional["TcpTimeout"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TcpRouteSpecOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TcpTimeout",
    jsii_struct_bases=[],
    name_mapping={"idle": "idle"},
)
class TcpTimeout:
    def __init__(self, *, idle: typing.Optional[aws_cdk.core.Duration] = None) -> None:
        '''Represents timeouts for TCP protocols.

        :param idle: Represents an idle timeout. The amount of time that a connection may be idle. Default: - none

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            import aws_cdk.core as cdk
            
            tcp_timeout = appmesh.TcpTimeout(
                idle=cdk.Duration.minutes(30)
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TcpTimeout.__init__)
            check_type(argname="argument idle", value=idle, expected_type=type_hints["idle"])
        self._values: typing.Dict[str, typing.Any] = {}
        if idle is not None:
            self._values["idle"] = idle

    @builtins.property
    def idle(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''Represents an idle timeout.

        The amount of time that a connection may be idle.

        :default: - none
        '''
        result = self._values.get("idle")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TcpTimeout(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TcpVirtualNodeListenerOptions",
    jsii_struct_bases=[],
    name_mapping={
        "connection_pool": "connectionPool",
        "health_check": "healthCheck",
        "outlier_detection": "outlierDetection",
        "port": "port",
        "timeout": "timeout",
        "tls": "tls",
    },
)
class TcpVirtualNodeListenerOptions:
    def __init__(
        self,
        *,
        connection_pool: typing.Optional[typing.Union[TcpConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        outlier_detection: typing.Optional[typing.Union[OutlierDetection, typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union[TcpTimeout, typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represent the TCP Node Listener prorperty.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for TCP protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            import aws_cdk.core as cdk
            
            # health_check: appmesh.HealthCheck
            # mutual_tls_validation_trust: appmesh.MutualTlsValidationTrust
            # subject_alternative_names: appmesh.SubjectAlternativeNames
            # tls_certificate: appmesh.TlsCertificate
            
            tcp_virtual_node_listener_options = appmesh.TcpVirtualNodeListenerOptions(
                connection_pool=appmesh.TcpConnectionPool(
                    max_connections=123
                ),
                health_check=health_check,
                outlier_detection=appmesh.OutlierDetection(
                    base_ejection_duration=cdk.Duration.minutes(30),
                    interval=cdk.Duration.minutes(30),
                    max_ejection_percent=123,
                    max_server_errors=123
                ),
                port=123,
                timeout=appmesh.TcpTimeout(
                    idle=cdk.Duration.minutes(30)
                ),
                tls=appmesh.ListenerTlsOptions(
                    certificate=tls_certificate,
                    mode=appmesh.TlsMode.STRICT,
            
                    # the properties below are optional
                    mutual_tls_validation=appmesh.MutualTlsValidation(
                        trust=mutual_tls_validation_trust,
            
                        # the properties below are optional
                        subject_alternative_names=subject_alternative_names
                    )
                )
            )
        '''
        if isinstance(connection_pool, dict):
            connection_pool = TcpConnectionPool(**connection_pool)
        if isinstance(outlier_detection, dict):
            outlier_detection = OutlierDetection(**outlier_detection)
        if isinstance(timeout, dict):
            timeout = TcpTimeout(**timeout)
        if isinstance(tls, dict):
            tls = ListenerTlsOptions(**tls)
        if __debug__:
            type_hints = typing.get_type_hints(TcpVirtualNodeListenerOptions.__init__)
            check_type(argname="argument connection_pool", value=connection_pool, expected_type=type_hints["connection_pool"])
            check_type(argname="argument health_check", value=health_check, expected_type=type_hints["health_check"])
            check_type(argname="argument outlier_detection", value=outlier_detection, expected_type=type_hints["outlier_detection"])
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
            check_type(argname="argument tls", value=tls, expected_type=type_hints["tls"])
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_pool is not None:
            self._values["connection_pool"] = connection_pool
        if health_check is not None:
            self._values["health_check"] = health_check
        if outlier_detection is not None:
            self._values["outlier_detection"] = outlier_detection
        if port is not None:
            self._values["port"] = port
        if timeout is not None:
            self._values["timeout"] = timeout
        if tls is not None:
            self._values["tls"] = tls

    @builtins.property
    def connection_pool(self) -> typing.Optional[TcpConnectionPool]:
        '''Connection pool for http listeners.

        :default: - None
        '''
        result = self._values.get("connection_pool")
        return typing.cast(typing.Optional[TcpConnectionPool], result)

    @builtins.property
    def health_check(self) -> typing.Optional[HealthCheck]:
        '''The health check information for the listener.

        :default: - no healthcheck
        '''
        result = self._values.get("health_check")
        return typing.cast(typing.Optional[HealthCheck], result)

    @builtins.property
    def outlier_detection(self) -> typing.Optional[OutlierDetection]:
        '''Represents the configuration for enabling outlier detection.

        :default: - none
        '''
        result = self._values.get("outlier_detection")
        return typing.cast(typing.Optional[OutlierDetection], result)

    @builtins.property
    def port(self) -> typing.Optional[jsii.Number]:
        '''Port to listen for connections on.

        :default: - 8080
        '''
        result = self._values.get("port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def timeout(self) -> typing.Optional[TcpTimeout]:
        '''Timeout for TCP protocol.

        :default: - None
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[TcpTimeout], result)

    @builtins.property
    def tls(self) -> typing.Optional[ListenerTlsOptions]:
        '''Represents the configuration for enabling TLS on a listener.

        :default: - none
        '''
        result = self._values.get("tls")
        return typing.cast(typing.Optional[ListenerTlsOptions], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TcpVirtualNodeListenerOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class TlsCertificate(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.TlsCertificate",
):
    '''Represents a TLS certificate.

    :exampleMetadata: infused

    Example::

        # A Virtual Node with listener TLS from an ACM provided certificate
        # cert: certificatemanager.Certificate
        # mesh: appmesh.Mesh
        
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node"),
            listeners=[appmesh.VirtualNodeListener.grpc(
                port=80,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.acm(cert)
                )
            )]
        )
        
        # A Virtual Gateway with listener TLS from a customer provided file certificate
        gateway = appmesh.VirtualGateway(self, "gateway",
            mesh=mesh,
            listeners=[appmesh.VirtualGatewayListener.grpc(
                port=8080,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey")
                )
            )],
            virtual_gateway_name="gateway"
        )
        
        # A Virtual Gateway with listener TLS from a SDS provided certificate
        gateway2 = appmesh.VirtualGateway(self, "gateway2",
            mesh=mesh,
            listeners=[appmesh.VirtualGatewayListener.http2(
                port=8080,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.sds("secrete_certificate")
                )
            )],
            virtual_gateway_name="gateway2"
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="acm")
    @builtins.classmethod
    def acm(
        cls,
        certificate: aws_cdk.aws_certificatemanager.ICertificate,
    ) -> "TlsCertificate":
        '''Returns an ACM TLS Certificate.

        :param certificate: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsCertificate.acm)
            check_type(argname="argument certificate", value=certificate, expected_type=type_hints["certificate"])
        return typing.cast("TlsCertificate", jsii.sinvoke(cls, "acm", [certificate]))

    @jsii.member(jsii_name="file")
    @builtins.classmethod
    def file(
        cls,
        certificate_chain_path: builtins.str,
        private_key_path: builtins.str,
    ) -> "MutualTlsCertificate":
        '''Returns an File TLS Certificate.

        :param certificate_chain_path: -
        :param private_key_path: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsCertificate.file)
            check_type(argname="argument certificate_chain_path", value=certificate_chain_path, expected_type=type_hints["certificate_chain_path"])
            check_type(argname="argument private_key_path", value=private_key_path, expected_type=type_hints["private_key_path"])
        return typing.cast("MutualTlsCertificate", jsii.sinvoke(cls, "file", [certificate_chain_path, private_key_path]))

    @jsii.member(jsii_name="sds")
    @builtins.classmethod
    def sds(cls, secret_name: builtins.str) -> "MutualTlsCertificate":
        '''Returns an SDS TLS Certificate.

        :param secret_name: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsCertificate.sds)
            check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
        return typing.cast("MutualTlsCertificate", jsii.sinvoke(cls, "sds", [secret_name]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, _scope: aws_cdk.core.Construct) -> "TlsCertificateConfig":
        '''Returns TLS certificate based provider.

        :param _scope: -
        '''
        ...


class _TlsCertificateProxy(TlsCertificate):
    @jsii.member(jsii_name="bind")
    def bind(self, _scope: aws_cdk.core.Construct) -> "TlsCertificateConfig":
        '''Returns TLS certificate based provider.

        :param _scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsCertificate.bind)
            check_type(argname="argument _scope", value=_scope, expected_type=type_hints["_scope"])
        return typing.cast("TlsCertificateConfig", jsii.invoke(self, "bind", [_scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, TlsCertificate).__jsii_proxy_class__ = lambda : _TlsCertificateProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TlsCertificateConfig",
    jsii_struct_bases=[],
    name_mapping={"tls_certificate": "tlsCertificate"},
)
class TlsCertificateConfig:
    def __init__(
        self,
        *,
        tls_certificate: typing.Union[CfnVirtualNode.ListenerTlsCertificateProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''A wrapper for the tls config returned by {@link TlsCertificate.bind}.

        :param tls_certificate: The CFN shape for a TLS certificate.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            tls_certificate_config = appmesh.TlsCertificateConfig(
                tls_certificate=appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                    acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                        certificate_arn="certificateArn"
                    ),
                    file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                        certificate_chain="certificateChain",
                        private_key="privateKey"
                    ),
                    sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                        secret_name="secretName"
                    )
                )
            )
        '''
        if isinstance(tls_certificate, dict):
            tls_certificate = CfnVirtualNode.ListenerTlsCertificateProperty(**tls_certificate)
        if __debug__:
            type_hints = typing.get_type_hints(TlsCertificateConfig.__init__)
            check_type(argname="argument tls_certificate", value=tls_certificate, expected_type=type_hints["tls_certificate"])
        self._values: typing.Dict[str, typing.Any] = {
            "tls_certificate": tls_certificate,
        }

    @builtins.property
    def tls_certificate(self) -> CfnVirtualNode.ListenerTlsCertificateProperty:
        '''The CFN shape for a TLS certificate.'''
        result = self._values.get("tls_certificate")
        assert result is not None, "Required property 'tls_certificate' is missing"
        return typing.cast(CfnVirtualNode.ListenerTlsCertificateProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TlsCertificateConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TlsClientPolicy",
    jsii_struct_bases=[],
    name_mapping={
        "validation": "validation",
        "enforce": "enforce",
        "mutual_tls_certificate": "mutualTlsCertificate",
        "ports": "ports",
    },
)
class TlsClientPolicy:
    def __init__(
        self,
        *,
        validation: typing.Union["TlsValidation", typing.Dict[str, typing.Any]],
        enforce: typing.Optional[builtins.bool] = None,
        mutual_tls_certificate: typing.Optional["MutualTlsCertificate"] = None,
        ports: typing.Optional[typing.Sequence[jsii.Number]] = None,
    ) -> None:
        '''Represents the properties needed to define client policy.

        :param validation: Represents the object for TLS validation context.
        :param enforce: Whether the policy is enforced. Default: true
        :param mutual_tls_certificate: Represents a client TLS certificate. The certificate will be sent only if the server requests it, enabling mutual TLS. Default: - client TLS certificate is not provided
        :param ports: TLS is enforced on the ports specified here. If no ports are specified, TLS will be enforced on all the ports. Default: - all ports

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            # service: cloudmap.Service
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=8080,
                    health_check=appmesh.HealthCheck.http(
                        healthy_threshold=3,
                        interval=cdk.Duration.seconds(5),
                        path="/ping",
                        timeout=cdk.Duration.seconds(2),
                        unhealthy_threshold=2
                    ),
                    timeout=appmesh.HttpTimeout(
                        idle=cdk.Duration.seconds(5)
                    )
                )],
                backend_defaults=appmesh.BackendDefaults(
                    tls_client_policy=appmesh.TlsClientPolicy(
                        validation=appmesh.TlsValidation(
                            trust=appmesh.TlsValidationTrust.file("/keys/local_cert_chain.pem")
                        )
                    )
                ),
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
            )
            
            cdk.Tags.of(node).add("Environment", "Dev")
        '''
        if isinstance(validation, dict):
            validation = TlsValidation(**validation)
        if __debug__:
            type_hints = typing.get_type_hints(TlsClientPolicy.__init__)
            check_type(argname="argument validation", value=validation, expected_type=type_hints["validation"])
            check_type(argname="argument enforce", value=enforce, expected_type=type_hints["enforce"])
            check_type(argname="argument mutual_tls_certificate", value=mutual_tls_certificate, expected_type=type_hints["mutual_tls_certificate"])
            check_type(argname="argument ports", value=ports, expected_type=type_hints["ports"])
        self._values: typing.Dict[str, typing.Any] = {
            "validation": validation,
        }
        if enforce is not None:
            self._values["enforce"] = enforce
        if mutual_tls_certificate is not None:
            self._values["mutual_tls_certificate"] = mutual_tls_certificate
        if ports is not None:
            self._values["ports"] = ports

    @builtins.property
    def validation(self) -> "TlsValidation":
        '''Represents the object for TLS validation context.'''
        result = self._values.get("validation")
        assert result is not None, "Required property 'validation' is missing"
        return typing.cast("TlsValidation", result)

    @builtins.property
    def enforce(self) -> typing.Optional[builtins.bool]:
        '''Whether the policy is enforced.

        :default: true
        '''
        result = self._values.get("enforce")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def mutual_tls_certificate(self) -> typing.Optional["MutualTlsCertificate"]:
        '''Represents a client TLS certificate.

        The certificate will be sent only if the server requests it, enabling mutual TLS.

        :default: - client TLS certificate is not provided
        '''
        result = self._values.get("mutual_tls_certificate")
        return typing.cast(typing.Optional["MutualTlsCertificate"], result)

    @builtins.property
    def ports(self) -> typing.Optional[typing.List[jsii.Number]]:
        '''TLS is enforced on the ports specified here.

        If no ports are specified, TLS will be enforced on all the ports.

        :default: - all ports
        '''
        result = self._values.get("ports")
        return typing.cast(typing.Optional[typing.List[jsii.Number]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TlsClientPolicy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-appmesh.TlsMode")
class TlsMode(enum.Enum):
    '''Enum of supported TLS modes.

    :exampleMetadata: infused

    Example::

        # A Virtual Node with listener TLS from an ACM provided certificate
        # cert: certificatemanager.Certificate
        # mesh: appmesh.Mesh
        
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node"),
            listeners=[appmesh.VirtualNodeListener.grpc(
                port=80,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.acm(cert)
                )
            )]
        )
        
        # A Virtual Gateway with listener TLS from a customer provided file certificate
        gateway = appmesh.VirtualGateway(self, "gateway",
            mesh=mesh,
            listeners=[appmesh.VirtualGatewayListener.grpc(
                port=8080,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey")
                )
            )],
            virtual_gateway_name="gateway"
        )
        
        # A Virtual Gateway with listener TLS from a SDS provided certificate
        gateway2 = appmesh.VirtualGateway(self, "gateway2",
            mesh=mesh,
            listeners=[appmesh.VirtualGatewayListener.http2(
                port=8080,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.sds("secrete_certificate")
                )
            )],
            virtual_gateway_name="gateway2"
        )
    '''

    STRICT = "STRICT"
    '''Only accept encrypted traffic.'''
    PERMISSIVE = "PERMISSIVE"
    '''Accept encrypted and plaintext traffic.'''
    DISABLED = "DISABLED"
    '''TLS is disabled, only accept plaintext traffic.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TlsValidation",
    jsii_struct_bases=[],
    name_mapping={
        "trust": "trust",
        "subject_alternative_names": "subjectAlternativeNames",
    },
)
class TlsValidation:
    def __init__(
        self,
        *,
        trust: "TlsValidationTrust",
        subject_alternative_names: typing.Optional[SubjectAlternativeNames] = None,
    ) -> None:
        '''Represents the properties needed to define TLS Validation context.

        :param trust: Reference to where to retrieve the trust chain.
        :param subject_alternative_names: Represents the subject alternative names (SANs) secured by the certificate. SANs must be in the FQDN or URI format. Default: - If you don't specify SANs on the terminating mesh endpoint, the Envoy proxy for that node doesn't verify the SAN on a peer client certificate. If you don't specify SANs on the originating mesh endpoint, the SAN on the certificate provided by the terminating endpoint must match the mesh endpoint service discovery configuration.

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            # service: cloudmap.Service
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=8080,
                    health_check=appmesh.HealthCheck.http(
                        healthy_threshold=3,
                        interval=cdk.Duration.seconds(5),
                        path="/ping",
                        timeout=cdk.Duration.seconds(2),
                        unhealthy_threshold=2
                    ),
                    timeout=appmesh.HttpTimeout(
                        idle=cdk.Duration.seconds(5)
                    )
                )],
                backend_defaults=appmesh.BackendDefaults(
                    tls_client_policy=appmesh.TlsClientPolicy(
                        validation=appmesh.TlsValidation(
                            trust=appmesh.TlsValidationTrust.file("/keys/local_cert_chain.pem")
                        )
                    )
                ),
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
            )
            
            cdk.Tags.of(node).add("Environment", "Dev")
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsValidation.__init__)
            check_type(argname="argument trust", value=trust, expected_type=type_hints["trust"])
            check_type(argname="argument subject_alternative_names", value=subject_alternative_names, expected_type=type_hints["subject_alternative_names"])
        self._values: typing.Dict[str, typing.Any] = {
            "trust": trust,
        }
        if subject_alternative_names is not None:
            self._values["subject_alternative_names"] = subject_alternative_names

    @builtins.property
    def trust(self) -> "TlsValidationTrust":
        '''Reference to where to retrieve the trust chain.'''
        result = self._values.get("trust")
        assert result is not None, "Required property 'trust' is missing"
        return typing.cast("TlsValidationTrust", result)

    @builtins.property
    def subject_alternative_names(self) -> typing.Optional[SubjectAlternativeNames]:
        '''Represents the subject alternative names (SANs) secured by the certificate.

        SANs must be in the FQDN or URI format.

        :default:

        - If you don't specify SANs on the terminating mesh endpoint,
        the Envoy proxy for that node doesn't verify the SAN on a peer client certificate.
        If you don't specify SANs on the originating mesh endpoint,
        the SAN on the certificate provided by the terminating endpoint must match the mesh endpoint service discovery configuration.
        '''
        result = self._values.get("subject_alternative_names")
        return typing.cast(typing.Optional[SubjectAlternativeNames], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TlsValidation(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class TlsValidationTrust(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.TlsValidationTrust",
):
    '''Defines the TLS Validation Context Trust.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        # service: cloudmap.Service
        
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
            listeners=[appmesh.VirtualNodeListener.http(
                port=8080,
                health_check=appmesh.HealthCheck.http(
                    healthy_threshold=3,
                    interval=cdk.Duration.seconds(5),
                    path="/ping",
                    timeout=cdk.Duration.seconds(2),
                    unhealthy_threshold=2
                ),
                timeout=appmesh.HttpTimeout(
                    idle=cdk.Duration.seconds(5)
                )
            )],
            backend_defaults=appmesh.BackendDefaults(
                tls_client_policy=appmesh.TlsClientPolicy(
                    validation=appmesh.TlsValidation(
                        trust=appmesh.TlsValidationTrust.file("/keys/local_cert_chain.pem")
                    )
                )
            ),
            access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
        )
        
        cdk.Tags.of(node).add("Environment", "Dev")
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="acm")
    @builtins.classmethod
    def acm(
        cls,
        certificate_authorities: typing.Sequence[aws_cdk.aws_acmpca.ICertificateAuthority],
    ) -> "TlsValidationTrust":
        '''TLS Validation Context Trust for ACM Private Certificate Authority (CA).

        :param certificate_authorities: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsValidationTrust.acm)
            check_type(argname="argument certificate_authorities", value=certificate_authorities, expected_type=type_hints["certificate_authorities"])
        return typing.cast("TlsValidationTrust", jsii.sinvoke(cls, "acm", [certificate_authorities]))

    @jsii.member(jsii_name="file")
    @builtins.classmethod
    def file(cls, certificate_chain: builtins.str) -> "MutualTlsValidationTrust":
        '''Tells envoy where to fetch the validation context from.

        :param certificate_chain: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsValidationTrust.file)
            check_type(argname="argument certificate_chain", value=certificate_chain, expected_type=type_hints["certificate_chain"])
        return typing.cast("MutualTlsValidationTrust", jsii.sinvoke(cls, "file", [certificate_chain]))

    @jsii.member(jsii_name="sds")
    @builtins.classmethod
    def sds(cls, secret_name: builtins.str) -> "MutualTlsValidationTrust":
        '''TLS Validation Context Trust for Envoy' service discovery service.

        :param secret_name: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsValidationTrust.sds)
            check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
        return typing.cast("MutualTlsValidationTrust", jsii.sinvoke(cls, "sds", [secret_name]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "TlsValidationTrustConfig":
        '''Returns Trust context based on trust type.

        :param scope: -
        '''
        ...


class _TlsValidationTrustProxy(TlsValidationTrust):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "TlsValidationTrustConfig":
        '''Returns Trust context based on trust type.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(TlsValidationTrust.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("TlsValidationTrustConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, TlsValidationTrust).__jsii_proxy_class__ = lambda : _TlsValidationTrustProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.TlsValidationTrustConfig",
    jsii_struct_bases=[],
    name_mapping={"tls_validation_trust": "tlsValidationTrust"},
)
class TlsValidationTrustConfig:
    def __init__(
        self,
        *,
        tls_validation_trust: typing.Union[CfnVirtualNode.TlsValidationContextTrustProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''All Properties for TLS Validation Trusts for both Client Policy and Listener.

        :param tls_validation_trust: VirtualNode CFN configuration for client policy's TLS Validation Trust.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            tls_validation_trust_config = appmesh.TlsValidationTrustConfig(
                tls_validation_trust=appmesh.CfnVirtualNode.TlsValidationContextTrustProperty(
                    acm=appmesh.CfnVirtualNode.TlsValidationContextAcmTrustProperty(
                        certificate_authority_arns=["certificateAuthorityArns"]
                    ),
                    file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                        certificate_chain="certificateChain"
                    ),
                    sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                        secret_name="secretName"
                    )
                )
            )
        '''
        if isinstance(tls_validation_trust, dict):
            tls_validation_trust = CfnVirtualNode.TlsValidationContextTrustProperty(**tls_validation_trust)
        if __debug__:
            type_hints = typing.get_type_hints(TlsValidationTrustConfig.__init__)
            check_type(argname="argument tls_validation_trust", value=tls_validation_trust, expected_type=type_hints["tls_validation_trust"])
        self._values: typing.Dict[str, typing.Any] = {
            "tls_validation_trust": tls_validation_trust,
        }

    @builtins.property
    def tls_validation_trust(self) -> CfnVirtualNode.TlsValidationContextTrustProperty:
        '''VirtualNode CFN configuration for client policy's TLS Validation Trust.'''
        result = self._values.get("tls_validation_trust")
        assert result is not None, "Required property 'tls_validation_trust' is missing"
        return typing.cast(CfnVirtualNode.TlsValidationContextTrustProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "TlsValidationTrustConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IVirtualGateway)
class VirtualGateway(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.VirtualGateway",
):
    '''VirtualGateway represents a newly defined App Mesh Virtual Gateway.

    A virtual gateway allows resources that are outside of your mesh to communicate to resources that
    are inside of your mesh.

    :see: https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_gateways.html
    :exampleMetadata: infused

    Example::

        # A Virtual Node with a gRPC listener with a connection pool set
        # mesh: appmesh.Mesh
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            # DNS service discovery can optionally specify the DNS response type as either LOAD_BALANCER or ENDPOINTS.
            # LOAD_BALANCER means that the DNS resolver returns a loadbalanced set of endpoints,
            # whereas ENDPOINTS means that the DNS resolver is returning all the endpoints.
            # By default, the response type is assumed to be LOAD_BALANCER
            service_discovery=appmesh.ServiceDiscovery.dns("node", appmesh.DnsResponseType.ENDPOINTS),
            listeners=[appmesh.VirtualNodeListener.http(
                port=80,
                connection_pool=appmesh.HttpConnectionPool(
                    max_connections=100,
                    max_pending_requests=10
                )
            )]
        )
        
        # A Virtual Gateway with a gRPC listener with a connection pool set
        gateway = appmesh.VirtualGateway(self, "gateway",
            mesh=mesh,
            listeners=[appmesh.VirtualGatewayListener.grpc(
                port=8080,
                connection_pool=appmesh.GrpcConnectionPool(
                    max_requests=10
                )
            )],
            virtual_gateway_name="gateway"
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualGatewayListener"]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param mesh: The Mesh which the VirtualGateway belongs to.
        :param access_log: Access Logging Configuration for the VirtualGateway. Default: - no access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param listeners: Listeners for the VirtualGateway. Only one is supported. Default: - Single HTTP listener on port 8080
        :param virtual_gateway_name: Name of the VirtualGateway. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGateway.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualGatewayProps(
            mesh=mesh,
            access_log=access_log,
            backend_defaults=backend_defaults,
            listeners=listeners,
            virtual_gateway_name=virtual_gateway_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromVirtualGatewayArn")
    @builtins.classmethod
    def from_virtual_gateway_arn(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        virtual_gateway_arn: builtins.str,
    ) -> IVirtualGateway:
        '''Import an existing VirtualGateway given an ARN.

        :param scope: -
        :param id: -
        :param virtual_gateway_arn: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGateway.from_virtual_gateway_arn)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument virtual_gateway_arn", value=virtual_gateway_arn, expected_type=type_hints["virtual_gateway_arn"])
        return typing.cast(IVirtualGateway, jsii.sinvoke(cls, "fromVirtualGatewayArn", [scope, id, virtual_gateway_arn]))

    @jsii.member(jsii_name="fromVirtualGatewayAttributes")
    @builtins.classmethod
    def from_virtual_gateway_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        virtual_gateway_name: builtins.str,
    ) -> IVirtualGateway:
        '''Import an existing VirtualGateway given its attributes.

        :param scope: -
        :param id: -
        :param mesh: The Mesh that the VirtualGateway belongs to.
        :param virtual_gateway_name: The name of the VirtualGateway.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGateway.from_virtual_gateway_attributes)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        attrs = VirtualGatewayAttributes(
            mesh=mesh, virtual_gateway_name=virtual_gateway_name
        )

        return typing.cast(IVirtualGateway, jsii.sinvoke(cls, "fromVirtualGatewayAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addGatewayRoute")
    def add_gateway_route(
        self,
        id: builtins.str,
        *,
        route_spec: GatewayRouteSpec,
        gateway_route_name: typing.Optional[builtins.str] = None,
    ) -> "GatewayRoute":
        '''Utility method to add a new GatewayRoute to the VirtualGateway.

        :param id: -
        :param route_spec: What protocol the route uses.
        :param gateway_route_name: The name of the GatewayRoute. Default: - an automatically generated name
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGateway.add_gateway_route)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = GatewayRouteBaseProps(
            route_spec=route_spec, gateway_route_name=gateway_route_name
        )

        return typing.cast("GatewayRoute", jsii.invoke(self, "addGatewayRoute", [id, props]))

    @jsii.member(jsii_name="grantStreamAggregatedResources")
    def grant_stream_aggregated_resources(
        self,
        identity: aws_cdk.aws_iam.IGrantable,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants the given entity ``appmesh:StreamAggregatedResources``.

        :param identity: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGateway.grant_stream_aggregated_resources)
            check_type(argname="argument identity", value=identity, expected_type=type_hints["identity"])
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantStreamAggregatedResources", [identity]))

    @builtins.property
    @jsii.member(jsii_name="listeners")
    def _listeners(self) -> typing.List["VirtualGatewayListenerConfig"]:
        return typing.cast(typing.List["VirtualGatewayListenerConfig"], jsii.get(self, "listeners"))

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh that the VirtualGateway belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayArn")
    def virtual_gateway_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the VirtualGateway.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualGatewayArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualGatewayName")
    def virtual_gateway_name(self) -> builtins.str:
        '''The name of the VirtualGateway.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualGatewayName"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualGatewayAttributes",
    jsii_struct_bases=[],
    name_mapping={"mesh": "mesh", "virtual_gateway_name": "virtualGatewayName"},
)
class VirtualGatewayAttributes:
    def __init__(self, *, mesh: IMesh, virtual_gateway_name: builtins.str) -> None:
        '''Unterface with properties necessary to import a reusable VirtualGateway.

        :param mesh: The Mesh that the VirtualGateway belongs to.
        :param virtual_gateway_name: The name of the VirtualGateway.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # mesh: appmesh.Mesh
            
            virtual_gateway_attributes = appmesh.VirtualGatewayAttributes(
                mesh=mesh,
                virtual_gateway_name="virtualGatewayName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGatewayAttributes.__init__)
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
            check_type(argname="argument virtual_gateway_name", value=virtual_gateway_name, expected_type=type_hints["virtual_gateway_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
            "virtual_gateway_name": virtual_gateway_name,
        }

    @builtins.property
    def mesh(self) -> IMesh:
        '''The Mesh that the VirtualGateway belongs to.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    @builtins.property
    def virtual_gateway_name(self) -> builtins.str:
        '''The name of the VirtualGateway.'''
        result = self._values.get("virtual_gateway_name")
        assert result is not None, "Required property 'virtual_gateway_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualGatewayAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualGatewayBaseProps",
    jsii_struct_bases=[],
    name_mapping={
        "access_log": "accessLog",
        "backend_defaults": "backendDefaults",
        "listeners": "listeners",
        "virtual_gateway_name": "virtualGatewayName",
    },
)
class VirtualGatewayBaseProps:
    def __init__(
        self,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualGatewayListener"]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Basic configuration properties for a VirtualGateway.

        :param access_log: Access Logging Configuration for the VirtualGateway. Default: - no access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param listeners: Listeners for the VirtualGateway. Only one is supported. Default: - Single HTTP listener on port 8080
        :param virtual_gateway_name: Name of the VirtualGateway. Default: - A name is automatically determined

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            
            
            gateway = mesh.add_virtual_gateway("gateway",
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout"),
                virtual_gateway_name="virtualGateway",
                listeners=[appmesh.VirtualGatewayListener.http(
                    port=443,
                    health_check=appmesh.HealthCheck.http(
                        interval=cdk.Duration.seconds(10)
                    )
                )]
            )
        '''
        if isinstance(backend_defaults, dict):
            backend_defaults = BackendDefaults(**backend_defaults)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGatewayBaseProps.__init__)
            check_type(argname="argument access_log", value=access_log, expected_type=type_hints["access_log"])
            check_type(argname="argument backend_defaults", value=backend_defaults, expected_type=type_hints["backend_defaults"])
            check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
            check_type(argname="argument virtual_gateway_name", value=virtual_gateway_name, expected_type=type_hints["virtual_gateway_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if access_log is not None:
            self._values["access_log"] = access_log
        if backend_defaults is not None:
            self._values["backend_defaults"] = backend_defaults
        if listeners is not None:
            self._values["listeners"] = listeners
        if virtual_gateway_name is not None:
            self._values["virtual_gateway_name"] = virtual_gateway_name

    @builtins.property
    def access_log(self) -> typing.Optional[AccessLog]:
        '''Access Logging Configuration for the VirtualGateway.

        :default: - no access logging
        '''
        result = self._values.get("access_log")
        return typing.cast(typing.Optional[AccessLog], result)

    @builtins.property
    def backend_defaults(self) -> typing.Optional[BackendDefaults]:
        '''Default Configuration Virtual Node uses to communicate with Virtual Service.

        :default: - No Config
        '''
        result = self._values.get("backend_defaults")
        return typing.cast(typing.Optional[BackendDefaults], result)

    @builtins.property
    def listeners(self) -> typing.Optional[typing.List["VirtualGatewayListener"]]:
        '''Listeners for the VirtualGateway.

        Only one is supported.

        :default: - Single HTTP listener on port 8080
        '''
        result = self._values.get("listeners")
        return typing.cast(typing.Optional[typing.List["VirtualGatewayListener"]], result)

    @builtins.property
    def virtual_gateway_name(self) -> typing.Optional[builtins.str]:
        '''Name of the VirtualGateway.

        :default: - A name is automatically determined
        '''
        result = self._values.get("virtual_gateway_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualGatewayBaseProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class VirtualGatewayListener(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.VirtualGatewayListener",
):
    '''Represents the properties needed to define listeners for a VirtualGateway.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
        
        gateway = appmesh.VirtualGateway(self, "gateway",
            mesh=mesh,
            listeners=[appmesh.VirtualGatewayListener.http(
                port=443,
                health_check=appmesh.HealthCheck.http(
                    interval=cdk.Duration.seconds(10)
                )
            )],
            backend_defaults=appmesh.BackendDefaults(
                tls_client_policy=appmesh.TlsClientPolicy(
                    ports=[8080, 8081],
                    validation=appmesh.TlsValidation(
                        trust=appmesh.TlsValidationTrust.acm([
                            acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                        ])
                    )
                )
            ),
            access_log=appmesh.AccessLog.from_file_path("/dev/stdout"),
            virtual_gateway_name="virtualGateway"
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="grpc")
    @builtins.classmethod
    def grpc(
        cls,
        *,
        connection_pool: typing.Optional[typing.Union[GrpcConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        port: typing.Optional[jsii.Number] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> "VirtualGatewayListener":
        '''Returns a GRPC Listener for a VirtualGateway.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param port: Port to listen for connections on. Default: - 8080
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none
        '''
        options = GrpcGatewayListenerOptions(
            connection_pool=connection_pool,
            health_check=health_check,
            port=port,
            tls=tls,
        )

        return typing.cast("VirtualGatewayListener", jsii.sinvoke(cls, "grpc", [options]))

    @jsii.member(jsii_name="http")
    @builtins.classmethod
    def http(
        cls,
        *,
        connection_pool: typing.Optional[typing.Union[HttpConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        port: typing.Optional[jsii.Number] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> "VirtualGatewayListener":
        '''Returns an HTTP Listener for a VirtualGateway.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param port: Port to listen for connections on. Default: - 8080
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none
        '''
        options = HttpGatewayListenerOptions(
            connection_pool=connection_pool,
            health_check=health_check,
            port=port,
            tls=tls,
        )

        return typing.cast("VirtualGatewayListener", jsii.sinvoke(cls, "http", [options]))

    @jsii.member(jsii_name="http2")
    @builtins.classmethod
    def http2(
        cls,
        *,
        connection_pool: typing.Optional[typing.Union[Http2ConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        port: typing.Optional[jsii.Number] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> "VirtualGatewayListener":
        '''Returns an HTTP2 Listener for a VirtualGateway.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param port: Port to listen for connections on. Default: - 8080
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none
        '''
        options = Http2GatewayListenerOptions(
            connection_pool=connection_pool,
            health_check=health_check,
            port=port,
            tls=tls,
        )

        return typing.cast("VirtualGatewayListener", jsii.sinvoke(cls, "http2", [options]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "VirtualGatewayListenerConfig":
        '''Called when the GatewayListener type is initialized.

        Can be used to enforce
        mutual exclusivity

        :param scope: -
        '''
        ...


class _VirtualGatewayListenerProxy(VirtualGatewayListener):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "VirtualGatewayListenerConfig":
        '''Called when the GatewayListener type is initialized.

        Can be used to enforce
        mutual exclusivity

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGatewayListener.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("VirtualGatewayListenerConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, VirtualGatewayListener).__jsii_proxy_class__ = lambda : _VirtualGatewayListenerProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualGatewayListenerConfig",
    jsii_struct_bases=[],
    name_mapping={"listener": "listener"},
)
class VirtualGatewayListenerConfig:
    def __init__(
        self,
        *,
        listener: typing.Union[CfnVirtualGateway.VirtualGatewayListenerProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''Properties for a VirtualGateway listener.

        :param listener: Single listener config for a VirtualGateway.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            virtual_gateway_listener_config = appmesh.VirtualGatewayListenerConfig(
                listener=appmesh.CfnVirtualGateway.VirtualGatewayListenerProperty(
                    port_mapping=appmesh.CfnVirtualGateway.VirtualGatewayPortMappingProperty(
                        port=123,
                        protocol="protocol"
                    ),
            
                    # the properties below are optional
                    connection_pool=appmesh.CfnVirtualGateway.VirtualGatewayConnectionPoolProperty(
                        grpc=appmesh.CfnVirtualGateway.VirtualGatewayGrpcConnectionPoolProperty(
                            max_requests=123
                        ),
                        http=appmesh.CfnVirtualGateway.VirtualGatewayHttpConnectionPoolProperty(
                            max_connections=123,
            
                            # the properties below are optional
                            max_pending_requests=123
                        ),
                        http2=appmesh.CfnVirtualGateway.VirtualGatewayHttp2ConnectionPoolProperty(
                            max_requests=123
                        )
                    ),
                    health_check=appmesh.CfnVirtualGateway.VirtualGatewayHealthCheckPolicyProperty(
                        healthy_threshold=123,
                        interval_millis=123,
                        protocol="protocol",
                        timeout_millis=123,
                        unhealthy_threshold=123,
            
                        # the properties below are optional
                        path="path",
                        port=123
                    ),
                    tls=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsProperty(
                        certificate=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsCertificateProperty(
                            acm=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsAcmCertificateProperty(
                                certificate_arn="certificateArn"
                            ),
                            file=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        mode="mode",
            
                        # the properties below are optional
                        validation=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextProperty(
                            trust=appmesh.CfnVirtualGateway.VirtualGatewayListenerTlsValidationContextTrustProperty(
                                file=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualGateway.VirtualGatewayTlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
            
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualGateway.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualGateway.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        )
                    )
                )
            )
        '''
        if isinstance(listener, dict):
            listener = CfnVirtualGateway.VirtualGatewayListenerProperty(**listener)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGatewayListenerConfig.__init__)
            check_type(argname="argument listener", value=listener, expected_type=type_hints["listener"])
        self._values: typing.Dict[str, typing.Any] = {
            "listener": listener,
        }

    @builtins.property
    def listener(self) -> CfnVirtualGateway.VirtualGatewayListenerProperty:
        '''Single listener config for a VirtualGateway.'''
        result = self._values.get("listener")
        assert result is not None, "Required property 'listener' is missing"
        return typing.cast(CfnVirtualGateway.VirtualGatewayListenerProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualGatewayListenerConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualGatewayProps",
    jsii_struct_bases=[VirtualGatewayBaseProps],
    name_mapping={
        "access_log": "accessLog",
        "backend_defaults": "backendDefaults",
        "listeners": "listeners",
        "virtual_gateway_name": "virtualGatewayName",
        "mesh": "mesh",
    },
)
class VirtualGatewayProps(VirtualGatewayBaseProps):
    def __init__(
        self,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        listeners: typing.Optional[typing.Sequence[VirtualGatewayListener]] = None,
        virtual_gateway_name: typing.Optional[builtins.str] = None,
        mesh: IMesh,
    ) -> None:
        '''Properties used when creating a new VirtualGateway.

        :param access_log: Access Logging Configuration for the VirtualGateway. Default: - no access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param listeners: Listeners for the VirtualGateway. Only one is supported. Default: - Single HTTP listener on port 8080
        :param virtual_gateway_name: Name of the VirtualGateway. Default: - A name is automatically determined
        :param mesh: The Mesh which the VirtualGateway belongs to.

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            
            certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
            
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.http(
                    port=443,
                    health_check=appmesh.HealthCheck.http(
                        interval=cdk.Duration.seconds(10)
                    )
                )],
                backend_defaults=appmesh.BackendDefaults(
                    tls_client_policy=appmesh.TlsClientPolicy(
                        ports=[8080, 8081],
                        validation=appmesh.TlsValidation(
                            trust=appmesh.TlsValidationTrust.acm([
                                acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                            ])
                        )
                    )
                ),
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout"),
                virtual_gateway_name="virtualGateway"
            )
        '''
        if isinstance(backend_defaults, dict):
            backend_defaults = BackendDefaults(**backend_defaults)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualGatewayProps.__init__)
            check_type(argname="argument access_log", value=access_log, expected_type=type_hints["access_log"])
            check_type(argname="argument backend_defaults", value=backend_defaults, expected_type=type_hints["backend_defaults"])
            check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
            check_type(argname="argument virtual_gateway_name", value=virtual_gateway_name, expected_type=type_hints["virtual_gateway_name"])
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
        }
        if access_log is not None:
            self._values["access_log"] = access_log
        if backend_defaults is not None:
            self._values["backend_defaults"] = backend_defaults
        if listeners is not None:
            self._values["listeners"] = listeners
        if virtual_gateway_name is not None:
            self._values["virtual_gateway_name"] = virtual_gateway_name

    @builtins.property
    def access_log(self) -> typing.Optional[AccessLog]:
        '''Access Logging Configuration for the VirtualGateway.

        :default: - no access logging
        '''
        result = self._values.get("access_log")
        return typing.cast(typing.Optional[AccessLog], result)

    @builtins.property
    def backend_defaults(self) -> typing.Optional[BackendDefaults]:
        '''Default Configuration Virtual Node uses to communicate with Virtual Service.

        :default: - No Config
        '''
        result = self._values.get("backend_defaults")
        return typing.cast(typing.Optional[BackendDefaults], result)

    @builtins.property
    def listeners(self) -> typing.Optional[typing.List[VirtualGatewayListener]]:
        '''Listeners for the VirtualGateway.

        Only one is supported.

        :default: - Single HTTP listener on port 8080
        '''
        result = self._values.get("listeners")
        return typing.cast(typing.Optional[typing.List[VirtualGatewayListener]], result)

    @builtins.property
    def virtual_gateway_name(self) -> typing.Optional[builtins.str]:
        '''Name of the VirtualGateway.

        :default: - A name is automatically determined
        '''
        result = self._values.get("virtual_gateway_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualGateway belongs to.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IVirtualNode)
class VirtualNode(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.VirtualNode",
):
    '''VirtualNode represents a newly defined AppMesh VirtualNode.

    Any inbound traffic that your virtual node expects should be specified as a
    listener. Any outbound traffic that your virtual node expects to reach
    should be specified as a backend.

    :see: https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_nodes.html
    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        # Cloud Map service discovery is currently required for host ejection by outlier detection
        vpc = ec2.Vpc(self, "vpc")
        namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
            vpc=vpc,
            name="domain.local"
        )
        service = namespace.create_service("Svc")
        node = mesh.add_virtual_node("virtual-node",
            service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
            listeners=[appmesh.VirtualNodeListener.http(
                outlier_detection=appmesh.OutlierDetection(
                    base_ejection_duration=cdk.Duration.seconds(10),
                    interval=cdk.Duration.seconds(30),
                    max_ejection_percent=50,
                    max_server_errors=5
                )
            )]
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        backends: typing.Optional[typing.Sequence[Backend]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualNodeListener"]] = None,
        service_discovery: typing.Optional[ServiceDiscovery] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param mesh: The Mesh which the VirtualNode belongs to.
        :param access_log: Access Logging Configuration for the virtual node. Default: - No access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param backends: Virtual Services that this is node expected to send outbound traffic to. Default: - No backends
        :param listeners: Initial listener for the virtual node. Default: - No listeners
        :param service_discovery: Defines how upstream clients will discover this VirtualNode. Default: - No Service Discovery
        :param virtual_node_name: The name of the VirtualNode. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNode.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualNodeProps(
            mesh=mesh,
            access_log=access_log,
            backend_defaults=backend_defaults,
            backends=backends,
            listeners=listeners,
            service_discovery=service_discovery,
            virtual_node_name=virtual_node_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromVirtualNodeArn")
    @builtins.classmethod
    def from_virtual_node_arn(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        virtual_node_arn: builtins.str,
    ) -> IVirtualNode:
        '''Import an existing VirtualNode given an ARN.

        :param scope: -
        :param id: -
        :param virtual_node_arn: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNode.from_virtual_node_arn)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument virtual_node_arn", value=virtual_node_arn, expected_type=type_hints["virtual_node_arn"])
        return typing.cast(IVirtualNode, jsii.sinvoke(cls, "fromVirtualNodeArn", [scope, id, virtual_node_arn]))

    @jsii.member(jsii_name="fromVirtualNodeAttributes")
    @builtins.classmethod
    def from_virtual_node_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        virtual_node_name: builtins.str,
    ) -> IVirtualNode:
        '''Import an existing VirtualNode given its name.

        :param scope: -
        :param id: -
        :param mesh: The Mesh that the VirtualNode belongs to.
        :param virtual_node_name: The name of the VirtualNode.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNode.from_virtual_node_attributes)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        attrs = VirtualNodeAttributes(mesh=mesh, virtual_node_name=virtual_node_name)

        return typing.cast(IVirtualNode, jsii.sinvoke(cls, "fromVirtualNodeAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addBackend")
    def add_backend(self, backend: Backend) -> None:
        '''Add a Virtual Services that this node is expected to send outbound traffic to.

        :param backend: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNode.add_backend)
            check_type(argname="argument backend", value=backend, expected_type=type_hints["backend"])
        return typing.cast(None, jsii.invoke(self, "addBackend", [backend]))

    @jsii.member(jsii_name="addListener")
    def add_listener(self, listener: "VirtualNodeListener") -> None:
        '''Utility method to add an inbound listener for this VirtualNode.

        Note: At this time, Virtual Nodes support at most one listener. Adding
        more than one will result in a failure to deploy the CloudFormation stack.
        However, the App Mesh team has plans to add support for multiple listeners
        on Virtual Nodes and Virtual Routers.

        :param listener: -

        :see: https://github.com/aws/aws-app-mesh-roadmap/issues/120
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNode.add_listener)
            check_type(argname="argument listener", value=listener, expected_type=type_hints["listener"])
        return typing.cast(None, jsii.invoke(self, "addListener", [listener]))

    @jsii.member(jsii_name="grantStreamAggregatedResources")
    def grant_stream_aggregated_resources(
        self,
        identity: aws_cdk.aws_iam.IGrantable,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants the given entity ``appmesh:StreamAggregatedResources``.

        :param identity: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNode.grant_stream_aggregated_resources)
            check_type(argname="argument identity", value=identity, expected_type=type_hints["identity"])
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantStreamAggregatedResources", [identity]))

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualNode belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualNodeArn")
    def virtual_node_arn(self) -> builtins.str:
        '''The Amazon Resource Name belonging to the VirtualNode.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualNodeArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualNodeName")
    def virtual_node_name(self) -> builtins.str:
        '''The name of the VirtualNode.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualNodeName"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualNodeAttributes",
    jsii_struct_bases=[],
    name_mapping={"mesh": "mesh", "virtual_node_name": "virtualNodeName"},
)
class VirtualNodeAttributes:
    def __init__(self, *, mesh: IMesh, virtual_node_name: builtins.str) -> None:
        '''Interface with properties necessary to import a reusable VirtualNode.

        :param mesh: The Mesh that the VirtualNode belongs to.
        :param virtual_node_name: The name of the VirtualNode.

        :exampleMetadata: infused

        Example::

            virtual_node_name = "my-virtual-node"
            appmesh.VirtualNode.from_virtual_node_attributes(self, "imported-virtual-node",
                mesh=appmesh.Mesh.from_mesh_name(self, "Mesh", "testMesh"),
                virtual_node_name=virtual_node_name
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNodeAttributes.__init__)
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
            check_type(argname="argument virtual_node_name", value=virtual_node_name, expected_type=type_hints["virtual_node_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
            "virtual_node_name": virtual_node_name,
        }

    @builtins.property
    def mesh(self) -> IMesh:
        '''The Mesh that the VirtualNode belongs to.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    @builtins.property
    def virtual_node_name(self) -> builtins.str:
        '''The name of the VirtualNode.'''
        result = self._values.get("virtual_node_name")
        assert result is not None, "Required property 'virtual_node_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualNodeAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualNodeBaseProps",
    jsii_struct_bases=[],
    name_mapping={
        "access_log": "accessLog",
        "backend_defaults": "backendDefaults",
        "backends": "backends",
        "listeners": "listeners",
        "service_discovery": "serviceDiscovery",
        "virtual_node_name": "virtualNodeName",
    },
)
class VirtualNodeBaseProps:
    def __init__(
        self,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        backends: typing.Optional[typing.Sequence[Backend]] = None,
        listeners: typing.Optional[typing.Sequence["VirtualNodeListener"]] = None,
        service_discovery: typing.Optional[ServiceDiscovery] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Basic configuration properties for a VirtualNode.

        :param access_log: Access Logging Configuration for the virtual node. Default: - No access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param backends: Virtual Services that this is node expected to send outbound traffic to. Default: - No backends
        :param listeners: Initial listener for the virtual node. Default: - No listeners
        :param service_discovery: Defines how upstream clients will discover this VirtualNode. Default: - No Service Discovery
        :param virtual_node_name: The name of the VirtualNode. Default: - A name is automatically determined

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            vpc = ec2.Vpc(self, "vpc")
            namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
                vpc=vpc,
                name="domain.local"
            )
            service = namespace.create_service("Svc")
            node = mesh.add_virtual_node("virtual-node",
                service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=8081,
                    health_check=appmesh.HealthCheck.http(
                        healthy_threshold=3,
                        interval=cdk.Duration.seconds(5),  # minimum
                        path="/health-check-path",
                        timeout=cdk.Duration.seconds(2),  # minimum
                        unhealthy_threshold=2
                    )
                )],
                access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
            )
        '''
        if isinstance(backend_defaults, dict):
            backend_defaults = BackendDefaults(**backend_defaults)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNodeBaseProps.__init__)
            check_type(argname="argument access_log", value=access_log, expected_type=type_hints["access_log"])
            check_type(argname="argument backend_defaults", value=backend_defaults, expected_type=type_hints["backend_defaults"])
            check_type(argname="argument backends", value=backends, expected_type=type_hints["backends"])
            check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
            check_type(argname="argument service_discovery", value=service_discovery, expected_type=type_hints["service_discovery"])
            check_type(argname="argument virtual_node_name", value=virtual_node_name, expected_type=type_hints["virtual_node_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if access_log is not None:
            self._values["access_log"] = access_log
        if backend_defaults is not None:
            self._values["backend_defaults"] = backend_defaults
        if backends is not None:
            self._values["backends"] = backends
        if listeners is not None:
            self._values["listeners"] = listeners
        if service_discovery is not None:
            self._values["service_discovery"] = service_discovery
        if virtual_node_name is not None:
            self._values["virtual_node_name"] = virtual_node_name

    @builtins.property
    def access_log(self) -> typing.Optional[AccessLog]:
        '''Access Logging Configuration for the virtual node.

        :default: - No access logging
        '''
        result = self._values.get("access_log")
        return typing.cast(typing.Optional[AccessLog], result)

    @builtins.property
    def backend_defaults(self) -> typing.Optional[BackendDefaults]:
        '''Default Configuration Virtual Node uses to communicate with Virtual Service.

        :default: - No Config
        '''
        result = self._values.get("backend_defaults")
        return typing.cast(typing.Optional[BackendDefaults], result)

    @builtins.property
    def backends(self) -> typing.Optional[typing.List[Backend]]:
        '''Virtual Services that this is node expected to send outbound traffic to.

        :default: - No backends
        '''
        result = self._values.get("backends")
        return typing.cast(typing.Optional[typing.List[Backend]], result)

    @builtins.property
    def listeners(self) -> typing.Optional[typing.List["VirtualNodeListener"]]:
        '''Initial listener for the virtual node.

        :default: - No listeners
        '''
        result = self._values.get("listeners")
        return typing.cast(typing.Optional[typing.List["VirtualNodeListener"]], result)

    @builtins.property
    def service_discovery(self) -> typing.Optional[ServiceDiscovery]:
        '''Defines how upstream clients will discover this VirtualNode.

        :default: - No Service Discovery
        '''
        result = self._values.get("service_discovery")
        return typing.cast(typing.Optional[ServiceDiscovery], result)

    @builtins.property
    def virtual_node_name(self) -> typing.Optional[builtins.str]:
        '''The name of the VirtualNode.

        :default: - A name is automatically determined
        '''
        result = self._values.get("virtual_node_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualNodeBaseProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class VirtualNodeListener(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.VirtualNodeListener",
):
    '''Defines listener for a VirtualNode.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        vpc = ec2.Vpc(self, "vpc")
        namespace = cloudmap.PrivateDnsNamespace(self, "test-namespace",
            vpc=vpc,
            name="domain.local"
        )
        service = namespace.create_service("Svc")
        node = mesh.add_virtual_node("virtual-node",
            service_discovery=appmesh.ServiceDiscovery.cloud_map(service),
            listeners=[appmesh.VirtualNodeListener.http(
                port=8081,
                health_check=appmesh.HealthCheck.http(
                    healthy_threshold=3,
                    interval=cdk.Duration.seconds(5),  # minimum
                    path="/health-check-path",
                    timeout=cdk.Duration.seconds(2),  # minimum
                    unhealthy_threshold=2
                )
            )],
            access_log=appmesh.AccessLog.from_file_path("/dev/stdout")
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="grpc")
    @builtins.classmethod
    def grpc(
        cls,
        *,
        connection_pool: typing.Optional[typing.Union[GrpcConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        outlier_detection: typing.Optional[typing.Union[OutlierDetection, typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union[GrpcTimeout, typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> "VirtualNodeListener":
        '''Returns an GRPC Listener for a VirtualNode.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for GRPC protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none
        '''
        props = GrpcVirtualNodeListenerOptions(
            connection_pool=connection_pool,
            health_check=health_check,
            outlier_detection=outlier_detection,
            port=port,
            timeout=timeout,
            tls=tls,
        )

        return typing.cast("VirtualNodeListener", jsii.sinvoke(cls, "grpc", [props]))

    @jsii.member(jsii_name="http")
    @builtins.classmethod
    def http(
        cls,
        *,
        connection_pool: typing.Optional[typing.Union[HttpConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        outlier_detection: typing.Optional[typing.Union[OutlierDetection, typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union[HttpTimeout, typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> "VirtualNodeListener":
        '''Returns an HTTP Listener for a VirtualNode.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for HTTP protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none
        '''
        props = HttpVirtualNodeListenerOptions(
            connection_pool=connection_pool,
            health_check=health_check,
            outlier_detection=outlier_detection,
            port=port,
            timeout=timeout,
            tls=tls,
        )

        return typing.cast("VirtualNodeListener", jsii.sinvoke(cls, "http", [props]))

    @jsii.member(jsii_name="http2")
    @builtins.classmethod
    def http2(
        cls,
        *,
        connection_pool: typing.Optional[typing.Union[Http2ConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        outlier_detection: typing.Optional[typing.Union[OutlierDetection, typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union[HttpTimeout, typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> "VirtualNodeListener":
        '''Returns an HTTP2 Listener for a VirtualNode.

        :param connection_pool: Connection pool for http2 listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for HTTP protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none
        '''
        props = Http2VirtualNodeListenerOptions(
            connection_pool=connection_pool,
            health_check=health_check,
            outlier_detection=outlier_detection,
            port=port,
            timeout=timeout,
            tls=tls,
        )

        return typing.cast("VirtualNodeListener", jsii.sinvoke(cls, "http2", [props]))

    @jsii.member(jsii_name="tcp")
    @builtins.classmethod
    def tcp(
        cls,
        *,
        connection_pool: typing.Optional[typing.Union[TcpConnectionPool, typing.Dict[str, typing.Any]]] = None,
        health_check: typing.Optional[HealthCheck] = None,
        outlier_detection: typing.Optional[typing.Union[OutlierDetection, typing.Dict[str, typing.Any]]] = None,
        port: typing.Optional[jsii.Number] = None,
        timeout: typing.Optional[typing.Union[TcpTimeout, typing.Dict[str, typing.Any]]] = None,
        tls: typing.Optional[typing.Union[ListenerTlsOptions, typing.Dict[str, typing.Any]]] = None,
    ) -> "VirtualNodeListener":
        '''Returns an TCP Listener for a VirtualNode.

        :param connection_pool: Connection pool for http listeners. Default: - None
        :param health_check: The health check information for the listener. Default: - no healthcheck
        :param outlier_detection: Represents the configuration for enabling outlier detection. Default: - none
        :param port: Port to listen for connections on. Default: - 8080
        :param timeout: Timeout for TCP protocol. Default: - None
        :param tls: Represents the configuration for enabling TLS on a listener. Default: - none
        '''
        props = TcpVirtualNodeListenerOptions(
            connection_pool=connection_pool,
            health_check=health_check,
            outlier_detection=outlier_detection,
            port=port,
            timeout=timeout,
            tls=tls,
        )

        return typing.cast("VirtualNodeListener", jsii.sinvoke(cls, "tcp", [props]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "VirtualNodeListenerConfig":
        '''Binds the current object when adding Listener to a VirtualNode.

        :param scope: -
        '''
        ...


class _VirtualNodeListenerProxy(VirtualNodeListener):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "VirtualNodeListenerConfig":
        '''Binds the current object when adding Listener to a VirtualNode.

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNodeListener.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("VirtualNodeListenerConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, VirtualNodeListener).__jsii_proxy_class__ = lambda : _VirtualNodeListenerProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualNodeListenerConfig",
    jsii_struct_bases=[],
    name_mapping={"listener": "listener"},
)
class VirtualNodeListenerConfig:
    def __init__(
        self,
        *,
        listener: typing.Union[CfnVirtualNode.ListenerProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''Properties for a VirtualNode listener.

        :param listener: Single listener config for a VirtualNode.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            virtual_node_listener_config = appmesh.VirtualNodeListenerConfig(
                listener=appmesh.CfnVirtualNode.ListenerProperty(
                    port_mapping=appmesh.CfnVirtualNode.PortMappingProperty(
                        port=123,
                        protocol="protocol"
                    ),
            
                    # the properties below are optional
                    connection_pool=appmesh.CfnVirtualNode.VirtualNodeConnectionPoolProperty(
                        grpc=appmesh.CfnVirtualNode.VirtualNodeGrpcConnectionPoolProperty(
                            max_requests=123
                        ),
                        http=appmesh.CfnVirtualNode.VirtualNodeHttpConnectionPoolProperty(
                            max_connections=123,
            
                            # the properties below are optional
                            max_pending_requests=123
                        ),
                        http2=appmesh.CfnVirtualNode.VirtualNodeHttp2ConnectionPoolProperty(
                            max_requests=123
                        ),
                        tcp=appmesh.CfnVirtualNode.VirtualNodeTcpConnectionPoolProperty(
                            max_connections=123
                        )
                    ),
                    health_check=appmesh.CfnVirtualNode.HealthCheckProperty(
                        healthy_threshold=123,
                        interval_millis=123,
                        protocol="protocol",
                        timeout_millis=123,
                        unhealthy_threshold=123,
            
                        # the properties below are optional
                        path="path",
                        port=123
                    ),
                    outlier_detection=appmesh.CfnVirtualNode.OutlierDetectionProperty(
                        base_ejection_duration=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        interval=appmesh.CfnVirtualNode.DurationProperty(
                            unit="unit",
                            value=123
                        ),
                        max_ejection_percent=123,
                        max_server_errors=123
                    ),
                    timeout=appmesh.CfnVirtualNode.ListenerTimeoutProperty(
                        grpc=appmesh.CfnVirtualNode.GrpcTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        http=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        http2=appmesh.CfnVirtualNode.HttpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            ),
                            per_request=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        ),
                        tcp=appmesh.CfnVirtualNode.TcpTimeoutProperty(
                            idle=appmesh.CfnVirtualNode.DurationProperty(
                                unit="unit",
                                value=123
                            )
                        )
                    ),
                    tls=appmesh.CfnVirtualNode.ListenerTlsProperty(
                        certificate=appmesh.CfnVirtualNode.ListenerTlsCertificateProperty(
                            acm=appmesh.CfnVirtualNode.ListenerTlsAcmCertificateProperty(
                                certificate_arn="certificateArn"
                            ),
                            file=appmesh.CfnVirtualNode.ListenerTlsFileCertificateProperty(
                                certificate_chain="certificateChain",
                                private_key="privateKey"
                            ),
                            sds=appmesh.CfnVirtualNode.ListenerTlsSdsCertificateProperty(
                                secret_name="secretName"
                            )
                        ),
                        mode="mode",
            
                        # the properties below are optional
                        validation=appmesh.CfnVirtualNode.ListenerTlsValidationContextProperty(
                            trust=appmesh.CfnVirtualNode.ListenerTlsValidationContextTrustProperty(
                                file=appmesh.CfnVirtualNode.TlsValidationContextFileTrustProperty(
                                    certificate_chain="certificateChain"
                                ),
                                sds=appmesh.CfnVirtualNode.TlsValidationContextSdsTrustProperty(
                                    secret_name="secretName"
                                )
                            ),
            
                            # the properties below are optional
                            subject_alternative_names=appmesh.CfnVirtualNode.SubjectAlternativeNamesProperty(
                                match=appmesh.CfnVirtualNode.SubjectAlternativeNameMatchersProperty(
                                    exact=["exact"]
                                )
                            )
                        )
                    )
                )
            )
        '''
        if isinstance(listener, dict):
            listener = CfnVirtualNode.ListenerProperty(**listener)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNodeListenerConfig.__init__)
            check_type(argname="argument listener", value=listener, expected_type=type_hints["listener"])
        self._values: typing.Dict[str, typing.Any] = {
            "listener": listener,
        }

    @builtins.property
    def listener(self) -> CfnVirtualNode.ListenerProperty:
        '''Single listener config for a VirtualNode.'''
        result = self._values.get("listener")
        assert result is not None, "Required property 'listener' is missing"
        return typing.cast(CfnVirtualNode.ListenerProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualNodeListenerConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualNodeProps",
    jsii_struct_bases=[VirtualNodeBaseProps],
    name_mapping={
        "access_log": "accessLog",
        "backend_defaults": "backendDefaults",
        "backends": "backends",
        "listeners": "listeners",
        "service_discovery": "serviceDiscovery",
        "virtual_node_name": "virtualNodeName",
        "mesh": "mesh",
    },
)
class VirtualNodeProps(VirtualNodeBaseProps):
    def __init__(
        self,
        *,
        access_log: typing.Optional[AccessLog] = None,
        backend_defaults: typing.Optional[typing.Union[BackendDefaults, typing.Dict[str, typing.Any]]] = None,
        backends: typing.Optional[typing.Sequence[Backend]] = None,
        listeners: typing.Optional[typing.Sequence[VirtualNodeListener]] = None,
        service_discovery: typing.Optional[ServiceDiscovery] = None,
        virtual_node_name: typing.Optional[builtins.str] = None,
        mesh: IMesh,
    ) -> None:
        '''The properties used when creating a new VirtualNode.

        :param access_log: Access Logging Configuration for the virtual node. Default: - No access logging
        :param backend_defaults: Default Configuration Virtual Node uses to communicate with Virtual Service. Default: - No Config
        :param backends: Virtual Services that this is node expected to send outbound traffic to. Default: - No backends
        :param listeners: Initial listener for the virtual node. Default: - No listeners
        :param service_discovery: Defines how upstream clients will discover this VirtualNode. Default: - No Service Discovery
        :param virtual_node_name: The name of the VirtualNode. Default: - A name is automatically determined
        :param mesh: The Mesh which the VirtualNode belongs to.

        :exampleMetadata: infused

        Example::

            # A Virtual Node with a gRPC listener with a connection pool set
            # mesh: appmesh.Mesh
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                # DNS service discovery can optionally specify the DNS response type as either LOAD_BALANCER or ENDPOINTS.
                # LOAD_BALANCER means that the DNS resolver returns a loadbalanced set of endpoints,
                # whereas ENDPOINTS means that the DNS resolver is returning all the endpoints.
                # By default, the response type is assumed to be LOAD_BALANCER
                service_discovery=appmesh.ServiceDiscovery.dns("node", appmesh.DnsResponseType.ENDPOINTS),
                listeners=[appmesh.VirtualNodeListener.http(
                    port=80,
                    connection_pool=appmesh.HttpConnectionPool(
                        max_connections=100,
                        max_pending_requests=10
                    )
                )]
            )
            
            # A Virtual Gateway with a gRPC listener with a connection pool set
            gateway = appmesh.VirtualGateway(self, "gateway",
                mesh=mesh,
                listeners=[appmesh.VirtualGatewayListener.grpc(
                    port=8080,
                    connection_pool=appmesh.GrpcConnectionPool(
                        max_requests=10
                    )
                )],
                virtual_gateway_name="gateway"
            )
        '''
        if isinstance(backend_defaults, dict):
            backend_defaults = BackendDefaults(**backend_defaults)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualNodeProps.__init__)
            check_type(argname="argument access_log", value=access_log, expected_type=type_hints["access_log"])
            check_type(argname="argument backend_defaults", value=backend_defaults, expected_type=type_hints["backend_defaults"])
            check_type(argname="argument backends", value=backends, expected_type=type_hints["backends"])
            check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
            check_type(argname="argument service_discovery", value=service_discovery, expected_type=type_hints["service_discovery"])
            check_type(argname="argument virtual_node_name", value=virtual_node_name, expected_type=type_hints["virtual_node_name"])
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
        }
        if access_log is not None:
            self._values["access_log"] = access_log
        if backend_defaults is not None:
            self._values["backend_defaults"] = backend_defaults
        if backends is not None:
            self._values["backends"] = backends
        if listeners is not None:
            self._values["listeners"] = listeners
        if service_discovery is not None:
            self._values["service_discovery"] = service_discovery
        if virtual_node_name is not None:
            self._values["virtual_node_name"] = virtual_node_name

    @builtins.property
    def access_log(self) -> typing.Optional[AccessLog]:
        '''Access Logging Configuration for the virtual node.

        :default: - No access logging
        '''
        result = self._values.get("access_log")
        return typing.cast(typing.Optional[AccessLog], result)

    @builtins.property
    def backend_defaults(self) -> typing.Optional[BackendDefaults]:
        '''Default Configuration Virtual Node uses to communicate with Virtual Service.

        :default: - No Config
        '''
        result = self._values.get("backend_defaults")
        return typing.cast(typing.Optional[BackendDefaults], result)

    @builtins.property
    def backends(self) -> typing.Optional[typing.List[Backend]]:
        '''Virtual Services that this is node expected to send outbound traffic to.

        :default: - No backends
        '''
        result = self._values.get("backends")
        return typing.cast(typing.Optional[typing.List[Backend]], result)

    @builtins.property
    def listeners(self) -> typing.Optional[typing.List[VirtualNodeListener]]:
        '''Initial listener for the virtual node.

        :default: - No listeners
        '''
        result = self._values.get("listeners")
        return typing.cast(typing.Optional[typing.List[VirtualNodeListener]], result)

    @builtins.property
    def service_discovery(self) -> typing.Optional[ServiceDiscovery]:
        '''Defines how upstream clients will discover this VirtualNode.

        :default: - No Service Discovery
        '''
        result = self._values.get("service_discovery")
        return typing.cast(typing.Optional[ServiceDiscovery], result)

    @builtins.property
    def virtual_node_name(self) -> typing.Optional[builtins.str]:
        '''The name of the VirtualNode.

        :default: - A name is automatically determined
        '''
        result = self._values.get("virtual_node_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualNode belongs to.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualNodeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IVirtualRouter)
class VirtualRouter(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.VirtualRouter",
):
    '''
    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        router = mesh.add_virtual_router("router",
            listeners=[appmesh.VirtualRouterListener.http(8080)]
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        listeners: typing.Optional[typing.Sequence["VirtualRouterListener"]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param mesh: The Mesh which the VirtualRouter belongs to.
        :param listeners: Listener specification for the VirtualRouter. Default: - A listener on HTTP port 8080
        :param virtual_router_name: The name of the VirtualRouter. Default: - A name is automatically determined
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouter.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualRouterProps(
            mesh=mesh, listeners=listeners, virtual_router_name=virtual_router_name
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromVirtualRouterArn")
    @builtins.classmethod
    def from_virtual_router_arn(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        virtual_router_arn: builtins.str,
    ) -> IVirtualRouter:
        '''Import an existing VirtualRouter given an ARN.

        :param scope: -
        :param id: -
        :param virtual_router_arn: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouter.from_virtual_router_arn)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument virtual_router_arn", value=virtual_router_arn, expected_type=type_hints["virtual_router_arn"])
        return typing.cast(IVirtualRouter, jsii.sinvoke(cls, "fromVirtualRouterArn", [scope, id, virtual_router_arn]))

    @jsii.member(jsii_name="fromVirtualRouterAttributes")
    @builtins.classmethod
    def from_virtual_router_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        virtual_router_name: builtins.str,
    ) -> IVirtualRouter:
        '''Import an existing VirtualRouter given attributes.

        :param scope: -
        :param id: -
        :param mesh: The Mesh which the VirtualRouter belongs to.
        :param virtual_router_name: The name of the VirtualRouter.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouter.from_virtual_router_attributes)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        attrs = VirtualRouterAttributes(
            mesh=mesh, virtual_router_name=virtual_router_name
        )

        return typing.cast(IVirtualRouter, jsii.sinvoke(cls, "fromVirtualRouterAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addRoute")
    def add_route(
        self,
        id: builtins.str,
        *,
        route_spec: RouteSpec,
        route_name: typing.Optional[builtins.str] = None,
    ) -> Route:
        '''Add a single route to the router.

        :param id: -
        :param route_spec: Protocol specific spec.
        :param route_name: The name of the route. Default: - An automatically generated name
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouter.add_route)
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = RouteBaseProps(route_spec=route_spec, route_name=route_name)

        return typing.cast(Route, jsii.invoke(self, "addRoute", [id, props]))

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualRouter belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualRouterArn")
    def virtual_router_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the VirtualRouter.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualRouterArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualRouterName")
    def virtual_router_name(self) -> builtins.str:
        '''The name of the VirtualRouter.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualRouterName"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualRouterAttributes",
    jsii_struct_bases=[],
    name_mapping={"mesh": "mesh", "virtual_router_name": "virtualRouterName"},
)
class VirtualRouterAttributes:
    def __init__(self, *, mesh: IMesh, virtual_router_name: builtins.str) -> None:
        '''Interface with properties ncecessary to import a reusable VirtualRouter.

        :param mesh: The Mesh which the VirtualRouter belongs to.
        :param virtual_router_name: The name of the VirtualRouter.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # mesh: appmesh.Mesh
            
            virtual_router_attributes = appmesh.VirtualRouterAttributes(
                mesh=mesh,
                virtual_router_name="virtualRouterName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterAttributes.__init__)
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
            check_type(argname="argument virtual_router_name", value=virtual_router_name, expected_type=type_hints["virtual_router_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
            "virtual_router_name": virtual_router_name,
        }

    @builtins.property
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualRouter belongs to.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    @builtins.property
    def virtual_router_name(self) -> builtins.str:
        '''The name of the VirtualRouter.'''
        result = self._values.get("virtual_router_name")
        assert result is not None, "Required property 'virtual_router_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualRouterAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualRouterBaseProps",
    jsii_struct_bases=[],
    name_mapping={
        "listeners": "listeners",
        "virtual_router_name": "virtualRouterName",
    },
)
class VirtualRouterBaseProps:
    def __init__(
        self,
        *,
        listeners: typing.Optional[typing.Sequence["VirtualRouterListener"]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Interface with base properties all routers willl inherit.

        :param listeners: Listener specification for the VirtualRouter. Default: - A listener on HTTP port 8080
        :param virtual_router_name: The name of the VirtualRouter. Default: - A name is automatically determined

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            
            router = mesh.add_virtual_router("router",
                listeners=[appmesh.VirtualRouterListener.http(8080)]
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterBaseProps.__init__)
            check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
            check_type(argname="argument virtual_router_name", value=virtual_router_name, expected_type=type_hints["virtual_router_name"])
        self._values: typing.Dict[str, typing.Any] = {}
        if listeners is not None:
            self._values["listeners"] = listeners
        if virtual_router_name is not None:
            self._values["virtual_router_name"] = virtual_router_name

    @builtins.property
    def listeners(self) -> typing.Optional[typing.List["VirtualRouterListener"]]:
        '''Listener specification for the VirtualRouter.

        :default: - A listener on HTTP port 8080
        '''
        result = self._values.get("listeners")
        return typing.cast(typing.Optional[typing.List["VirtualRouterListener"]], result)

    @builtins.property
    def virtual_router_name(self) -> typing.Optional[builtins.str]:
        '''The name of the VirtualRouter.

        :default: - A name is automatically determined
        '''
        result = self._values.get("virtual_router_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualRouterBaseProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class VirtualRouterListener(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.VirtualRouterListener",
):
    '''Represents the properties needed to define listeners for a VirtualRouter.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        router = mesh.add_virtual_router("router",
            listeners=[appmesh.VirtualRouterListener.http(8080)]
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="grpc")
    @builtins.classmethod
    def grpc(cls, port: typing.Optional[jsii.Number] = None) -> "VirtualRouterListener":
        '''Returns a GRPC Listener for a VirtualRouter.

        :param port: the optional port of the listener, 8080 by default.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterListener.grpc)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
        return typing.cast("VirtualRouterListener", jsii.sinvoke(cls, "grpc", [port]))

    @jsii.member(jsii_name="http")
    @builtins.classmethod
    def http(cls, port: typing.Optional[jsii.Number] = None) -> "VirtualRouterListener":
        '''Returns an HTTP Listener for a VirtualRouter.

        :param port: the optional port of the listener, 8080 by default.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterListener.http)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
        return typing.cast("VirtualRouterListener", jsii.sinvoke(cls, "http", [port]))

    @jsii.member(jsii_name="http2")
    @builtins.classmethod
    def http2(
        cls,
        port: typing.Optional[jsii.Number] = None,
    ) -> "VirtualRouterListener":
        '''Returns an HTTP2 Listener for a VirtualRouter.

        :param port: the optional port of the listener, 8080 by default.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterListener.http2)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
        return typing.cast("VirtualRouterListener", jsii.sinvoke(cls, "http2", [port]))

    @jsii.member(jsii_name="tcp")
    @builtins.classmethod
    def tcp(cls, port: typing.Optional[jsii.Number] = None) -> "VirtualRouterListener":
        '''Returns a TCP Listener for a VirtualRouter.

        :param port: the optional port of the listener, 8080 by default.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterListener.tcp)
            check_type(argname="argument port", value=port, expected_type=type_hints["port"])
        return typing.cast("VirtualRouterListener", jsii.sinvoke(cls, "tcp", [port]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, scope: aws_cdk.core.Construct) -> "VirtualRouterListenerConfig":
        '''Called when the VirtualRouterListener type is initialized.

        Can be used to enforce
        mutual exclusivity

        :param scope: -
        '''
        ...


class _VirtualRouterListenerProxy(VirtualRouterListener):
    @jsii.member(jsii_name="bind")
    def bind(self, scope: aws_cdk.core.Construct) -> "VirtualRouterListenerConfig":
        '''Called when the VirtualRouterListener type is initialized.

        Can be used to enforce
        mutual exclusivity

        :param scope: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterListener.bind)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
        return typing.cast("VirtualRouterListenerConfig", jsii.invoke(self, "bind", [scope]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, VirtualRouterListener).__jsii_proxy_class__ = lambda : _VirtualRouterListenerProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualRouterListenerConfig",
    jsii_struct_bases=[],
    name_mapping={"listener": "listener"},
)
class VirtualRouterListenerConfig:
    def __init__(
        self,
        *,
        listener: typing.Union[CfnVirtualRouter.VirtualRouterListenerProperty, typing.Dict[str, typing.Any]],
    ) -> None:
        '''Properties for a VirtualRouter listener.

        :param listener: Single listener config for a VirtualRouter.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            virtual_router_listener_config = appmesh.VirtualRouterListenerConfig(
                listener=appmesh.CfnVirtualRouter.VirtualRouterListenerProperty(
                    port_mapping=appmesh.CfnVirtualRouter.PortMappingProperty(
                        port=123,
                        protocol="protocol"
                    )
                )
            )
        '''
        if isinstance(listener, dict):
            listener = CfnVirtualRouter.VirtualRouterListenerProperty(**listener)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterListenerConfig.__init__)
            check_type(argname="argument listener", value=listener, expected_type=type_hints["listener"])
        self._values: typing.Dict[str, typing.Any] = {
            "listener": listener,
        }

    @builtins.property
    def listener(self) -> CfnVirtualRouter.VirtualRouterListenerProperty:
        '''Single listener config for a VirtualRouter.'''
        result = self._values.get("listener")
        assert result is not None, "Required property 'listener' is missing"
        return typing.cast(CfnVirtualRouter.VirtualRouterListenerProperty, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualRouterListenerConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualRouterProps",
    jsii_struct_bases=[VirtualRouterBaseProps],
    name_mapping={
        "listeners": "listeners",
        "virtual_router_name": "virtualRouterName",
        "mesh": "mesh",
    },
)
class VirtualRouterProps(VirtualRouterBaseProps):
    def __init__(
        self,
        *,
        listeners: typing.Optional[typing.Sequence[VirtualRouterListener]] = None,
        virtual_router_name: typing.Optional[builtins.str] = None,
        mesh: IMesh,
    ) -> None:
        '''The properties used when creating a new VirtualRouter.

        :param listeners: Listener specification for the VirtualRouter. Default: - A listener on HTTP port 8080
        :param virtual_router_name: The name of the VirtualRouter. Default: - A name is automatically determined
        :param mesh: The Mesh which the VirtualRouter belongs to.

        :exampleMetadata: infused

        Example::

            # infra_stack: cdk.Stack
            # app_stack: cdk.Stack
            
            
            mesh = appmesh.Mesh(infra_stack, "AppMesh",
                mesh_name="myAwsMesh",
                egress_filter=appmesh.MeshFilterType.ALLOW_ALL
            )
            
            # the VirtualRouter will belong to 'appStack',
            # even though the Mesh belongs to 'infraStack'
            router = appmesh.VirtualRouter(app_stack, "router",
                mesh=mesh,  # notice that mesh is a required property when creating a router with the 'new' statement
                listeners=[appmesh.VirtualRouterListener.http(8081)]
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualRouterProps.__init__)
            check_type(argname="argument listeners", value=listeners, expected_type=type_hints["listeners"])
            check_type(argname="argument virtual_router_name", value=virtual_router_name, expected_type=type_hints["virtual_router_name"])
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
        }
        if listeners is not None:
            self._values["listeners"] = listeners
        if virtual_router_name is not None:
            self._values["virtual_router_name"] = virtual_router_name

    @builtins.property
    def listeners(self) -> typing.Optional[typing.List[VirtualRouterListener]]:
        '''Listener specification for the VirtualRouter.

        :default: - A listener on HTTP port 8080
        '''
        result = self._values.get("listeners")
        return typing.cast(typing.Optional[typing.List[VirtualRouterListener]], result)

    @builtins.property
    def virtual_router_name(self) -> typing.Optional[builtins.str]:
        '''The name of the VirtualRouter.

        :default: - A name is automatically determined
        '''
        result = self._values.get("virtual_router_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualRouter belongs to.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualRouterProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IVirtualService)
class VirtualService(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.VirtualService",
):
    '''VirtualService represents a service inside an AppMesh.

    It routes traffic either to a Virtual Node or to a Virtual Router.

    :see: https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_services.html
    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node")
        )
        
        virtual_service = appmesh.VirtualService(self, "service-1",
            virtual_service_provider=appmesh.VirtualServiceProvider.virtual_node(node),
            virtual_service_name="service1.domain.local"
        )
        
        node.add_backend(appmesh.Backend.virtual_service(virtual_service))
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        virtual_service_provider: "VirtualServiceProvider",
        virtual_service_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param virtual_service_provider: The VirtualNode or VirtualRouter which the VirtualService uses as its provider.
        :param virtual_service_name: The name of the VirtualService. It is recommended this follows the fully-qualified domain name format, such as "my-service.default.svc.cluster.local". Example value: ``service.domain.local`` Default: - A name is automatically generated
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualService.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = VirtualServiceProps(
            virtual_service_provider=virtual_service_provider,
            virtual_service_name=virtual_service_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromVirtualServiceArn")
    @builtins.classmethod
    def from_virtual_service_arn(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        virtual_service_arn: builtins.str,
    ) -> IVirtualService:
        '''Import an existing VirtualService given an ARN.

        :param scope: -
        :param id: -
        :param virtual_service_arn: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualService.from_virtual_service_arn)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument virtual_service_arn", value=virtual_service_arn, expected_type=type_hints["virtual_service_arn"])
        return typing.cast(IVirtualService, jsii.sinvoke(cls, "fromVirtualServiceArn", [scope, id, virtual_service_arn]))

    @jsii.member(jsii_name="fromVirtualServiceAttributes")
    @builtins.classmethod
    def from_virtual_service_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        mesh: IMesh,
        virtual_service_name: builtins.str,
    ) -> IVirtualService:
        '''Import an existing VirtualService given its attributes.

        :param scope: -
        :param id: -
        :param mesh: The Mesh which the VirtualService belongs to.
        :param virtual_service_name: The name of the VirtualService, it is recommended this follows the fully-qualified domain name format.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualService.from_virtual_service_attributes)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        attrs = VirtualServiceAttributes(
            mesh=mesh, virtual_service_name=virtual_service_name
        )

        return typing.cast(IVirtualService, jsii.sinvoke(cls, "fromVirtualServiceAttributes", [scope, id, attrs]))

    @builtins.property
    @jsii.member(jsii_name="mesh")
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualService belongs to.'''
        return typing.cast(IMesh, jsii.get(self, "mesh"))

    @builtins.property
    @jsii.member(jsii_name="virtualServiceArn")
    def virtual_service_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the virtual service.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualServiceArn"))

    @builtins.property
    @jsii.member(jsii_name="virtualServiceName")
    def virtual_service_name(self) -> builtins.str:
        '''The name of the VirtualService, it is recommended this follows the fully-qualified domain name format.'''
        return typing.cast(builtins.str, jsii.get(self, "virtualServiceName"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualServiceAttributes",
    jsii_struct_bases=[],
    name_mapping={"mesh": "mesh", "virtual_service_name": "virtualServiceName"},
)
class VirtualServiceAttributes:
    def __init__(self, *, mesh: IMesh, virtual_service_name: builtins.str) -> None:
        '''Interface with properties ncecessary to import a reusable VirtualService.

        :param mesh: The Mesh which the VirtualService belongs to.
        :param virtual_service_name: The name of the VirtualService, it is recommended this follows the fully-qualified domain name format.

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # mesh: appmesh.Mesh
            
            virtual_service_attributes = appmesh.VirtualServiceAttributes(
                mesh=mesh,
                virtual_service_name="virtualServiceName"
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceAttributes.__init__)
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
            check_type(argname="argument virtual_service_name", value=virtual_service_name, expected_type=type_hints["virtual_service_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
            "virtual_service_name": virtual_service_name,
        }

    @builtins.property
    def mesh(self) -> IMesh:
        '''The Mesh which the VirtualService belongs to.'''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    @builtins.property
    def virtual_service_name(self) -> builtins.str:
        '''The name of the VirtualService, it is recommended this follows the fully-qualified domain name format.'''
        result = self._values.get("virtual_service_name")
        assert result is not None, "Required property 'virtual_service_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualServiceAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualServiceBackendOptions",
    jsii_struct_bases=[],
    name_mapping={"tls_client_policy": "tlsClientPolicy"},
)
class VirtualServiceBackendOptions:
    def __init__(
        self,
        *,
        tls_client_policy: typing.Optional[typing.Union[TlsClientPolicy, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Represents the properties needed to define a Virtual Service backend.

        :param tls_client_policy: TLS properties for Client policy for the backend. Default: - none

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # mutual_tls_certificate: appmesh.MutualTlsCertificate
            # subject_alternative_names: appmesh.SubjectAlternativeNames
            # tls_validation_trust: appmesh.TlsValidationTrust
            
            virtual_service_backend_options = appmesh.VirtualServiceBackendOptions(
                tls_client_policy=appmesh.TlsClientPolicy(
                    validation=appmesh.TlsValidation(
                        trust=tls_validation_trust,
            
                        # the properties below are optional
                        subject_alternative_names=subject_alternative_names
                    ),
            
                    # the properties below are optional
                    enforce=False,
                    mutual_tls_certificate=mutual_tls_certificate,
                    ports=[123]
                )
            )
        '''
        if isinstance(tls_client_policy, dict):
            tls_client_policy = TlsClientPolicy(**tls_client_policy)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceBackendOptions.__init__)
            check_type(argname="argument tls_client_policy", value=tls_client_policy, expected_type=type_hints["tls_client_policy"])
        self._values: typing.Dict[str, typing.Any] = {}
        if tls_client_policy is not None:
            self._values["tls_client_policy"] = tls_client_policy

    @builtins.property
    def tls_client_policy(self) -> typing.Optional[TlsClientPolicy]:
        '''TLS properties for  Client policy for the backend.

        :default: - none
        '''
        result = self._values.get("tls_client_policy")
        return typing.cast(typing.Optional[TlsClientPolicy], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualServiceBackendOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualServiceProps",
    jsii_struct_bases=[],
    name_mapping={
        "virtual_service_provider": "virtualServiceProvider",
        "virtual_service_name": "virtualServiceName",
    },
)
class VirtualServiceProps:
    def __init__(
        self,
        *,
        virtual_service_provider: "VirtualServiceProvider",
        virtual_service_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''The properties applied to the VirtualService being defined.

        :param virtual_service_provider: The VirtualNode or VirtualRouter which the VirtualService uses as its provider.
        :param virtual_service_name: The name of the VirtualService. It is recommended this follows the fully-qualified domain name format, such as "my-service.default.svc.cluster.local". Example value: ``service.domain.local`` Default: - A name is automatically generated

        :exampleMetadata: infused

        Example::

            # mesh: appmesh.Mesh
            
            
            node = appmesh.VirtualNode(self, "node",
                mesh=mesh,
                service_discovery=appmesh.ServiceDiscovery.dns("node")
            )
            
            virtual_service = appmesh.VirtualService(self, "service-1",
                virtual_service_provider=appmesh.VirtualServiceProvider.virtual_node(node),
                virtual_service_name="service1.domain.local"
            )
            
            node.add_backend(appmesh.Backend.virtual_service(virtual_service))
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceProps.__init__)
            check_type(argname="argument virtual_service_provider", value=virtual_service_provider, expected_type=type_hints["virtual_service_provider"])
            check_type(argname="argument virtual_service_name", value=virtual_service_name, expected_type=type_hints["virtual_service_name"])
        self._values: typing.Dict[str, typing.Any] = {
            "virtual_service_provider": virtual_service_provider,
        }
        if virtual_service_name is not None:
            self._values["virtual_service_name"] = virtual_service_name

    @builtins.property
    def virtual_service_provider(self) -> "VirtualServiceProvider":
        '''The VirtualNode or VirtualRouter which the VirtualService uses as its provider.'''
        result = self._values.get("virtual_service_provider")
        assert result is not None, "Required property 'virtual_service_provider' is missing"
        return typing.cast("VirtualServiceProvider", result)

    @builtins.property
    def virtual_service_name(self) -> typing.Optional[builtins.str]:
        '''The name of the VirtualService.

        It is recommended this follows the fully-qualified domain name format,
        such as "my-service.default.svc.cluster.local".

        Example value: ``service.domain.local``

        :default: - A name is automatically generated
        '''
        result = self._values.get("virtual_service_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualServiceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class VirtualServiceProvider(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.VirtualServiceProvider",
):
    '''Represents the properties needed to define the provider for a VirtualService.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        
        node = appmesh.VirtualNode(self, "node",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node")
        )
        
        virtual_service = appmesh.VirtualService(self, "service-1",
            virtual_service_provider=appmesh.VirtualServiceProvider.virtual_node(node),
            virtual_service_name="service1.domain.local"
        )
        
        node.add_backend(appmesh.Backend.virtual_service(virtual_service))
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="none")
    @builtins.classmethod
    def none(cls, mesh: IMesh) -> "VirtualServiceProvider":
        '''Returns an Empty Provider for a VirtualService.

        This provides no routing capabilities
        and should only be used as a placeholder

        :param mesh: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceProvider.none)
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
        return typing.cast("VirtualServiceProvider", jsii.sinvoke(cls, "none", [mesh]))

    @jsii.member(jsii_name="virtualNode")
    @builtins.classmethod
    def virtual_node(cls, virtual_node: IVirtualNode) -> "VirtualServiceProvider":
        '''Returns a VirtualNode based Provider for a VirtualService.

        :param virtual_node: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceProvider.virtual_node)
            check_type(argname="argument virtual_node", value=virtual_node, expected_type=type_hints["virtual_node"])
        return typing.cast("VirtualServiceProvider", jsii.sinvoke(cls, "virtualNode", [virtual_node]))

    @jsii.member(jsii_name="virtualRouter")
    @builtins.classmethod
    def virtual_router(cls, virtual_router: IVirtualRouter) -> "VirtualServiceProvider":
        '''Returns a VirtualRouter based Provider for a VirtualService.

        :param virtual_router: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceProvider.virtual_router)
            check_type(argname="argument virtual_router", value=virtual_router, expected_type=type_hints["virtual_router"])
        return typing.cast("VirtualServiceProvider", jsii.sinvoke(cls, "virtualRouter", [virtual_router]))

    @jsii.member(jsii_name="bind")
    @abc.abstractmethod
    def bind(self, _construct: constructs.Construct) -> "VirtualServiceProviderConfig":
        '''Enforces mutual exclusivity for VirtualService provider types.

        :param _construct: -
        '''
        ...


class _VirtualServiceProviderProxy(VirtualServiceProvider):
    @jsii.member(jsii_name="bind")
    def bind(self, _construct: constructs.Construct) -> "VirtualServiceProviderConfig":
        '''Enforces mutual exclusivity for VirtualService provider types.

        :param _construct: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceProvider.bind)
            check_type(argname="argument _construct", value=_construct, expected_type=type_hints["_construct"])
        return typing.cast("VirtualServiceProviderConfig", jsii.invoke(self, "bind", [_construct]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, VirtualServiceProvider).__jsii_proxy_class__ = lambda : _VirtualServiceProviderProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.VirtualServiceProviderConfig",
    jsii_struct_bases=[],
    name_mapping={
        "mesh": "mesh",
        "virtual_node_provider": "virtualNodeProvider",
        "virtual_router_provider": "virtualRouterProvider",
    },
)
class VirtualServiceProviderConfig:
    def __init__(
        self,
        *,
        mesh: IMesh,
        virtual_node_provider: typing.Optional[typing.Union[CfnVirtualService.VirtualNodeServiceProviderProperty, typing.Dict[str, typing.Any]]] = None,
        virtual_router_provider: typing.Optional[typing.Union[CfnVirtualService.VirtualRouterServiceProviderProperty, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Properties for a VirtualService provider.

        :param mesh: Mesh the Provider is using. Default: - none
        :param virtual_node_provider: Virtual Node based provider. Default: - none
        :param virtual_router_provider: Virtual Router based provider. Default: - none

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # mesh: appmesh.Mesh
            
            virtual_service_provider_config = appmesh.VirtualServiceProviderConfig(
                mesh=mesh,
            
                # the properties below are optional
                virtual_node_provider=appmesh.CfnVirtualService.VirtualNodeServiceProviderProperty(
                    virtual_node_name="virtualNodeName"
                ),
                virtual_router_provider=appmesh.CfnVirtualService.VirtualRouterServiceProviderProperty(
                    virtual_router_name="virtualRouterName"
                )
            )
        '''
        if isinstance(virtual_node_provider, dict):
            virtual_node_provider = CfnVirtualService.VirtualNodeServiceProviderProperty(**virtual_node_provider)
        if isinstance(virtual_router_provider, dict):
            virtual_router_provider = CfnVirtualService.VirtualRouterServiceProviderProperty(**virtual_router_provider)
        if __debug__:
            type_hints = typing.get_type_hints(VirtualServiceProviderConfig.__init__)
            check_type(argname="argument mesh", value=mesh, expected_type=type_hints["mesh"])
            check_type(argname="argument virtual_node_provider", value=virtual_node_provider, expected_type=type_hints["virtual_node_provider"])
            check_type(argname="argument virtual_router_provider", value=virtual_router_provider, expected_type=type_hints["virtual_router_provider"])
        self._values: typing.Dict[str, typing.Any] = {
            "mesh": mesh,
        }
        if virtual_node_provider is not None:
            self._values["virtual_node_provider"] = virtual_node_provider
        if virtual_router_provider is not None:
            self._values["virtual_router_provider"] = virtual_router_provider

    @builtins.property
    def mesh(self) -> IMesh:
        '''Mesh the Provider is using.

        :default: - none
        '''
        result = self._values.get("mesh")
        assert result is not None, "Required property 'mesh' is missing"
        return typing.cast(IMesh, result)

    @builtins.property
    def virtual_node_provider(
        self,
    ) -> typing.Optional[CfnVirtualService.VirtualNodeServiceProviderProperty]:
        '''Virtual Node based provider.

        :default: - none
        '''
        result = self._values.get("virtual_node_provider")
        return typing.cast(typing.Optional[CfnVirtualService.VirtualNodeServiceProviderProperty], result)

    @builtins.property
    def virtual_router_provider(
        self,
    ) -> typing.Optional[CfnVirtualService.VirtualRouterServiceProviderProperty]:
        '''Virtual Router based provider.

        :default: - none
        '''
        result = self._values.get("virtual_router_provider")
        return typing.cast(typing.Optional[CfnVirtualService.VirtualRouterServiceProviderProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VirtualServiceProviderConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.WeightedTarget",
    jsii_struct_bases=[],
    name_mapping={"virtual_node": "virtualNode", "weight": "weight"},
)
class WeightedTarget:
    def __init__(
        self,
        *,
        virtual_node: IVirtualNode,
        weight: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties for the Weighted Targets in the route.

        :param virtual_node: The VirtualNode the route points to.
        :param weight: The weight for the target. Default: 1

        :exampleMetadata: fixture=_generated

        Example::

            # The code below shows an example of how to instantiate this type.
            # The values are placeholders you should change.
            import aws_cdk.aws_appmesh as appmesh
            
            # virtual_node: appmesh.VirtualNode
            
            weighted_target = appmesh.WeightedTarget(
                virtual_node=virtual_node,
            
                # the properties below are optional
                weight=123
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(WeightedTarget.__init__)
            check_type(argname="argument virtual_node", value=virtual_node, expected_type=type_hints["virtual_node"])
            check_type(argname="argument weight", value=weight, expected_type=type_hints["weight"])
        self._values: typing.Dict[str, typing.Any] = {
            "virtual_node": virtual_node,
        }
        if weight is not None:
            self._values["weight"] = weight

    @builtins.property
    def virtual_node(self) -> IVirtualNode:
        '''The VirtualNode the route points to.'''
        result = self._values.get("virtual_node")
        assert result is not None, "Required property 'virtual_node' is missing"
        return typing.cast(IVirtualNode, result)

    @builtins.property
    def weight(self) -> typing.Optional[jsii.Number]:
        '''The weight for the target.

        :default: 1
        '''
        result = self._values.get("weight")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "WeightedTarget(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IGatewayRoute)
class GatewayRoute(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-appmesh.GatewayRoute",
):
    '''GatewayRoute represents a new or existing gateway route attached to a VirtualGateway and Mesh.

    :see: https://docs.aws.amazon.com/app-mesh/latest/userguide/gateway-routes.html
    :exampleMetadata: fixture=_generated

    Example::

        # The code below shows an example of how to instantiate this type.
        # The values are placeholders you should change.
        import aws_cdk.aws_appmesh as appmesh
        
        # gateway_route_spec: appmesh.GatewayRouteSpec
        # virtual_gateway: appmesh.VirtualGateway
        
        gateway_route = appmesh.GatewayRoute(self, "MyGatewayRoute",
            route_spec=gateway_route_spec,
            virtual_gateway=virtual_gateway,
        
            # the properties below are optional
            gateway_route_name="gatewayRouteName"
        )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        virtual_gateway: IVirtualGateway,
        route_spec: GatewayRouteSpec,
        gateway_route_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param virtual_gateway: The VirtualGateway this GatewayRoute is associated with.
        :param route_spec: What protocol the route uses.
        :param gateway_route_name: The name of the GatewayRoute. Default: - an automatically generated name
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRoute.__init__)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        props = GatewayRouteProps(
            virtual_gateway=virtual_gateway,
            route_spec=route_spec,
            gateway_route_name=gateway_route_name,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromGatewayRouteArn")
    @builtins.classmethod
    def from_gateway_route_arn(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        gateway_route_arn: builtins.str,
    ) -> IGatewayRoute:
        '''Import an existing GatewayRoute given an ARN.

        :param scope: -
        :param id: -
        :param gateway_route_arn: -
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRoute.from_gateway_route_arn)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
            check_type(argname="argument gateway_route_arn", value=gateway_route_arn, expected_type=type_hints["gateway_route_arn"])
        return typing.cast(IGatewayRoute, jsii.sinvoke(cls, "fromGatewayRouteArn", [scope, id, gateway_route_arn]))

    @jsii.member(jsii_name="fromGatewayRouteAttributes")
    @builtins.classmethod
    def from_gateway_route_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        gateway_route_name: builtins.str,
        virtual_gateway: IVirtualGateway,
    ) -> IGatewayRoute:
        '''Import an existing GatewayRoute given attributes.

        :param scope: -
        :param id: -
        :param gateway_route_name: The name of the GatewayRoute.
        :param virtual_gateway: The VirtualGateway this GatewayRoute is associated with.
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GatewayRoute.from_gateway_route_attributes)
            check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
            check_type(argname="argument id", value=id, expected_type=type_hints["id"])
        attrs = GatewayRouteAttributes(
            gateway_route_name=gateway_route_name, virtual_gateway=virtual_gateway
        )

        return typing.cast(IGatewayRoute, jsii.sinvoke(cls, "fromGatewayRouteAttributes", [scope, id, attrs]))

    @builtins.property
    @jsii.member(jsii_name="gatewayRouteArn")
    def gateway_route_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) for the GatewayRoute.'''
        return typing.cast(builtins.str, jsii.get(self, "gatewayRouteArn"))

    @builtins.property
    @jsii.member(jsii_name="gatewayRouteName")
    def gateway_route_name(self) -> builtins.str:
        '''The name of the GatewayRoute.'''
        return typing.cast(builtins.str, jsii.get(self, "gatewayRouteName"))

    @builtins.property
    @jsii.member(jsii_name="virtualGateway")
    def virtual_gateway(self) -> IVirtualGateway:
        '''The VirtualGateway this GatewayRoute is a part of.'''
        return typing.cast(IVirtualGateway, jsii.get(self, "virtualGateway"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcRetryPolicy",
    jsii_struct_bases=[HttpRetryPolicy],
    name_mapping={
        "retry_attempts": "retryAttempts",
        "retry_timeout": "retryTimeout",
        "http_retry_events": "httpRetryEvents",
        "tcp_retry_events": "tcpRetryEvents",
        "grpc_retry_events": "grpcRetryEvents",
    },
)
class GrpcRetryPolicy(HttpRetryPolicy):
    def __init__(
        self,
        *,
        retry_attempts: jsii.Number,
        retry_timeout: aws_cdk.core.Duration,
        http_retry_events: typing.Optional[typing.Sequence[HttpRetryEvent]] = None,
        tcp_retry_events: typing.Optional[typing.Sequence[TcpRetryEvent]] = None,
        grpc_retry_events: typing.Optional[typing.Sequence[GrpcRetryEvent]] = None,
    ) -> None:
        '''gRPC retry policy.

        :param retry_attempts: The maximum number of retry attempts.
        :param retry_timeout: The timeout for each retry attempt.
        :param http_retry_events: Specify HTTP events on which to retry. You must specify at least one value for at least one types of retry events. Default: - no retries for http events
        :param tcp_retry_events: TCP events on which to retry. The event occurs before any processing of a request has started and is encountered when the upstream is temporarily or permanently unavailable. You must specify at least one value for at least one types of retry events. Default: - no retries for tcp events
        :param grpc_retry_events: gRPC events on which to retry. You must specify at least one value for at least one types of retry events. Default: - no retries for gRPC events

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-grpc-retry",
                route_spec=appmesh.RouteSpec.grpc(
                    weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                    match=appmesh.GrpcRouteMatch(service_name="servicename"),
                    retry_policy=appmesh.GrpcRetryPolicy(
                        tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                        http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                        # Retry if gRPC responds that the request was cancelled, a resource
                        # was exhausted, or if the service is unavailable
                        grpc_retry_events=[appmesh.GrpcRetryEvent.CANCELLED, appmesh.GrpcRetryEvent.RESOURCE_EXHAUSTED, appmesh.GrpcRetryEvent.UNAVAILABLE
                        ],
                        retry_attempts=5,
                        retry_timeout=cdk.Duration.seconds(1)
                    )
                )
            )
        '''
        if __debug__:
            type_hints = typing.get_type_hints(GrpcRetryPolicy.__init__)
            check_type(argname="argument retry_attempts", value=retry_attempts, expected_type=type_hints["retry_attempts"])
            check_type(argname="argument retry_timeout", value=retry_timeout, expected_type=type_hints["retry_timeout"])
            check_type(argname="argument http_retry_events", value=http_retry_events, expected_type=type_hints["http_retry_events"])
            check_type(argname="argument tcp_retry_events", value=tcp_retry_events, expected_type=type_hints["tcp_retry_events"])
            check_type(argname="argument grpc_retry_events", value=grpc_retry_events, expected_type=type_hints["grpc_retry_events"])
        self._values: typing.Dict[str, typing.Any] = {
            "retry_attempts": retry_attempts,
            "retry_timeout": retry_timeout,
        }
        if http_retry_events is not None:
            self._values["http_retry_events"] = http_retry_events
        if tcp_retry_events is not None:
            self._values["tcp_retry_events"] = tcp_retry_events
        if grpc_retry_events is not None:
            self._values["grpc_retry_events"] = grpc_retry_events

    @builtins.property
    def retry_attempts(self) -> jsii.Number:
        '''The maximum number of retry attempts.'''
        result = self._values.get("retry_attempts")
        assert result is not None, "Required property 'retry_attempts' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def retry_timeout(self) -> aws_cdk.core.Duration:
        '''The timeout for each retry attempt.'''
        result = self._values.get("retry_timeout")
        assert result is not None, "Required property 'retry_timeout' is missing"
        return typing.cast(aws_cdk.core.Duration, result)

    @builtins.property
    def http_retry_events(self) -> typing.Optional[typing.List[HttpRetryEvent]]:
        '''Specify HTTP events on which to retry.

        You must specify at least one value
        for at least one types of retry events.

        :default: - no retries for http events
        '''
        result = self._values.get("http_retry_events")
        return typing.cast(typing.Optional[typing.List[HttpRetryEvent]], result)

    @builtins.property
    def tcp_retry_events(self) -> typing.Optional[typing.List[TcpRetryEvent]]:
        '''TCP events on which to retry.

        The event occurs before any processing of a
        request has started and is encountered when the upstream is temporarily or
        permanently unavailable. You must specify at least one value for at least
        one types of retry events.

        :default: - no retries for tcp events
        '''
        result = self._values.get("tcp_retry_events")
        return typing.cast(typing.Optional[typing.List[TcpRetryEvent]], result)

    @builtins.property
    def grpc_retry_events(self) -> typing.Optional[typing.List[GrpcRetryEvent]]:
        '''gRPC events on which to retry.

        You must specify at least one value
        for at least one types of retry events.

        :default: - no retries for gRPC events
        '''
        result = self._values.get("grpc_retry_events")
        return typing.cast(typing.Optional[typing.List[GrpcRetryEvent]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcRetryPolicy(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.GrpcRouteSpecOptions",
    jsii_struct_bases=[RouteSpecOptionsBase],
    name_mapping={
        "priority": "priority",
        "match": "match",
        "weighted_targets": "weightedTargets",
        "retry_policy": "retryPolicy",
        "timeout": "timeout",
    },
)
class GrpcRouteSpecOptions(RouteSpecOptionsBase):
    def __init__(
        self,
        *,
        priority: typing.Optional[jsii.Number] = None,
        match: typing.Union[GrpcRouteMatch, typing.Dict[str, typing.Any]],
        weighted_targets: typing.Sequence[typing.Union[WeightedTarget, typing.Dict[str, typing.Any]]],
        retry_policy: typing.Optional[typing.Union[GrpcRetryPolicy, typing.Dict[str, typing.Any]]] = None,
        timeout: typing.Optional[typing.Union[GrpcTimeout, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Properties specific for a GRPC Based Routes.

        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        :param match: The criterion for determining a request match for this Route.
        :param weighted_targets: List of targets that traffic is routed to when a request matches the route.
        :param retry_policy: The retry policy. Default: - no retry policy
        :param timeout: An object that represents a grpc timeout. Default: - None

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-http",
                route_spec=appmesh.RouteSpec.grpc(
                    weighted_targets=[appmesh.WeightedTarget(
                        virtual_node=node
                    )
                    ],
                    match=appmesh.GrpcRouteMatch(
                        service_name="my-service.default.svc.cluster.local"
                    ),
                    timeout=appmesh.GrpcTimeout(
                        idle=cdk.Duration.seconds(2),
                        per_request=cdk.Duration.seconds(1)
                    )
                )
            )
        '''
        if isinstance(match, dict):
            match = GrpcRouteMatch(**match)
        if isinstance(retry_policy, dict):
            retry_policy = GrpcRetryPolicy(**retry_policy)
        if isinstance(timeout, dict):
            timeout = GrpcTimeout(**timeout)
        if __debug__:
            type_hints = typing.get_type_hints(GrpcRouteSpecOptions.__init__)
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            check_type(argname="argument weighted_targets", value=weighted_targets, expected_type=type_hints["weighted_targets"])
            check_type(argname="argument retry_policy", value=retry_policy, expected_type=type_hints["retry_policy"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
        self._values: typing.Dict[str, typing.Any] = {
            "match": match,
            "weighted_targets": weighted_targets,
        }
        if priority is not None:
            self._values["priority"] = priority
        if retry_policy is not None:
            self._values["retry_policy"] = retry_policy
        if timeout is not None:
            self._values["timeout"] = timeout

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the route.

        When a Virtual Router has multiple routes, route match is performed in the
        order of specified value, where 0 is the highest priority, and first matched route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def match(self) -> GrpcRouteMatch:
        '''The criterion for determining a request match for this Route.'''
        result = self._values.get("match")
        assert result is not None, "Required property 'match' is missing"
        return typing.cast(GrpcRouteMatch, result)

    @builtins.property
    def weighted_targets(self) -> typing.List[WeightedTarget]:
        '''List of targets that traffic is routed to when a request matches the route.'''
        result = self._values.get("weighted_targets")
        assert result is not None, "Required property 'weighted_targets' is missing"
        return typing.cast(typing.List[WeightedTarget], result)

    @builtins.property
    def retry_policy(self) -> typing.Optional[GrpcRetryPolicy]:
        '''The retry policy.

        :default: - no retry policy
        '''
        result = self._values.get("retry_policy")
        return typing.cast(typing.Optional[GrpcRetryPolicy], result)

    @builtins.property
    def timeout(self) -> typing.Optional[GrpcTimeout]:
        '''An object that represents a grpc timeout.

        :default: - None
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[GrpcTimeout], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GrpcRouteSpecOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-appmesh.HttpRouteSpecOptions",
    jsii_struct_bases=[RouteSpecOptionsBase],
    name_mapping={
        "priority": "priority",
        "weighted_targets": "weightedTargets",
        "match": "match",
        "retry_policy": "retryPolicy",
        "timeout": "timeout",
    },
)
class HttpRouteSpecOptions(RouteSpecOptionsBase):
    def __init__(
        self,
        *,
        priority: typing.Optional[jsii.Number] = None,
        weighted_targets: typing.Sequence[typing.Union[WeightedTarget, typing.Dict[str, typing.Any]]],
        match: typing.Optional[typing.Union[HttpRouteMatch, typing.Dict[str, typing.Any]]] = None,
        retry_policy: typing.Optional[typing.Union[HttpRetryPolicy, typing.Dict[str, typing.Any]]] = None,
        timeout: typing.Optional[typing.Union[HttpTimeout, typing.Dict[str, typing.Any]]] = None,
    ) -> None:
        '''Properties specific for HTTP Based Routes.

        :param priority: The priority for the route. When a Virtual Router has multiple routes, route match is performed in the order of specified value, where 0 is the highest priority, and first matched route is selected. Default: - no particular priority
        :param weighted_targets: List of targets that traffic is routed to when a request matches the route.
        :param match: The criterion for determining a request match for this Route. Default: - matches on '/'
        :param retry_policy: The retry policy. Default: - no retry policy
        :param timeout: An object that represents a http timeout. Default: - None

        :exampleMetadata: infused

        Example::

            # router: appmesh.VirtualRouter
            # node: appmesh.VirtualNode
            
            
            router.add_route("route-http2-retry",
                route_spec=appmesh.RouteSpec.http2(
                    weighted_targets=[appmesh.WeightedTarget(virtual_node=node)],
                    retry_policy=appmesh.HttpRetryPolicy(
                        # Retry if the connection failed
                        tcp_retry_events=[appmesh.TcpRetryEvent.CONNECTION_ERROR],
                        # Retry if HTTP responds with a gateway error (502, 503, 504)
                        http_retry_events=[appmesh.HttpRetryEvent.GATEWAY_ERROR],
                        # Retry five times
                        retry_attempts=5,
                        # Use a 1 second timeout per retry
                        retry_timeout=cdk.Duration.seconds(1)
                    )
                )
            )
        '''
        if isinstance(match, dict):
            match = HttpRouteMatch(**match)
        if isinstance(retry_policy, dict):
            retry_policy = HttpRetryPolicy(**retry_policy)
        if isinstance(timeout, dict):
            timeout = HttpTimeout(**timeout)
        if __debug__:
            type_hints = typing.get_type_hints(HttpRouteSpecOptions.__init__)
            check_type(argname="argument priority", value=priority, expected_type=type_hints["priority"])
            check_type(argname="argument weighted_targets", value=weighted_targets, expected_type=type_hints["weighted_targets"])
            check_type(argname="argument match", value=match, expected_type=type_hints["match"])
            check_type(argname="argument retry_policy", value=retry_policy, expected_type=type_hints["retry_policy"])
            check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
        self._values: typing.Dict[str, typing.Any] = {
            "weighted_targets": weighted_targets,
        }
        if priority is not None:
            self._values["priority"] = priority
        if match is not None:
            self._values["match"] = match
        if retry_policy is not None:
            self._values["retry_policy"] = retry_policy
        if timeout is not None:
            self._values["timeout"] = timeout

    @builtins.property
    def priority(self) -> typing.Optional[jsii.Number]:
        '''The priority for the route.

        When a Virtual Router has multiple routes, route match is performed in the
        order of specified value, where 0 is the highest priority, and first matched route is selected.

        :default: - no particular priority
        '''
        result = self._values.get("priority")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def weighted_targets(self) -> typing.List[WeightedTarget]:
        '''List of targets that traffic is routed to when a request matches the route.'''
        result = self._values.get("weighted_targets")
        assert result is not None, "Required property 'weighted_targets' is missing"
        return typing.cast(typing.List[WeightedTarget], result)

    @builtins.property
    def match(self) -> typing.Optional[HttpRouteMatch]:
        '''The criterion for determining a request match for this Route.

        :default: - matches on '/'
        '''
        result = self._values.get("match")
        return typing.cast(typing.Optional[HttpRouteMatch], result)

    @builtins.property
    def retry_policy(self) -> typing.Optional[HttpRetryPolicy]:
        '''The retry policy.

        :default: - no retry policy
        '''
        result = self._values.get("retry_policy")
        return typing.cast(typing.Optional[HttpRetryPolicy], result)

    @builtins.property
    def timeout(self) -> typing.Optional[HttpTimeout]:
        '''An object that represents a http timeout.

        :default: - None
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[HttpTimeout], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "HttpRouteSpecOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class MutualTlsCertificate(
    TlsCertificate,
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.MutualTlsCertificate",
):
    '''Represents a TLS certificate that is supported for mutual TLS authentication.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        
        node1 = appmesh.VirtualNode(self, "node1",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node"),
            listeners=[appmesh.VirtualNodeListener.grpc(
                port=80,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey"),
                    # Validate a file client certificates to enable mutual TLS authentication when a client provides a certificate.
                    mutual_tls_validation=appmesh.MutualTlsValidation(
                        trust=appmesh.TlsValidationTrust.file("path-to-certificate")
                    )
                )
            )]
        )
        
        certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
        node2 = appmesh.VirtualNode(self, "node2",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node2"),
            backend_defaults=appmesh.BackendDefaults(
                tls_client_policy=appmesh.TlsClientPolicy(
                    ports=[8080, 8081],
                    validation=appmesh.TlsValidation(
                        subject_alternative_names=appmesh.SubjectAlternativeNames.matching_exactly("mesh-endpoint.apps.local"),
                        trust=appmesh.TlsValidationTrust.acm([
                            acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                        ])
                    ),
                    # Provide a SDS client certificate when a server requests it and enable mutual TLS authentication.
                    mutual_tls_certificate=appmesh.TlsCertificate.sds("secret_certificate")
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @builtins.property
    @jsii.member(jsii_name="differentiator")
    def _differentiator(self) -> builtins.bool:
        return typing.cast(builtins.bool, jsii.get(self, "differentiator"))


class _MutualTlsCertificateProxy(
    MutualTlsCertificate,
    jsii.proxy_for(TlsCertificate), # type: ignore[misc]
):
    pass

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, MutualTlsCertificate).__jsii_proxy_class__ = lambda : _MutualTlsCertificateProxy


class MutualTlsValidationTrust(
    TlsValidationTrust,
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-appmesh.MutualTlsValidationTrust",
):
    '''Represents a TLS Validation Context Trust that is supported for mutual TLS authentication.

    :exampleMetadata: infused

    Example::

        # mesh: appmesh.Mesh
        
        
        node1 = appmesh.VirtualNode(self, "node1",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node"),
            listeners=[appmesh.VirtualNodeListener.grpc(
                port=80,
                tls=appmesh.ListenerTlsOptions(
                    mode=appmesh.TlsMode.STRICT,
                    certificate=appmesh.TlsCertificate.file("path/to/certChain", "path/to/privateKey"),
                    # Validate a file client certificates to enable mutual TLS authentication when a client provides a certificate.
                    mutual_tls_validation=appmesh.MutualTlsValidation(
                        trust=appmesh.TlsValidationTrust.file("path-to-certificate")
                    )
                )
            )]
        )
        
        certificate_authority_arn = "arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
        node2 = appmesh.VirtualNode(self, "node2",
            mesh=mesh,
            service_discovery=appmesh.ServiceDiscovery.dns("node2"),
            backend_defaults=appmesh.BackendDefaults(
                tls_client_policy=appmesh.TlsClientPolicy(
                    ports=[8080, 8081],
                    validation=appmesh.TlsValidation(
                        subject_alternative_names=appmesh.SubjectAlternativeNames.matching_exactly("mesh-endpoint.apps.local"),
                        trust=appmesh.TlsValidationTrust.acm([
                            acmpca.CertificateAuthority.from_certificate_authority_arn(self, "certificate", certificate_authority_arn)
                        ])
                    ),
                    # Provide a SDS client certificate when a server requests it and enable mutual TLS authentication.
                    mutual_tls_certificate=appmesh.TlsCertificate.sds("secret_certificate")
                )
            )
        )
    '''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @builtins.property
    @jsii.member(jsii_name="differentiator")
    def _differentiator(self) -> builtins.bool:
        return typing.cast(builtins.bool, jsii.get(self, "differentiator"))


class _MutualTlsValidationTrustProxy(
    MutualTlsValidationTrust,
    jsii.proxy_for(TlsValidationTrust), # type: ignore[misc]
):
    pass

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, MutualTlsValidationTrust).__jsii_proxy_class__ = lambda : _MutualTlsValidationTrustProxy


__all__ = [
    "AccessLog",
    "AccessLogConfig",
    "Backend",
    "BackendConfig",
    "BackendDefaults",
    "CfnGatewayRoute",
    "CfnGatewayRouteProps",
    "CfnMesh",
    "CfnMeshProps",
    "CfnRoute",
    "CfnRouteProps",
    "CfnVirtualGateway",
    "CfnVirtualGatewayProps",
    "CfnVirtualNode",
    "CfnVirtualNodeProps",
    "CfnVirtualRouter",
    "CfnVirtualRouterProps",
    "CfnVirtualService",
    "CfnVirtualServiceProps",
    "CommonGatewayRouteSpecOptions",
    "DnsResponseType",
    "GatewayRoute",
    "GatewayRouteAttributes",
    "GatewayRouteBaseProps",
    "GatewayRouteHostnameMatch",
    "GatewayRouteHostnameMatchConfig",
    "GatewayRouteProps",
    "GatewayRouteSpec",
    "GatewayRouteSpecConfig",
    "GrpcConnectionPool",
    "GrpcGatewayListenerOptions",
    "GrpcGatewayRouteMatch",
    "GrpcGatewayRouteSpecOptions",
    "GrpcHealthCheckOptions",
    "GrpcRetryEvent",
    "GrpcRetryPolicy",
    "GrpcRouteMatch",
    "GrpcRouteSpecOptions",
    "GrpcTimeout",
    "GrpcVirtualNodeListenerOptions",
    "HeaderMatch",
    "HeaderMatchConfig",
    "HealthCheck",
    "HealthCheckBindOptions",
    "HealthCheckConfig",
    "Http2ConnectionPool",
    "Http2GatewayListenerOptions",
    "Http2VirtualNodeListenerOptions",
    "HttpConnectionPool",
    "HttpGatewayListenerOptions",
    "HttpGatewayRouteMatch",
    "HttpGatewayRoutePathMatch",
    "HttpGatewayRoutePathMatchConfig",
    "HttpGatewayRouteSpecOptions",
    "HttpHealthCheckOptions",
    "HttpRetryEvent",
    "HttpRetryPolicy",
    "HttpRouteMatch",
    "HttpRouteMethod",
    "HttpRoutePathMatch",
    "HttpRoutePathMatchConfig",
    "HttpRouteProtocol",
    "HttpRouteSpecOptions",
    "HttpTimeout",
    "HttpVirtualNodeListenerOptions",
    "IGatewayRoute",
    "IMesh",
    "IRoute",
    "IVirtualGateway",
    "IVirtualNode",
    "IVirtualRouter",
    "IVirtualService",
    "ListenerTlsOptions",
    "Mesh",
    "MeshFilterType",
    "MeshProps",
    "MutualTlsCertificate",
    "MutualTlsValidation",
    "MutualTlsValidationTrust",
    "OutlierDetection",
    "Protocol",
    "QueryParameterMatch",
    "QueryParameterMatchConfig",
    "Route",
    "RouteAttributes",
    "RouteBaseProps",
    "RouteProps",
    "RouteSpec",
    "RouteSpecConfig",
    "RouteSpecOptionsBase",
    "ServiceDiscovery",
    "ServiceDiscoveryConfig",
    "SubjectAlternativeNames",
    "SubjectAlternativeNamesMatcherConfig",
    "TcpConnectionPool",
    "TcpHealthCheckOptions",
    "TcpRetryEvent",
    "TcpRouteSpecOptions",
    "TcpTimeout",
    "TcpVirtualNodeListenerOptions",
    "TlsCertificate",
    "TlsCertificateConfig",
    "TlsClientPolicy",
    "TlsMode",
    "TlsValidation",
    "TlsValidationTrust",
    "TlsValidationTrustConfig",
    "VirtualGateway",
    "VirtualGatewayAttributes",
    "VirtualGatewayBaseProps",
    "VirtualGatewayListener",
    "VirtualGatewayListenerConfig",
    "VirtualGatewayProps",
    "VirtualNode",
    "VirtualNodeAttributes",
    "VirtualNodeBaseProps",
    "VirtualNodeListener",
    "VirtualNodeListenerConfig",
    "VirtualNodeProps",
    "VirtualRouter",
    "VirtualRouterAttributes",
    "VirtualRouterBaseProps",
    "VirtualRouterListener",
    "VirtualRouterListenerConfig",
    "VirtualRouterProps",
    "VirtualService",
    "VirtualServiceAttributes",
    "VirtualServiceBackendOptions",
    "VirtualServiceProps",
    "VirtualServiceProvider",
    "VirtualServiceProviderConfig",
    "WeightedTarget",
]

publication.publish()
