[Apiman-user] Enhancing apiman-cli to make headless gateway configs easier to use.

Marc Savy marc.savy at redhat.com
Tue Nov 7 06:36:50 EST 2017


Here are some examples. Make sure you look through all the sections to
see the different approaches.

Example usage session drilling into API details:

$ ./apiman-cli gateway organization list
test

$ ./apiman-cli gateway api list --org test
foo

$ ./apiman-cli gateway api list --org test --api foo
1.0
3
4
5

$ ./apiman-cli gateway api list --org test --api foo --version 5
{
  "publicAPI" : true,
  "organizationId" : "test",
  "apiId" : "foo",
  "version" : "5",
  "endpoint" : "http://localhost:8080/services/echo",
  "endpointType" : "rest",
  "endpointContentType" : "json",
  "endpointProperties" : { },
  "parsePayload" : false,
  "apiPolicies" : [ {
    "policyJsonConfig" : "{\"favouriteColour\":\"#ff6c54\",\"surcharge\":10}",
    "policyImpl" :
"plugin:io.apiman.plugins:apiman-plugins-simple-example-2-policy:1.3.2-SNAPSHOT:war/io.apiman.plugins.simpleexample2.SimpleExample2Policy"
  } ],
  "maxPayloadBufferSize" : 0
}


-----------

There's a tonne of power available in the YAML _declaration_ format
contributed by Pete Cornish and Raleigh Pickard. It allows you to
define and write your setup in a much more human friendly manner;
publish to either the Apiman Manager or (as a new feature) the Apiman
Gateway directly!

More detail in a forthcoming blog and documentation, but...

Example of using the CLI to write a declaration directly to the Gateway API:

$ ./apiman-cli gateway apply -f /Users/msavy/tmp/sample.yaml
INFO  Loaded declaration: /Users/msavy/tmp/sample.yaml
INFO  Resolving plugin: TestPolicy
INFO  Automatically selecting policy: Test Policy
INFO  Publishing API

Where sample.yaml is...

# Simple apiman example
---
  system:
    gateways:
      - name: "test-gw"
        type: "REST"
        config:
          endpoint: "http://localhost:8080/apiman-gateway-api"
          username: "apimanager"
          password: "apiman123!"
    plugins:
      - name: TestPolicy
        groupId: "io.apiman.plugins"
        artifactId: "apiman-plugins-test-policy"
        version: "1.3.1.Final"
  org:
    name: "test"
    apis:
      - name: "example"
        version: "1.0"
        config:
          endpoint: "http://localhost:8080/services/echo"
          endpointType: "rest"
          public: true
          gateway: "test-gw"
        policies:
          - name: "CachingPolicy"
            config:
              ttl: 60
          - plugin: TestPolicy
            config:
              foo: 123


-----

And finally, for people who want to generate the Headless JSON configs
without doing all of the legwork of looking up plugin references,
escaping certain fields, etc:

$ ./apiman gateway generate headless -f /Users/msavy/tmp/sample.yaml
-o my-headless.json
INFO  Loaded declaration: /Users/msavy/tmp/sample.yaml
INFO  Resolving plugin: TestPolicy
INFO  Automatically selecting policy: Test Policy

$ cat my-headless.json
{
  "apis" : [ {
    "publicAPI" : true,
    "organizationId" : "test",
    "apiId" : "example",
    "version" : "1.0",
    "endpoint" : "http://localhost:8080/services/echo",
    "endpointType" : "rest",
    "endpointContentType" : null,
    "endpointProperties" : { },
    "parsePayload" : false,
    "apiPolicies" : [ {
      "policyJsonConfig" : "{\n  \"ttl\" : 60\n}",
      "policyImpl" : "class:io.apiman.gateway.engine.policies.CachingPolicy"
    }, {
      "policyJsonConfig" : "{\n  \"foo\" : 123\n}",
      "policyImpl" :
"plugin:io.apiman.plugins:apiman-plugins-test-policy:1.3.1.Final:war/io.apiman.plugins.test_policy.TestPolicy"
    } ],
    "maxPayloadBufferSize" : 0
  } ],
  "clients" : [ ]
}

This is just the barest introduction to whet people's appetites. More soon!

On 7 November 2017 at 10:55, Marc Savy <marc.savy at redhat.com> wrote:
> I thought I'd share some of the good progress that has been made in this area:
>
> The Apiman CLI tool will now:
>
> * Allow Apiman Gateway API to be driven directly.
>
> * Expose new Apiman Gateway API "list entity" functions (e.g. list
> orgs, APIs, Clients, Versions, etc).
>     * List all orgs: apiman-cli gateway organization list
>     * List all APIs in org "test": apiman-cli gateway api list --org test
>
> * Directly apply YAML declarations on the Gateway API (with status checks, etc).
>
> * Generate Headless Gateway JSON configs from the YAML declaration format.
>
> For more detail, see:
>   https://github.com/apiman/apiman-cli/pull/28
>
> On 25 July 2017 at 17:11, Marc Savy <marc.savy at redhat.com> wrote:
>> Here's the PR for those who want to track progress:
>>
>> https://github.com/apiman/apiman-cli/pull/27
>>
>> On 18 July 2017 at 23:34, Marc Savy <marc.savy at redhat.com> wrote:
>>>
>>> Here's a preview of my proposed data format -- it reuses the format
>>> and model developed by Pete Cornish and his team; big kudos to them!
>>> [1].
>>>
>>> I'm soliciting suggestions and comments, feel free to reply here (or
>>> reach out privately if that's not possible).
>>>
>>> Example:
>>>
>>> apiman-cli gateway apply -f /Users/msavy/tmp/sample.yaml
>>>
>>> ```
>>> # sample.yaml
>>> ---
>>>   system:
>>>     gateways:
>>>       - name: "test-gw"
>>>         type: "REST"
>>>         config:
>>>           endpoint: "http://localhost:8080/apiman-gateway-api"
>>>           username: "apimanager"
>>>           password: "apiman123!"
>>>     plugins:
>>>       - name: TestPolicyFriendlyName // (1)
>>>         groupId: "io.apiman.plugins"
>>>         artifactId: "apiman-plugins-test-policy"
>>>         version: "1.3.1.Final"
>>>   org:
>>>     name: "test"
>>>     apis:
>>>       - name: "example"
>>>         version: "1.0"
>>>         config:
>>>           endpoint: "http://localhost:8080/services/echo"
>>>           endpointType: "rest"
>>>           public: true
>>>           gateway: "test-gw"
>>>         policies:
>>>           - name: "CachingPolicy" // (2)
>>>             config:
>>>               ttl: 60
>>>           - plugin: TestPolicyFriendlyName // (3)
>>>             config:
>>>               foo: 123
>>> ```
>>> (1) Friendly name for plugin instead of having to refer to it by full GAV
>>> (2) In-built policy will be looked up to ensure it exists and resolves
>>> the correct FQCN.
>>> (3) Add a policy by plugin friendly name (else GAV)
>>>
>>> One rare edge case when multiple policies are defined in a single
>>> plugin. In that situation we allow disambiguation by providing the
>>> plugin's `id` in the `name`/`id` field:
>>>
>>> ```
>>> <SNIP>
>>>         policies:
>>>           - name: PolicyOne
>>>             plugin: PluginWithMultiplePolicies
>>>             config:
>>>               foo: 123
>>> ```
>>>
>>> Thoughts? Feedback?
>>>
>>> Still a bit of work to do before it's PR-ready but making some progress.
>>>
>>> Regards,
>>> Marc
>>>
>>> [1] With one tiny addition.
>>>
>>> On 7 July 2017 at 14:29, Marc Savy <marc.savy at redhat.com> wrote:
>>> > We've had some people using the Apiman Gateway headless for a while
>>> > now, either with the new immutable registry that loads from JSON[1],
>>> > or simply using any existing registry via the gateway API instead of
>>> > using a manager.
>>> >
>>> > The main issue people encounter is that policy configuration contains
>>> > two fields that are difficult to work out and clumsy to encode
>>> > properly[1]:
>>> >
>>> > - `policyImpl` requires the plugin's URI, including the path to its
>>> > main class. You can work these out by looking at the plugin's source
>>> > code, but that's rather circuitous and it would be nicer to just
>>> > provide the plugin's GAV (like in the manager) and for it to be
>>> > resolved.
>>> >
>>> > - `policyJsonConfig`[3] needs to be escaped properly (and must valid
>>> > according to its schema).
>>> >
>>> > Neither of these aspects are especially user-friendly. My proposal is
>>> > to extend apiman-cli's functionality to allow the Apiman Gateway to be
>>> > configured directly via a YAML/JSON file (i.e. declaratively).
>>> >
>>> > We can therefore provide a more user-friendly interface that automates
>>> > the resolution of plugins; validations and escapes the policy config;
>>> > etc.
>>> >
>>> > A final step would be to bundle the apiman-cli tool with our distros
>>> > to make it easier to access.
>>> >
>>> > Any thoughts?
>>> >
>>> > Regards,
>>> > Marc
>>> >
>>> > [1]
>>> > https://apiman.gitbooks.io/apiman-installation-guide/installation-guide/vertx/download.html#_elasticsearch
>>> > [2]  Of course, this interface was never truly designed to be used by
>>> > humans, so that's understandable
>>> > [3] Unfortunately named as it can be any arbitrary string, the policy
>>> > just needs to be able to decode it. For example, it could be XML.
>>
>>


More information about the Apiman-user mailing list