How to add Quota policy for different clientids and pull the allowed count from KVM for each client

Hi,

Below is the Quota policy i created for my proxy.

<Quota async="false" continueOnError="false" enabled="true" name="QuotaLimit">
<DisplayName>QuotaLimit</DisplayName>
<Properties/>
<TimeUnit>minute</TimeUnit>
<Interval>1</Interval>
<Distributed>false</Distributed>
<Synchronous>false</Synchronous>
<Allow>
<Class ref="consumer.client.id">
<Allow class="client1" count="2" />
<Allow class="client2" count="4"/>
</Class>
</Allow>
</Quota>

Now the problem here is , client 1 can come back to me tomorrow and ask me to raise its quota from 2 to 10. In such case I will have to make that update in apigee proxy and re-deploy. Instead I was looking for a way by which re-deployment was not needed ie. instead of hardcoding this value if there was a way by which we could fetch the value from KVM(update in KVM should have been required in such case), it would have been great. "countRef" doesnt seem to work/present for the Allow(child of Class) - ref(https://docs.apigee.com/api-platform/reference/policies/quota-policy#allowelement-allowclassallowele...).

Is there anyway by which i can achieve above ?

0 9 576
9 REPLIES 9

You could store it in the KeyValueMap and use a KVM policy to retrieve it. Your quota policy then refers to the variable value retrieved from the KVM.

Another approach could be instead of using KVM - you could store a quota value as a custom attribute against the consumer's app in apigee. You then can use that custom attribute value as your countRef.

Don't forget to have a default value for your quota policy in case the variable is not set. You could also use a value from your API product as the fallback/default to avoid having anything hardcoded in your API proxy. 

You may also want to consider scalability/manual overhead of having consumers telling you to update quotas in such a manner, and instead offer multiple types of API Products with different quotas depending on who the consumer is eg internal consumers or privileged partners may be entitled to a higher quota via a product that's unique to this type of consumer. 

An example of how a combined API Product + App approach would work.. 

If you create a new API Proxy in Apigee X, the wizard has an option for including a default authentication and quota policy.. (You can always use a different authentication policy, but I'll use apikey for simplicity)

Screenshot 2023-05-17 at 6.44.39 PM.png

This will give you a proxy with 3 policies - Verify API Key, a policy to remove the apikey, and a quota policy preconfigured to use values set in the API Product.

Screenshot 2023-05-17 at 6.45.19 PM.png

You can then configure an API Product/s for this API Proxy and configure your quota. Apigee will know which is the relevant API Product based on the api key when the Verify API Key policy executes.

Screenshot 2023-05-17 at 6.47.27 PM.png

To allow the quota be overridden at the consumer app level, we can

1. Introduce a third policy - AM-Quota (AssignMessage) to set a quota variable based on the app value if it's available, otherwise fallback to the API Product's value.

Screenshot 2023-05-17 at 6.58.45 PM.png

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-Quota">
    <DisplayName>AM-Quota</DisplayName>
    <AssignVariable>
        <Name>quota</Name>
        <Template>{firstnonnull(verifyapikey.verify-api-key.app.quota,verifyapikey.verify-api-key.apiproduct.developer.quota.limit)}</Template>
    </AssignVariable>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

 

This uses a message template which gives us a function to use the first variable if available (app level), otherwise it falls back to the API product. The verify api key policies sets a number of flow variables (including app and api product details), you can see what variables are available in the docs for all policies. 

2. Update the quota policy, to use this quota since we can only have a single quota reference.
Also, the default generated quota policy from the wizard doesnt include an identifier so all consumers will be sharing a counter, instead we can use the client_id to maintain a separate counter for each consumer

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Quota async="false" continueOnError="false" enabled="true" name="impose-quota">
    <DisplayName>Impose Quota</DisplayName>
    <Allow countRef="quota" count="2000"/>
    <Interval ref="verifyapikey.verify-api-key.apiproduct.developer.quota.interval">1</Interval>
    <Identifier ref="verifyapikey.verify-api-key.client_id"/>
    <Distributed>true</Distributed>
    <Synchronous>true</Synchronous>
    <TimeUnit ref="verifyapikey.verify-api-key.apiproduct.developer.quota.timeunit">month</TimeUnit>
</Quota>

 

 (The <allow> and <identifier> lines were changed from the wizard default)

Now requests to this proxy will use the API Product defined quota. If you then set a custom attribute in the app for quota, the proxy will automatically use this value instead for requests associated to that app. Note, you may have to wait a few minutes for the custom attribute to take effect as lookups such as app configuration gets cached.

Screenshot 2023-05-17 at 7.00.02 PM.png 

Cool!

Since we are using APIGEE , i think apigee does not allow countRef inside Allow(child of Class) tag. Are you saying it does work ?

Since I am quite new to APIGEE. I just found that APIGEE and APIGEE-X are two separate tools. And i think APIGEE does not allow countRef.

I already tried reading data from KVM(which was successful) and assigned it to a customer attribute but i am unable to use that custom attribute in the Quota Policy due to the restriction mentioned at the below doc of apigee :

 

You can use countRef, refer to https://docs.apigee.com/api-platform/reference/policies/quota-policy#allow

Based on your description, I don't think you need to use Class tags. Instead you're setting a quota for each consumer by using a dynamic quota for <Allow>, and the <Identifier> to maintain unique counters

Yeah. The ask is to maintain different counters for different clients invoking our APIGEE proxy.

Below doc ref doesnt allow to maintain different counters for different clients. instead it would allow same counter individually to all the clients.

https://docs.apigee.com/api-platform/reference/policies/quota-policy#allow

As per the above example, you use the <Identifier> to have unique counters. This can be based on client_id for example as per the example above.

https://docs.apigee.com/api-platform/reference/policies/quota-policy#identifierelement

I think there is some confusion here.

The example which you mentioned above will apply same quota to all the unique client_ids. Using identifier I will be only able to apply same quota uniquely to all the client_ids.

Taking your above example :

Lets say distinct values of client_id which my application expects is Clientid1, Clientid2 and Clientid3

Clientid1 will have its own quota 999

Clientid2 will have its own quota 999

Clientid3 will have its own quota 999

 

However, I was looking for a way by which i can have :

Clientid1 having quota 999

Clientid2 having quota 1999

Clientid3 having quota 2499

The example I provided will use the quota defined one the consumer's app (if one is defined there), otherwise the API Proudct quota.