AssignMessage to create a request header in postflow

Not applicable

Hello,

I have a step called AssignMessage.ForwardUserInfo which is in PostFlow as below.

    <PostFlow>
        <Request>
            <Step>
                <Name>AssignMessage.ForwardUserInfo</Name>
            </Step>
        </Request>
    </PostFlow>

Which sets up Request Headers

<AssignMessage name="AssignMessage.ForwardUserInfo">
    <AssignVariable>
        <Name>request.header.X-Apigee-UserName</Name>
        <Ref>accesstoken.username</Ref>
        <Value/>
    </AssignVariable>
</AssignMessage>

When I look at the trace I have cannot see where and if this step actually runs. Could somebody help me with this.

I also want to read these response headers in my .NET WebAPI to use for logging and possibly to control the data returned. I would expect I can just read this in the request headers in .NET but it always returns NULL which is why I am not sure the step is running.

Thanks in Advance

Daniel.

Solved Solved
1 21 965
1 ACCEPTED SOLUTION

Hi @Daniel Barnes, the whole point of the cache is for Apigee to respond to client requests without bothering the server. So by definition, no requests will reach your target as Apigee is responding from its cache as if Apigee sends the request to your target, caching on Apigee would be unnecessary. We would just return the response we got from your target.

The pattern we should follow for logging is to put a JS policy which would send a request asynchronously to some endpoint in your target so that you can get data you require. This is if you want logging for ALL requests irrespective of whether they are cached on Apigee or not. We would then place this policy in response flow after ResponseCache policy and anywhere on DefaultFaultRules.

View solution in original post

21 REPLIES 21

If the policy doesn't appear in trace would you verify that you are tracing the correct revision/environment?

Not applicable

Can you please try this ?

<AssignMessage name="AssignMessage.ForwardUserInfo">
	<Set>
		<Headers>
            		<Header name="X-Apigee-UserName">{accesstoken.username}</Header>        </Headers>
	</Set>
</AssignMessage>

@Daniel Barnes ,

I can reproduce your issue. Looks like Apigee converts the header into lower case before sending the request to target. Nothing wrong with your assign message policy. Just use lower case letters while accessing the header in your target. It should work. Yeah, Agree, It's weird that apigee converts case. Atleast trace should show correct case. It's a bug in trace.

See attached API proxy where i can retrieve the header in NodeJS target endpoint using lower case letters.

customheaderassignmessage-rev2-2016-10-28.zip

My Node target code,

var http = require('http');


console.log('node.js application starting...');


var svr = http.createServer(function(req, resp) {
    var headers = req.headers;
    var apigeeUserName = headers['x-apigee-username'];
    resp.end('Hello, World! ' + apigeeUserName);
});


svr.listen(9000, function() {
    console.log('Node HTTP server is listening');
});

And it's working, http://anildevportal-test.apigee.net/customheaderassignmessage

Hope it helps. Keep us posted if any.

Hello @Anil Sagar

This still isn't working. My header is still returning null.

Could it be an issue with the apigee implementation returning null or not working as I cannot see it at all in the trace?

Daniel

@Daniel Barnes , It should work. See above sample proxy. It should show up in trace. Send me sample CURL call using "Ask An Expert" button , I will investigate.

@Anil Sagar I have sent CURL.

Hello @Anil Sagar

Hello Anil, Thank you for your response. This does make sense to me in what is happening but where in ResponseCache.Data is it terminating?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResponseCache name="ResponseCache.Data">
    <CacheKey>
        <KeyFragment ref="flow.preqin.cache.response.identifier"/>
    </CacheKey>
    <ExpirySettings>
        <TimeoutInSec ref="flow.preqin.configuration.cache.response.ttl">600</TimeoutInSec>
    </ExpirySettings>
    <CacheResource>data-v1-responsecache</CacheResource>
    <SkipCacheLookup>request.header.X-Apigee-SkipCache = "true"</SkipCacheLookup>
    <SkipCachePopulation>response.status.code != 200</SkipCachePopulation>
</ResponseCache>

Hello @Anil Sagar or anybody else, can anybody please point me in the direction of where my ResponseCache object above is terminating.

@Daniel Barnes ,

Response cache policy is getting hit in Target Endpoint Preflow, As long as response cache is there, Request will never hit your target server. Cache data is returned from your proxy.

Hello @Anil Sagar

Thanks for the reply,

How do we stop this happening then so it just continues on?

Daniel.

@Daniel Barnes , You can just remove response cache policy so that it hits the target server. But, you haven't told us the reason behind using the response cache policy. Ideally, ResponseCache policy should have expiry time as well as invalidate cache / skip cache conditions. I don't see any.

Hello @Anil Sagar

Thank you very much for the continued assistance and sorry for my not so helpful replies.


Unfortunately because I didn't write this I find it hard to fully understand it at present. I can promise I am trying my best to get as up to speed on the apigee implementation as quickly as possible and after today I should have a lot more time.


I believe the response cache policy caches the data being requested from the user.

Daniel

@Daniel Barnes , Yes, It caches the data in Apigee Edge. Also, If you send the request with header X-Apigee-SkipCache with value true, It should skip the response cache policy as per your policy.

<SkipCacheLookup>request.header.X-Apigee-SkipCache = "true"</SkipCacheLookup>

Hello @Anil Sagar

I understand what you are saying but surly I want it to cache and then return the headers as expected.

As I understand it I want it to do both. The caching and then the AssignMessage.ForwardUserInfo policy.

Daniel

@Daniel Barnes ,

Here is how it works,

Scenario 1 : No data cached in Apigee Edge,

  • API Request Made
  • Proxy reqest preflow execute
  • Proxy request postflow executes
  • Target request preflow executes
    • Here it finds response cache policy in request
    • Since, No cached data, It skips
  • Target request postflow executes
    • Your Assing Message Policy executes & sets custom headers
  • API Request hits target server
  • Target server logic executes
  • Target sends response to Apigee
  • Apigee Target Response Preflow executes
    • Find response cache policy, Remember, Response cache policy should be attached both to request & response
    • Executes response cache policy, caches the data in Apigee Edge.
  • Sends back the response to the client.

Scenario 2 : Scenario 1 is already executed & cached data is available in Apigee.

  • API Request Made
  • Proxy reqest preflow execute
  • Proxy request postflow executes
  • Target request preflow executes
    • Here it finds response cache policy in request
    • It finds cached data, Returns cache data to the client. All further steps are skipped.

In your case, scenario 2 is keep executing because of cached data & you don't see any request coming to target server. Hope it helps.

Hi @Daniel Barnes,

  1. In trace, if you have "Show Skipped Phases" enabled AND you don't see an arrow on the policy in the map view, then it is executed. If there is an arrow, then Apigee is skipping execution of this policy most probably because of the condition attached to that step.
  2. If you have "Show Skipped Phases" disabled AND you see the policy, then it is executed. If you can't see the policy, it is not executed.
  3. If you have response cache policy configured for the flow and if that response has already been cached by Apigee, Apigee will automatically respond to the client with the value from the cache. In this situation you will not see any request coming to your target servers.

Hello @Ozan Seymen

Thanks for the reply.

So in regards to point 3 if its already in the case and returns with the value from the cache the headers will not get return to the client which means we can not get user details from the headers.

It seems that the headers are never returned.

Daniel.

Hi @Daniel Barnes - you should see correct headers coming to your target if this is the first request for your cache key. You can also simulate that by clearing the cache resource associated with that ResponseCache.

Hi @Daniel Barnes, the whole point of the cache is for Apigee to respond to client requests without bothering the server. So by definition, no requests will reach your target as Apigee is responding from its cache as if Apigee sends the request to your target, caching on Apigee would be unnecessary. We would just return the response we got from your target.

The pattern we should follow for logging is to put a JS policy which would send a request asynchronously to some endpoint in your target so that you can get data you require. This is if you want logging for ALL requests irrespective of whether they are cached on Apigee or not. We would then place this policy in response flow after ResponseCache policy and anywhere on DefaultFaultRules.

Hey @Ozan Seymen

Its not really just about Logging its also about what data is returned and I need to know who the user is in the actual API but I suppose if they have been given the data once then it will be cached and the correct data is returned the next time so that should be fine.

When testing it though it would seem those headers with user data are never populated.

Daniel.

Hello @Ozan Seymen

Thank you so much I think I have this worked out now and can see what is happening.

Daniel.

PS. Looking forward to looking at the new edge environment now.