Calling a GET on the Apigee HTTPTargetConnection when the request was POST - apigee

I need to call a legacy API which uses GET.
My API proxy uses POST.
I tried using in AssignMessage:
<AssignTo type="request" createNew="false"/>
and
<Set> ... <Verb>GET</Verb>
But it still does a POST on the target API.
What is the proper way of converting?
Will the gateway automatically convert the POST form parameters into GET query parameters?
Is message.queryparam the same for both GET and POST?

When converting the Verb from POST to GET, the policy will NOT automatically convert the form parameters to query parameters. You will need to use the <Add> and/or <Remove> functionality of the AssignMessage policy to manipulate the message further. Example use in the AssignMessage policy to add the queryparams, referencing the formparams:
<Add>
<QueryParams>
<QueryParam name="q1">{request.formparam.q1}</QueryParam>
</QueryParams>
</Add>
Also, in your question you mentioned that the API Proxy accepts the request using method as POST. Then, you have a policy to set GET:
<Set> ... <Verb>GET</Verb>
But it still does a GET on the target API.
What's the problem? Isn't that what you are expecting? The request goes into the Apigee API Proxy as POST, the proxy converts the method (verb) to GET, and sends the request to the backend legacy API using GET.
Note: <AssignTo> is optional in the AssignMessage. Try leaving this out if the method is not being set properly. In its absence, the message at the current point in the flow will be modified.

Change this predefined variable to post
request.verb = "GET"
Note: If you do this and you have a flow condition based on request.verb="POST" that will not work well in the response. So you need to use another variable to use in the flow condition.
Here is the policy code that worked for me.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="changeverbassignmessage">
<DisplayName>ChangeVerbAssignMessage</DisplayName>
<FaultRules/>
<Properties/>
<AssignVariable>
<Name>request.verb</Name>
<Value>GET</Value>
<Ref/>
</AssignVariable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Related

Block undefined routes/paths in apigee

I have a proxy defined in Apigee with an end point which has quite a few different controllers and paths. I only want to expose 2 of these via apigee (a get and post). I can't work out how to stop anyone else being able to access the other endpoints through the apigee proxy.
Anyone able to help?
Just to confirm I understand your requirement right, the target API exposes multiple paths. Of all those paths, you would want to expose 2(GET and POST) paths via Apigee to your consumers.
This can be done using conditional flows. Create three conditional flows in your proxy endpoint. Two conditional flows for two paths you would want to expose. You may use combination of paths and HTTP verbs in the Condition tag.
Use the third conditional flow without any conditions as a catch all block. You can use the raise fault policy in the third conditional flow to return appropriate error to the consumer.
Your proxy endpoint should look something like this -
<Flows>
<Flow name="get-resource">
<Description>Get resource</Description>
<Request/>
<Response/>
<Condition>(proxy.pathsuffix MatchesPath "/resource") and (request.verb = "GET")</Condition>
</Flow>
<Flow name="post-resource">
<Description>Create resource</Description>
<Request/>
<Response/>
<Condition>(proxy.pathsuffix MatchesPath "/resource") and (request.verb = "POST")</Condition>
</Flow>
<Flow name="Unknown Resource">
<Description>Unknown resource</Description>
<Request>
<Step>
<Name>RaiseFault-UnknownResource</Name>
</Step>
</Request>
<Response/>
</Flow>
</Flows>
And the raise fault policy would look something like this -
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="RaiseFault-UnknownResource">
<DisplayName>RaiseFault-UnknownResource</DisplayName>
<Properties/>
<FaultResponse>
<Set>
<Headers/>
<Payload contentType="text/plain">Resource not found</Payload>
<StatusCode>404</StatusCode>
<ReasonPhrase>Not Found</ReasonPhrase>
</Set>
</FaultResponse>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>
If this is not the requirement please clarify it and I'll try and update the answer accordingly.

Send username/password to SOAP Service

I created a WDSL API-Proxy, everything works find but as expected i'm receiving an Authentication error because i'm not sending the correct user and password to the SOAP server, where do i set that?
Maybe you need pass username and password in header request.
Typical you will include an Authorization header for a SOAP call. I typically do these in an assign message policy like the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<AssignMessage name="buildSoapMessage">
<DisplayName>buildSoapMessage</DisplayName>
<AssignTo createNew="true" type="request">request</AssignTo>
<Set>
<Headers>
<Header name="Authorization">{request.header.Authorization}</Header>
</Headers>
<Verb>POST</Verb>
<Payload contentType="text/xml">
<Request xmlns="urn:foo:bar:1.0">

How to Query the APIGee Cache

My Question: How can i query/list the contents of the cache.
So i have creates one cache from Management API->Environment Configuration.
Then i created a api proxy with no target and attached populate cache policy to it. e.g.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PopulateCache async="false" continueOnError="false" enabled="true" name="populateBlacklistByIP">
<DisplayName>populateBlacklistByIP</DisplayName>
<FaultRules/>
<Properties/>
<CacheKey>
<Prefix>CLIENTIP-</Prefix>
<KeyFragment ref='request.queryparam.myvar'/>
</CacheKey>
<CacheResource>mycache</CacheResource>
<Scope>Global</Scope>
<!-- no expiry -->
<ExpirySettings>
<TimeoutInSec>432000</TimeoutInSec>
</ExpirySettings>
<Source>request.queryparam.myvar</Source>
</PopulateCache>
Now i invoke the operation and get 200 ok back. But no way to check if the value made to cache or not.
Please help.
Got My Answer from digging through the documentation.
Ref: http://apigee.com/docs/api-services/content/persistence.
Read this from url above:
Cache versus Key/value map
The PopulateCache policy does not persist cache entries. Entries are in memory until the configured expiration time. You can look up the value only until it expires.
One limitation is that you cannot find the list of keys that are currently in a cache.
When using KeyValueMap, the keys are persisted indefinitely. There are APIs available to retrieve the list of keys. There is no expiration time for the keys; you must explicitly delete them.

Differences in validating APIKeys with GetOAuthV1Info and VerifyAPIKey

We are in the process of totally rewriting our main API Proxy config and we discovered an issue with our new configuration (or maybe our existing one) relating to how API keys are being validated. Our current API uses the policy GetOAuthV1Info
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GetOAuthV1Info enabled="true" continueOnError="false" async="false" name="APIKey-Validate">
<DisplayName>APIKey-Validate</DisplayName>
<FaultRules/>
<Properties/>
<AppKey ref="request.queryparam.apikey"></AppKey>
</GetOAuthV1Info>
Our new configuration uses the policy VerifyAPIKey
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-Api-Key">
<DisplayName>Verify API Key</DisplayName>
<APIKey ref="request.queryparam.apikey"/>
</VerifyAPIKey>
On the surface both of these policies appear to work fine. However, after deploying the new config to our test environment some API keys were failing with a 401 Unauthorized error. Digging into those keys we discovered that they are assigned to a product that doesn't have access to the test environment. It appears that the GetOAuthV1Info step is not validating the environment..? The documentation for GetOAuthV1Info doesn't help as it doesn't talk about APIKeys at all (http://apigee.com/docs/api-services/content/authorize-requests-using-oauth-10a).
Fixing this particular issue is pretty straight forward in that we just need to allow those other products access to the test environment. However, this makes me wonder what the other differences are between these two policies? I'm very nervous now about deploying any changes to these API proxies because I don't know what else will break, or what other unforeseen issues will appear.
Is this a known limitation with the GetOAuthV1Info policy? Why does this even work at all? What are the other differences between these two policies that might bite me later?
The only difference that I'm aware of is that the variable names are assigned differently in the VerifyAPIKey Policy (it appends the policy type and name to the vairalbes like verifyapikey.verify_apikey-1.apiproduct.developer.quota.limit for example).
Both VerifyAPIKey and OAuth 1 does support restrictions by environment -- when I tested the GetOAuthV1 with an APIKey in an invalid environment and got this error:
OAuth Failure : Invalid API call as no apiproduct match found
Keep in mind that the convention for most projects seems to be either OAuth2 flows or the VerifyAPI so there is less information about the OAuth1 policies.

Apigee: Using environment name to extract variable

I have set up a custom variable in my developer app called sandbox.app_id so I can have different ids for different applications.
I am using the verify api key policy and this populate the verifyapikey.* variables.
I want an ExtractVariable policy similar to below:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-TLRG-App-ID">
<DisplayName>Extract TLRG App ID</DisplayName>
<FaultRules/>
<Properties/>
<Variable name="app_id">verifyapikey.verify-api-key.{environment.name}.app_id</Variable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>
Is this possible, or will I have to resort to javascript?
Basically you are trying to access custom application attributes from your extract variable policy. So you need to place this extract variable policy after your verify api key policy. A verify api key policy would load all the application attributes as flow variables for a valid key. You may not see the custom attributes as variables in the debug view. However correct way to access the variables is to use this naming format below:
verifyapikey.{your_policy_name}.app.{custom_attribute_name}
Note that the verify api key policy is mandatory, otherwise the application associated with the API call can not be identified.

Resources