AssignMessage SET request values missing in Target request if JavaCallout is in between

I was trying Dino's AWS Signing V4 - Java callout.  In Target Request Pre-flow:

1. I was using AssignMessage to prepare request.

<AssignMessage continueOnError="false" enabled="true" name="AM-ConstructBackendRequest">
  <DisplayName>AM-ConstructBackendRequest</DisplayName>
  <Properties/>
  <Remove/>
  <Set>
    <Headers>
      <Header name="x-id">{private.id}</Header>
      <Header name="x-scopes">Data.Read</Header>
      <Header name="x-no-of-rows">12</Header>
    </Headers>
    <QueryParams>
      <QueryParam name="from-date">{fromDate}</QueryParam>
      <QueryParam name="to-date">{toDate}</QueryParam>
    </QueryParams>
    <Verb>GET</Verb>
    <Path>/</Path>
  </Set>
  <AssignTo createNew="true" transport="http" type="request">lambdaRequest</AssignTo>
</AssignMessage>
 
2. In AWS Signing Java callout, I refer lambdaRequest as source.
 
In the AssignMessage I have tried createNew="false" or using <AssignTo>Request</AssignTo>.. In debug, I could see the AssignMessage setting all headers; but once JavaCallout is executed, it only sets the signing headers set by Java callout.  When the request is sent to Target server, the headers set in the AssignMessage are missing.  
 
I had to create a new request object (createNew="true"), and after Javacallout, copy that object into request using another AssignMessage policy step(after removing all existing request parameters with <Remove/>).   Can you please check it out; looks like this problem is there in other callouts as well (tried Python callout, it also seem to reset the values).  Looks like this is specific to Target request; because the example for AWSSigning uses ServiceCallout - am sure that would have been tested.  The same sequence for Target request is not working.
 
Thanks,
Muthu  
 
 
Solved Solved
1 5 177
1 ACCEPTED SOLUTION

That's strange. When I try it on my Apigee X instance, it works as I would expect:  AssignMessage sets headers, the Java callout sets additional headers and signs things (including the original headers), and ... the target gets all of the headers.

For my test proxy, I used an "echo" target , which just echo's back what it receives. In the response I can see that the target has received all the headers. 

$ curl -i $endpoint/muthu-20230919/t1 
HTTP/2 200 
version: 20230113-1204
content-type: application/json; charset=utf-8
etag: W/"365-ruPUZhM1ePIvc+0zfzEUEMc6O00"
x-cloud-trace-context: b9baabc0a526e23dc78dfa9a19a00d73
date: Tue, 19 Sep 2023 16:38:38 GMT
content-length: 869
apiproxy: muthu-20230919 r1
x-request-id: 24e6fee8-330e-492b-a7d4-d8f698a2cdd4
via: 1.1 google
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

{
  "url": "/t1?from-date=10-08-2023&to-date=15-08-2023",
  "method": "GET",
  "headers": {
    "host": "example.demo.altostrat.com",
    "x-id": "123456",
    "x-scopes": "Data.Read",
    "x-no-of-rows": "12",
    "x-amz-date": "20230919T163838Z",
    "authorization": "AWS4-HMAC-SHA256 Credential=xWxTestKeyxWx/20230919/ap-south-1/lambda/aws4_request, SignedHeaders=host;x-amz-date;x-id;x-no-of-rows;x-scopes, Signature=20ee3afde9222f4f4cef8cc1c5f215eaadb571b05907d82c397dfbc7b609b139",
    "x-cloud-trace-context": "b9baabc0a526e23dc78dfa9a19a00d73/14516245761368739297",
    "traceparent": "00-b9baabc0a526e23dc78dfa9a19a00d73-c974109c0ea74de1-00",
    "x-forwarded-for": "0.0.0.0",
    "x-forwarded-proto": "https",
    "forwarded": "for=\"0.0.0.0\";proto=https"
  },
  "query": {
    "from-date": "10-08-2023",
    "to-date": "15-08-2023"
  },
  "body": {}
}%                                                                        

Attached please find my test proxy. You will need to configure your own echo service in the target. 

 

View solution in original post

5 REPLIES 5

In debug, I could see the AssignMessage setting all headers; but once JavaCallout is executed, it only sets the signing headers set by Java callout. When the request is sent to Target server, the headers set in the AssignMessage are missing.

I have some comments.

If you specify lambdaRequest in the AssignMessage and lambdaRequest for the Javacallout , then the callout will place the results of the signing  into lambdaRequest. But the Apigee target won't use lambdaRequest ! It uses the target request. So ... you are setting things on a request message that ... I suppose, never gets sent out. I can't see your proxy, so I don't know for sure, but that's what it sounds like to me.

It would be appropriate for you to use a custom request, like lambdaRequest, if you were subsequently going to use ServiceCallout to send that request out. In ServiceCallout you can specify the request variable (eg, lambdaRequest), and then it will send THAT out. That does not work with the target flow. The target flow always sends out "request". 

In the AssignMessage I have tried createNew="false" or using <AssignTo>Request</AssignTo>.

...and you're seeing the same results? First, let's make sure you've got your casing correct. The correct form would be

 

<AssignTo>request</AssignTo>

 

Lowercase. Case is important. In the snip you showed, the request was capitalized. That's not the same.

Second, make sure that is the name of the message that you specified in the JavaCallout as well.  Both AssignMessage and JavaCallout must specify the same message. 

Assuming that you were actually using the lowercase form of request, and you are specifying it consistently in both AssignMessage and the JavaCallout, if you are seeing the same results, that is curious. At the inception of the Target flow (before Target Preflow), Apigee copies the proxy request message to the target request message. Using <AssignTo>request</AssignTo> in your AssignMessage policy ought to set the target request. Maybe for some reason it is not working as we expect. Perhaps you can try <AssignTo>message</AssignTo>. And of course you need to modify the JavaCallout in the same way.

Good luck.

Hi Dino,

Thanks for the response. Yes, I tried with 'request' in both AssignMessage and in Callout.  And also have tried with 'message' as you have suggested.  The result is same; in AssignMessage it sets the required headers and in Java callout it sets additional 3 headers; to the target only those three are being sent to target (whatever were set in AssignMessage are missing) 

I created a test proxy with just two policies; 

1. AssignMessage  - to prepare the request

<AssignMessage name="AM-PrepareLambdaRequest">
  <Remove/>
  <Set>
    <Headers>
      <!-- <Header name="X-Amz-Invocation-Type">RequestResponse</Header> -->
      <Header name="x-id">123456</Header>
      <Header name="x-scopes">Data.Read</Header>
      <Header name="x-no-of-rows">12</Header>
    </Headers>
    <QueryParams>
      <QueryParam name="from-date">10-08-2023</QueryParam>
      <QueryParam name="to-date">15-08-2023</QueryParam>
    </QueryParams>
    <Verb>GET</Verb>
    <Path>/</Path>
  </Set>
  <AssignTo>message</AssignTo>
</AssignMessage>

2. Java callout

<JavaCallout name="Java-AWSSignv4">
  <DisplayName>Java-AWSSignv4</DisplayName>
  <Properties>
    <Property name="debug">true</Property>
    <Property name="service">lambda</Property>
    <Property name="endpoint">http://mocktarget.apigee.net</Property>
    <Property name="region">ap-south-1</Property>
    <Property name="key">xWxTestKeyxWx</Property>
    <Property name="secret">yTyTestSecretyTy</Property>
    <!--<Property name="sign-content-sha256">true</Property>-->
    <!--<Property name="insure-trailing-slash">true</Property> -->
    <Property name="source">message</Property>
  </Properties>
  <ClassName>com.google.apigee.callouts.AWSV4Signature</ClassName>
  <ResourceURL>java://apigee-callout-awsv4sig-20230705.jar</ResourceURL>
</JavaCallout>

I am using mocktarget as Target endpoint; the purpose is just to verify the target request being sent.   I have attached the debug trace screenshot.  To overcome this, I had to create a new request object, and after callout add another AssignMessage (actually two AssignMessage policies, because of a different problem in AssignMessage - removing & setting existing headers in same policy results in missing those headers; will put in a different question, so that it can be tracked), to copy the contents of it to the 'request'.

Thanks,

Muthu

Target RequestTarget RequestAfter AssignMessageAfter AssignMessage

That's strange. When I try it on my Apigee X instance, it works as I would expect:  AssignMessage sets headers, the Java callout sets additional headers and signs things (including the original headers), and ... the target gets all of the headers.

For my test proxy, I used an "echo" target , which just echo's back what it receives. In the response I can see that the target has received all the headers. 

$ curl -i $endpoint/muthu-20230919/t1 
HTTP/2 200 
version: 20230113-1204
content-type: application/json; charset=utf-8
etag: W/"365-ruPUZhM1ePIvc+0zfzEUEMc6O00"
x-cloud-trace-context: b9baabc0a526e23dc78dfa9a19a00d73
date: Tue, 19 Sep 2023 16:38:38 GMT
content-length: 869
apiproxy: muthu-20230919 r1
x-request-id: 24e6fee8-330e-492b-a7d4-d8f698a2cdd4
via: 1.1 google
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

{
  "url": "/t1?from-date=10-08-2023&to-date=15-08-2023",
  "method": "GET",
  "headers": {
    "host": "example.demo.altostrat.com",
    "x-id": "123456",
    "x-scopes": "Data.Read",
    "x-no-of-rows": "12",
    "x-amz-date": "20230919T163838Z",
    "authorization": "AWS4-HMAC-SHA256 Credential=xWxTestKeyxWx/20230919/ap-south-1/lambda/aws4_request, SignedHeaders=host;x-amz-date;x-id;x-no-of-rows;x-scopes, Signature=20ee3afde9222f4f4cef8cc1c5f215eaadb571b05907d82c397dfbc7b609b139",
    "x-cloud-trace-context": "b9baabc0a526e23dc78dfa9a19a00d73/14516245761368739297",
    "traceparent": "00-b9baabc0a526e23dc78dfa9a19a00d73-c974109c0ea74de1-00",
    "x-forwarded-for": "0.0.0.0",
    "x-forwarded-proto": "https",
    "forwarded": "for=\"0.0.0.0\";proto=https"
  },
  "query": {
    "from-date": "10-08-2023",
    "to-date": "15-08-2023"
  },
  "body": {}
}%                                                                        

Attached please find my test proxy. You will need to configure your own echo service in the target. 

 

Hi Dino,

Yes, the header values are getting set.  It is just that in the trace it is not capturing (.xml) - so it is not displaying.  I assumed trace was working properly.  

Thanks a lot.

 

 

ok

Well I'm glad the call is working. If you want to diagnose the surprise you're seeing in the Debug Trace experience, I can try to help you with that too. Or, if you'd just like to move on, that's fine with me, too.