This year for the holidays we got a great gift, a new and much improved Gateway Container! (Well, at least I think it's a great gift)
What is the Gateway Container?
The Gateway container is a Docker image of the CA API Gateway. The docker image containers just the Gateway process. For more details see the official documentation here: Using the Container Gateway - CA API Gateway - 9.3 - CA Technologies Documentation
Prerequisites
In order to run the Gateway Container on your local machine you need to have Docker installed.
You also need to have a valid license for the CA API Gateway.
Using the Gateway Container
One of the focuses on the updated Gateway Container was making it simple to use. You can start a gateway by running:
docker run -p 8080:8080 -p 8443:8443 -e ACCEPT_LICENSE=true -v /absolute/path/to/license.xml:/opt/SecureSpan/Gateway/node/default/etc/bootstrap/license/license.xml caapim/gateway:9.3.00
Some details on the command:
- docker run
- The docker run command starts a docker container. Read the official documentation for more info.
- -p 8080:8080 -p 8443:8443
- This exposes port 8080 and port 8443.
- -e ACCEPT_LICENSE=true
- Accepts the Container Gateway End User License Agreement
-v /absolute/path/to/license.xml:/opt/SecureSpan/Gateway/node/default/etc/bootstrap/license/license.xml
- This provides the license to the gateway. The path before the `:` is the absolute path to the license.xml file on your local machine. This path will be specified differently on windows vs unix operating systems.
- caapim/gateway:9.3.00
- This is the image to run. The gateway container, specifically tagged with 9.3.00 (for version 9.3.00)
You will now have a fully running gateway. But what exactly is running?
The Gateway that is running will have no services or endpoints available. There is also a randomized administrator username and password so you will not be able to access it via the Policy Manager. The next steps would be to expose some services in the Container Gateway, so let's see how you would do that.
Adding Services to the Container Gateway
Services are added to the Container Gateway by mounting restman bundles to bootstrap folders in the Container Gateway Image. For example, let's use the following bundle:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<l7:Bundle xmlns:l7="http://ns.l7tech.com/2010/04/gateway-management">
<l7:References>
<l7:Item>
<l7:Name>HelloContainer</l7:Name>
<l7:Id>f65f1da6c82e3f10aeb7fd633bf60ee2</l7:Id>
<l7:Type>SERVICE</l7:Type>
<l7:Resource>
<l7:Service id="f65f1da6c82e3f10aeb7fd633bf60ee2">
<l7:ServiceDetail folderId="0000000000000000ffffffffffffec76" id="f65f1da6c82e3f10aeb7fd633bf60ee2">
<l7:Name>HelloContainer</l7:Name>
<l7:Enabled>true</l7:Enabled>
<l7:ServiceMappings>
<l7:HttpMapping>
<l7:UrlPattern>/hellocontainer</l7:UrlPattern>
<l7:Verbs>
<l7:Verb>GET</l7:Verb>
<l7:Verb>POST</l7:Verb>
<l7:Verb>PUT</l7:Verb>
<l7:Verb>DELETE</l7:Verb>
</l7:Verbs>
</l7:HttpMapping>
</l7:ServiceMappings>
<l7:Properties>
<l7:Property key="internal">
<l7:BooleanValue>false</l7:BooleanValue>
</l7:Property>
<l7:Property key="policyRevision">
<l7:LongValue>2</l7:LongValue>
</l7:Property>
<l7:Property key="soap">
<l7:BooleanValue>false</l7:BooleanValue>
</l7:Property>
<l7:Property key="tracingEnabled">
<l7:BooleanValue>false</l7:BooleanValue>
</l7:Property>
<l7:Property key="wssProcessingEnabled">
<l7:BooleanValue>false</l7:BooleanValue>
</l7:Property>
</l7:Properties>
</l7:ServiceDetail>
<l7:Resources>
<l7:ResourceSet tag="policy">
<l7:Resource type="policy" version="1"><?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy xmlns:L7p="http://www.layer7tech.com/ws/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
<wsp:All wsp:Usage="Required">
<L7p:HardcodedResponse>
<L7p:Base64ResponseBody stringValue="SGVsbG8gZnJvbSBhIEdhdGV3YXkgQ29udGFpbmVy"/>
<L7p:ResponseContentType stringValue="text/plain; charset=UTF-8"/>
</L7p:HardcodedResponse>
</wsp:All>
</wsp:Policy>
</l7:Resource>
</l7:ResourceSet>
</l7:Resources>
</l7:Service>
</l7:Resource>
</l7:Item>
</l7:References>
<l7:Mappings>
<l7:Mapping action="NewOrExisting" srcId="0000000000000000ffffffffffffec76" type="FOLDER">
<l7:Properties>
<l7:Property key="FailOnNew">
<l7:BooleanValue>true</l7:BooleanValue>
</l7:Property>
</l7:Properties>
</l7:Mapping>
<l7:Mapping action="NewOrExisting" srcId="f65f1da6c82e3f10aeb7fd633bf60ee2" type="SERVICE"/>
</l7:Mappings>
</l7:Bundle>
The above bundle will create a service available at the `/hellocontainer` endpoint. In order to add this service to the Gateway save the bundle to a file and mount it as a volume in the container:
docker run -p 8080:8080 -p 8443:8443 -e ACCEPT_LICENSE=true -v /absolute/path/to/license.xml:/opt/SecureSpan/Gateway/node/default/etc/bootstrap/license/license.xml -v /absolute/path/to/hellocontainer.bundle:/opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/hellocontainer.bundle caapim/gateway:9.3.00
Here we added another volume mount:
-v /absolute/path/to/hellocontainer.bundle:/opt/SecureSpan/Gateway/node/default/etc/bootstrap/bundle/hellocontainer.bundle
- This provides the hellocontainer.bundle to the gateway. The path before the `:` is the absolute path to the hellocontainer.bundle file on your local machine. This path will be specified differently on windows vs unix operating systems.
Once the Gateway has started you can open http://localhost:8080/hellocontainer and see the results of executing the service. (Note, in some cases docker may not be running on localhost. In that case run `docker-machine ip` to find the address of the docker container).
Next Steps
The next steps would be to explore the other available environment variables in the Container Gateway. In a subsequent blog post I will talk about how to use the Container Gateway in a development environment in order to create bundle files for bootstrapping in other Gateway Containers.
Best Practices
There are many other configuration parameters available however, with Gateway containers the best practices is to run containers in an ephemeral mode. This means not using external databases and not configuring the gateway using policy manager, GMU, or the RESTMAN api's. Container Gateways should be exclusively configured via the bootstrap folders.
I would like to point out, -p 8080:8080 and -p 8443:8443 are direct 1:1 port mapping from the docker vm to the running Gateway container inside of it. This means you will not be able to scale up the containers within this docker vm as the 8080 and 8443 ports are taken. To map a random port from the docker vm to 8080/8443 port on the container, you can use -p 8080 -p 8443.
You can then use docker ps to figure out the actual port used to be able to hit services hosted on the Gateway. Though scaling up in docker without a fronting load balancer is quite useless. For proper load balancing in docker you may consult similar reference docs like Create a proxy or load balancer | Docker Documentation