I have created an API in WSO2 Micro Integrator to invoke a backend which require to pass each time the token in header ,I have implemented this use case by invoking two backend ,the first one will generate the token then save the token in a property and finally send the token to the second backend to be invoked as shown below my config file :
<?xml version="1.0" encoding="UTF-8"?>
<api context="/crmtest" name="crmtest" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/crm1">
<inSequence>
<property name="client_id" scope="default" type="STRING" value="************"/>
<property name="client_secret" scope="default" type="STRING" value="************"/>
<property name="grant_type" scope="default" type="STRING" value="client_credentials"/>
<property name="resource" scope="default" type="STRING" value="https://************.com"/>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root>
<client_id>$1</client_id>
<client_secret>$2</client_secret>
<grant_type>$3</grant_type>
<resource>$4</resource>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$ctx:client_id"/>
<arg evaluator="xml" expression="$ctx:client_secret"/>
<arg evaluator="xml" expression="$ctx:grant_type"/>
<arg evaluator="xml" expression="$ctx:resource"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<call>
<endpoint>
<http method="post" uri-template="https://login.microsoftonline.com/************f/oauth2/token">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<property name="token" scope="default" type="STRING" expression="json-eval($.access_token)"/>
<log>
<property expression="get-property('token')" name="tt"/>
</log>
<property name="bearer" scope="transport" type="STRING" value="Bearer "/>
<property expression="concat(get-property('bearer'),get-property('token'))" name="Authorization" scope="transport" type="STRING"/>
<call>
<endpoint>
<http method="post" uri-template="https://************.com/api/data/v9.2/ext_APICreateOffre">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
The problem that the token is generated successfully but i didn't got the right response from the backend as shown below:
{
"error": {
"code": "0x80048d19",
"message": "Error identified in Payload provided by the user for Entity :'', For more information on this error please follow this help link https://go.microsoft.com/fwlink/?linkid=2195293 ----> InnerException : Microsoft.OData.ODataException: The parameter 'token_type' in the request payload is not a valid parameter for the operation 'ext_APICreateOffre'.\r\n at Microsoft.OData.ODataParameterReaderCore.GetParameterTypeReference(String parameterName)\r\n at Microsoft.OData.JsonLight.ODataJsonLightParameterDeserializer.<>c__DisplayClass3_0.<ReadNextParameter>b__0(PropertyParsingResult propertyParsingResult, String parameterName)\r\n at Microsoft.OData.JsonLight.ODataJsonLightDeserializer.ProcessProperty(PropertyAndAnnotationCollector propertyAndAnnotationCollector, Func`2 readPropertyAnnotationValue, Action`2 handleProperty)\r\n at Microsoft.OData.JsonLight.ODataJsonLightParameterDeserializer.ReadNextParameter(PropertyAndAnnotationCollector propertyAndAnnotationCollector)\r\n at Microsoft.OData.ODataParameterReaderCore.ReadImplementation()\r\n at Microsoft.OData.ODataParameterReaderCore.InterceptException[T](Func`1 action)\r\n at Microsoft.Crm.Extensibility.ODataV4.CrmODataActionPayloadDeserializer.Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)."
}
}
Is there any best approch to implement this use case .
I tried what @sanoJ say in the comment and it works fine by using the OAuth HTTP endpoint.
As the configuration below :
<?xml version="1.0" encoding="UTF-8"?>
<api context="/API" name="API" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/CreateOffre">
<inSequence>
<call>
<endpoint>
<http method="post" uri-template="https://********.dynamics.com/api/data/v9.2/********">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
<authentication>
<oauth>
<clientCredentials>
<clientId>********</clientId>
<clientSecret>********</clientSecret>
<tokenUrl>https://login.microsoftonline.com/********/oauth2/token</tokenUrl>
<requestParameters>
<parameter name="resource">https://********.dynamics.com</parameter>
</requestParameters>
<authMode>header</authMode>
</clientCredentials>
</oauth>
</authentication>
</http>
</endpoint>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>