Apigee Spike Arrest Rate Limit Application - api

I am an Apigee newbie.
I am trying to understand the Spike Arrest policy.
I am looking at this documentation:
http://apigee.com/docs/api-services/content/shield-apis-using-spikearrest
http://apigee.com/docs/api-services/content/policy-attachment-and-enforcement
The one thing I cannot understand for certain is if, when the Spike Arrest Policy is applied to an ApiProxy, whether the rate limit is applied per Key/Client Dev Application, or is it shared between all Keys/Client Dev Applications?
For example if we have the following config:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SpikeArrest async="false" continueOnError="false" enabled="true" name="spikearrest-1">
<DisplayName>SpikeArrest-1</DisplayName>
<FaultRules/>
<Properties/>
<Identifier ref="request.header.some-header-name"/>
<MessageWeight ref="request.header.weight"/>
<Rate>50ps</Rate>
</SpikeArrest>
And Client Dev Apps:
1. DevApp1
2. DevApp2
Is the 50ps rate limit shared between DevApp1 and DevApp2, or do DevApp1 and DevApp2 get 50ps rate limit each?
Thanks,

You can use any of the predefined variables:
http://apigee.com/docs/api-services/api/variables-reference
The variable that is probably the most commonly used for Spike Arrest is client.ip.
Edge will make all elements of a request message available. If your clients are adding a client_id (aka API key) to a request as a query parameter, for example api.call.com?client_id=u34r8ur, then you would set the variable in your Spike Arrest Identifier to be:
<Identifier ref="request.queryparam.client_id"/>
Or if it is in an HTTP header:
<Identifier ref="request.header.client_id"/>
Hope that helps!

Its per app identified by your identifier.

Related

Selenoid: What does the count attribute do in a quota file?

I started Selenoid with docker: aerokube/cm:latest selenoid start --args "-limit 20"
I then created a quota file with:
user.xml:
<qa:browsers xmlns:qa="urn:config.gridrouter.qatools.ru">
<browser name="chrome" defaultVersion="62.0">
<version number="62.0">
<region name="1">
<host name="1.2.3.4" port="4445" count="10"/>
</region>
</version>
</browser>
</qa:browsers>
When I run with this user it runs 20 in parallel. I thought count="10" would mean this user can do at most 10 in parallel. And -limit 20 was the max for the VM. Is this the correct usage of count?
In fact count field in Ggr quota XML file means host weight. It makes sense when two or more hosts are present in quota. This attribute is called so for historical reasons. So when you have e.g. two hosts in quota with counts 1 and 3 then sessions will be distributed as 1:3 over these hosts. When counts are equal then distribution should be random uniform. If you set count equal to the real count of browsers for each host - then you also get random uniform distribution. This is what we are recommend to do in production.

Gemfire WAN Gateway-sender configuration

We are using the Gemfire WAN topology and have problems setting up the gateway-senders.
Couple of assumptions:
- Replicated regions
- Serial gateway-senders
- manual-start is false for all gateway-senders
Let's say we have 2 clusters, within each cluster, we have 2 members (Member A and Member B)
Member A's cache.xml
<gfe:gateway-sender id="gateway-sender-A" parallel="false" remote-distributed-system-id="2" manual-start="false" />
<gfe:replicated-region name="data" scope="DISTRIBUTED_NO_ACK">
<gfe:replicated-region name="subData" data-policy="REPLICATE" scope="DISTRIBUTED_ACK">
<gfe:gateway-sender-ref bean="gateway-sender-A"/>
</gfe:replicated-region>
</gfe:replicated-region>
Member B's cache.xml
<gfe:gateway-sender id="gateway-sender-B" parallel="false" remote-distributed-system-id="2" manual-start="false" />
<gfe:replicated-region name="data" scope="DISTRIBUTED_NO_ACK">
<gfe:replicated-region name="subData" data-policy="REPLICATE" scope="DISTRIBUTED_ACK">
<gfe:gateway-sender-ref bean="gateway-sender-B"/>
</gfe:replicated-region>
</gfe:replicated-region>
There is a problem when we run start up the two members within one cluster. It raises this error:
java.lang.IllegalStateException: Cannot create Region /data with [gateway-sender-A] gateway sender ids because another cache has the same region defined with [gateway-sender-B] gateway sender ids
Looking at the "High Availability for Gateway Senders" documentation, our understanding is that we can create 2 gateway-senders, in which only one will be doing the sending at a given point in time. Ultimately, we want to have 2 gateway senders (one in each member) for one cache region, one as the primary sender and the other as the secondary sender.
Thanks
From Geode documentation, it says
For serial Senders, Queue HA is achieved by configuring identical serial Senders in multiple members. The Queue is replicated between the members.
So if the two gateway senders in member A and B is doing the same job (except their primary/secondary roles), you should use "identical" setting.
Among gateway senders, there will be one that manages to acquire a specific distributed lock and becomes the primary sender, usually the first one comes up. I don't see a property to force one to become primary.
Geode is the open source version of Gemfire if you wonder.
After changing the sender-ids to the same for both members, we have another problem:
java.lang.IllegalStateException: Cannot create Gateway Sender
"some-gateway-sender-id" with manual start "false" because another
cache has the same Gateway Sender defined with manual start "true
It seems like our problem was the inconsistent format.
Member A used XML format
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 8.0//EN" "http://www.gemstone.com/dtd/cache8_0.dtd">
Member B used Spring Gemfire Data format
xmlns:gfe="http://www.springframework.org/schema/gemfire" xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">
<gfe:gateway-sender ...>
We switched to using the Spring Gemfire Data format for both members, and it solved both issues.
TL;DR, the gateway-senders need to have the same ids if they are in the same cluster and use consistent cache xml formats.

Bit rate error when trying to dial out to an ISDN line using Polycom XML API

I am having a problem connecting to an ISDN line using Polycom's XML API on an RMX_2000. Below is the request I am sending, and the response. I can do the same action from the RMX Manager, for the same number, in the same conference, and it works. When I trace the XML from the RMX Manager, I get an ADD_PARTY request that looks exactly like my constructed request, except with a lot more elements. I've reviewed and don't see any that seem like they could be relevant, and I am loath to manually code every single element, knowing that it is a long shot that it will even help. The same request (variant) works fine for IP and registered number requests, but no matter what I do, always get the bit rate error below. Can anyone tell me what I am doing wrong?
<TRANS_CONF_1>
<TRANS_COMMON_PARAMS>
<MCU_TOKEN>304</MCU_TOKEN>
<MCU_USER_TOKEN>304</MCU_USER_TOKEN>
<MESSAGE_ID>1</MESSAGE_ID>
</TRANS_COMMON_PARAMS>
<ACTION>
<ADD_PARTY>
<ID>18466</ID>
<PARTY>
<ID>0</ID>
<NAME>isdn</NAME>
<PHONE_LIST>
<PHONE1>12345678910</PHONE1>
</PHONE_LIST>
<INTERFACE>isdn</INTERFACE>
<CONNECTION>dial_out</CONNECTION>
<MEET_ME_METHOD>party</MEET_ME_METHOD>
<NUM_TYPE>taken_from_service</NUM_TYPE>
<MULTI_RATE>auto</MULTI_RATE>
<ALIAS>
<NAME>12345678910</NAME>
<ALIAS_TYPE>323_id</ALIAS_TYPE>
</ALIAS>
<VIDEO_BIT_RATE>automatic</VIDEO_BIT_RATE>
<ENHANCED_VIDEO>false</ENHANCED_VIDEO>
<UNDEFINED>false</UNDEFINED>
</PARTY>
</ADD_PARTY>
</ACTION>
</TRANS_CONF_1>
Here is the response:
<RESPONSE_TRANS_CONF>
<RETURN_STATUS>
<ID>1015</ID>
<DESCRIPTION>Conference bit rate must be set to a minimum of 128Kbps to enable ISDN participant connection</DESCRIPTION>
<YOUR_TOKEN1>0</YOUR_TOKEN1>
<YOUR_TOKEN2>0</YOUR_TOKEN2>
<MESSAGE_ID>1</MESSAGE_ID>
<DESCRIPTION_EX></DESCRIPTION_EX>
</RETURN_STATUS>
<ACTION>
<ADD_PARTY/>
</ACTION>
</RESPONSE_TRANS_CONF>
Thanks to a little help from someone at Polycom, I found out that the following node is required for this:
auto
I added that to the PARTY node, and now all is well.
After alot of troubleshooting and wiresharking on this error I found a combination of 2 properties being the issue
Reservation object needs
<TRANSFER_RATE>384</TRANSFER_RATE>
Party object needs
<NET_CHANNEL_NUMBER>auto</NET_CHANNEL_NUMBER>

Reset quota is not working as expected in apigee

I have applied a quota policy by using the following code
<Quota async="false" continueOnError="false" enabled="true" name="Quota-1">
<DisplayName>Quota 1</DisplayName>
<Allow count="2"/>
<Interval>1</Interval>
<Distributed>true</Distributed>
<Synchronous>false</Synchronous>
<TimeUnit>minute</TimeUnit>
<Identifier ref="request.queryparam.id"/>
<AsynchronousConfiguration>
<SyncIntervalInSeconds>1</SyncIntervalInSeconds>
<SyncMessageCount>5</SyncMessageCount>
</AsynchronousConfiguration>
</Quota>
And then i am resetting the count by using reset count policy with following code
<ResetQuota async="false" continueOnError="false" enabled="true" name="Reset-Quota-1">
<DisplayName>Reset Quota 1</DisplayName>
<Quota name="Quota-1">
<Identifier ref="request.queryparam.id">
<Allow>6</Allow>
</Identifier>
</Quota>
</ResetQuota>
As per my knowledge when i am giving requests the available count needs to be 6,5,4,3,2,1,0
But it is showing 1,6,11,16,21,.....
In this scenario there is no chance to count come down to 0.
What might be the wrong.
Thanks in advance....
I see that you are using asynchronous quota by setting the to false. You also have an incorrect AsynchronousConfiguration because your SyncMessageCount (5) is greater than your Allow count (2).
What the Asynchronous Configuration really means is that the quota counters would not be updated to the backend for every request, but only at intervals of every 5 seconds, which is anyways higher than the allow count. That's the problem you are running into, and that's why you see the count increasing by a factor of 5 - 1,6,11,16,21 etc.
You need to set the sync interval to be smaller than the allow count. Also note that Async quota would not give you 100% accuracy since it only synchs the counters across multiple servers at regular intervals and not for every request.

Maximum number of messages sent to a Queue in OpenMQ?

I am currently using Glassfish v2.1 and I have set up a queue to send and receive messages from with Sesion beans and MDBs respectively. However, I have noticed that I can send only a maximum of 1000 messages to the queue. Is there any reason why I cannot send more than 1000 messages to the queue? I do have a "developer" profile setup for the glassfish domain. Could that be the reason? Or is there some resource configuration setting that I need to modify?
I have setup the sun-resources.xml configuration properties as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN" "http://www.sun.com/software/appserver/dtds/sun-resources_1_3.dtd">
<resources>
<admin-object-resource
enabled="true"
jndi-name="jms/UpdateQueue"
object-type="user"
res-adapter="jmsra"
res-type="javax.jms.Queue">
<description/>
<property name="Name" value="UpdatePhysicalQueue"/>
</admin-object-resource>
<connector-resource
enabled="true" jndi-name="jms/UpdateQueueFactory"
object-type="user"
pool-name="jms/UpdateQueueFactoryPool">
<description/>
</connector-resource>
<connector-connection-pool
associate-with-thread="false"
connection-creation-retry-attempts="0"
connection-creation-retry-interval-in-seconds="10"
connection-definition-name="javax.jms.QueueConnectionFactory"
connection-leak-reclaim="false"
connection-leak-timeout-in-seconds="0"
fail-all-connections="false"
idle-timeout-in-seconds="300"
is-connection-validation-required="false"
lazy-connection-association="false"
lazy-connection-enlistment="false"
match-connections="true"
max-connection-usage-count="0"
max-pool-size="32"
max-wait-time-in-millis="60000"
name="jms/UpdateFactoryPool"
pool-resize-quantity="2"
resource-adapter-name="jmsra"
steady-pool-size="8"
validate-atmost-once-period-in-seconds="0"/>
</resources>
Hmm .. further investigation revealed the following in the imq logs:
[17/Nov/2009:10:27:57 CST] ERROR sendMessage: Sending message failed. Connection ID: 427038234214377984:
com.sun.messaging.jmq.jmsserver.util.BrokerException: transaction failed: [B4303]: The maximum number of messages [1,000] that the producer can process in a single transaction (TID=427038234364096768) has been exceeded. Please either limit the # of messages per transaction or increase the imq.transaction.producer.maxNumMsgs property.
So what would I do if I needed to send more than 5000 messages at a time?
What I am trying to do is to read all the records in a table and update a particular field of each record based on the corresponding value of that record in a legacy table to which I have only read only access. This table has more than 10k records in it. As of now, I am sequentially going through each record in a for loop, getting the corresponding record from the legacy table, comparing the field values, updating the record if necessary and adding corresponding new records in other tables.
However, I was hoping to improve performance by processing all the records asynchronously. To do that I was thinking of sending each record info as a separate message and hence requiring so many messages.
To configure OpenMQ and set artitrary broker properties, have a look at this blog post.
But actually, I wouldn't advice to increase the imq.transaction.producer.maxNumMsgs property, at least not above the value recommended in the documentation:
The maximum number of messages that a producer can process in a single transaction. It is recommended that the value be less than 5000 to prevent the exhausting of resources.
If you need to send more messages, consider doing it in several transactions.