Request Message not available while using ServiceCallout & Assign Message with createnew="false"

Hi All,

Request message/payload is not forwarded to target even though createnew="false" in Assign Message Policy (all query params and Headers are available but not payload). Please find the policies below.

Key Value Map Operations:

 

 

<!-- Key/value pairs can be stored, retrieved, and deleted from named existing maps by configuring this policy by specifying PUT, GET, or DELETE operations -->
<!-- mapIdentifier refers to the name of the key value map -->
<!-- Don't use Key Value Maps to store your logs as this can impact API Proxy runtime flow -->
<KeyValueMapOperations mapIdentifier="Sharepoint_Cred" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
	<!-- PUT stores the key value pair mentioned inside the element -->
<Get assignTo="private.tenant_id">         
   <Key>             
      <Parameter>tenant_id</Parameter>         
   </Key>     
</Get>
<Get assignTo="private.Site">         
   <Key>             
      <Parameter>Site</Parameter>         
   </Key>     
</Get>
<Get assignTo="private.resource_id">         
   <Key>             
      <Parameter>resource_id</Parameter>         
   </Key>     
</Get>
<Get assignTo="private.client_secret">         
   <Key>             
      <Parameter>client_secret</Parameter>         
   </Key>     
</Get>
<Get assignTo="private.client_id">         
   <Key>             
      <Parameter>client_id</Parameter>         
   </Key>     
</Get>
	<!-- the scope of the key value map. Valid values are environment, organization, apiproxy and policy -->
<Scope>environment</Scope>
</KeyValueMapOperations>

 

 

Javascript

here I had to store request payload in "payl" variable and use in later.

 

 

context.setVariable("client_id",context.getVariable("private.client_id").concat("@",context.getVariable("private.tenant_id")))
context.setVariable("resource",context.getVariable("private.resource_id").concat("/",context.getVariable("private.Site"),"@",context.getVariable("private.tenant_id")))
context.setVariable("client_secret",context.getVariable("private.client_secret"))
context.setVariable("token_url","https://accounts.accesscontrol.windows.net/".concat(context.getVariable("private.tenant_id"),"/tokens/OAuth/2"))
print(context.getVariable("request.content"))
context.setVariable("payl",context.getVariable("request.content"))

 

 

Assign Message: Here createNew="false" which means existing request message object payload should be preserved (as headers query params are preserved from request)

 

 

<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
	<!-- Sets a new value to the existing parameter -->
<Add>
    <FormParams>
      <FormParam name="grant_type">client_credentials</FormParam>
      <FormParam name="client_id">{client_id}</FormParam>
      <FormParam name="client_secret">{client_secret}</FormParam>
      <FormParam name="resource">{resource}</FormParam>
    </FormParams>
</Add>
<Set>
  <Path>/</Path>
  <!--<Path></Path>-->
</Set>
	<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
	<!--<AssignTo createNew="true" type="request">requ</AssignTo>-->
	<!--<AssignTo createNew="true" type="request"></AssignTo>-->
	<AssignTo createNew="false" type="request"></AssignTo>
</AssignMessage>

 

 

Service callout

 

 

<ServiceCallout async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
	<!-- The request that gets sent from the API proxy flow to the external service -->
	<Request variable="request"/>
	<!--<Request/>-->
	<!-- the variable into which the response from the external service should be stored -->
	<Response>TokenResp</Response>
	<!-- The time in milliseconds that the Service Callout policy will wait for a response from the target before exiting. Default value is 120000 ms -->
	<Timeout>30000</Timeout>
	<HTTPTargetConnection>
		<!-- The URL to the service being called -->
		<URL>https://accounts.accesscontrol.windows.net/{private.tenant_id}/tokens/OAuth/2</URL>
      <!-- The SSL reference to be used to access the https url -->
 <SSLInfo>  
    <Enabled>true</Enabled> 
     <ClientAuthEnabled>false</ClientAuthEnabled> 
     <KeyStore/> 
     <KeyAlias/> 
     <TrustStore/> 
     <Ciphers/> 
     <Protocols/> 
 </SSLInfo> 
	</HTTPTargetConnection>
</ServiceCallout>

 

 

Extract Variables:

 

 

<!-- Extract content from the request or response messages, including headers, URI paths, JSON/XML payloads, form parameters, and query parameters -->
<ExtractVariables async="true" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
	<!-- the source variable which should be parsed -->
	<Source>TokenResp</Source>
	<!-- Specifies the XML-formatted message from which the value of the variable will be extracted -->
<JSONPayload>
   <Variable name="accessTok" type="string">
      <JSONPath>$.access_token</JSONPath>
   </Variable>
</JSONPayload>
</ExtractVariables> 

 

 

Assign Message:

 

 

<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
 
	<!-- Sets a new value to the existing parameter -->
	<!--<Set>
		<Payload contentType="application/json" variablePrefix="@" variableSuffix="#">{"name":"foo", "type":"@apiproxy.name#"}</Payload>
	</Set>-->
	<Set>
	    <Payload contentType="text/xml">{payl}</Payload>
	</Set>
	<Add>
	    <Headers>
	        <Header name ="Auth">Bearer {accessTok}</Header>
	    </Headers>
	</Add>
	<Remove>
	  <FormParams>
      <FormParam name="grant_type"></FormParam>
      <FormParam name="client_id"></FormParam>
      <FormParam name="client_secret"></FormParam>
      <FormParam name="resource"></FormParam>
    </FormParams> 
	</Remove>
	<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
	<AssignTo createNew="false" type="request"></AssignTo>
</AssignMessage>

 

 

Could you please help to forward the request message to target endpoint(without copying into variable and using it later as mentioned in JS above). Here form params are also removed which may be conflicting the actual xml payload sent as request to Apigee proxy endpoint.

Regards,

Sachin Belide

Solved Solved
0 2 146
1 ACCEPTED SOLUTION

It's a little bit difficult to follow the behaviour you're observing and what you're expecting at different points in time. One thing I've noted is you've stated for the first Assign message policy 

"Assign Message: Here createNew="false" which means existing request message object payload should be preserved (as headers query params are preserved from request)"

However, by setting FormParams, you are overriding the existing request.content so if there's an existing payload, that will be lost. Although headers and query parameters as mentioned should be preserved

View solution in original post

2 REPLIES 2

It's a little bit difficult to follow the behaviour you're observing and what you're expecting at different points in time. One thing I've noted is you've stated for the first Assign message policy 

"Assign Message: Here createNew="false" which means existing request message object payload should be preserved (as headers query params are preserved from request)"

However, by setting FormParams, you are overriding the existing request.content so if there's an existing payload, that will be lost. Although headers and query parameters as mentioned should be preserved

Hi @dknezic ,

Thankyou for the response. Instead of creating a new request message object with new variable/new request message, I thought of using existing with createnew="false" and it is now clear that I am overwriting existing message object with form params where source payload is lost.