I have created a custom sequence in wso2am, in order to convert a rest web service call, to a soap call.
I would like to have the username of the user that makes the actual call, so as to log it, and use it in the soap body.
I tried by accessing the tenant.id and tenant domain variables but the are not available. I tried the END_USER_NAME var but that was also null
<property name="domain" expression="$ctx:tenant.info.domain" />
<property name="user" expression="substring-before(get-property('END_USER_NAME'), '#')" />
Is something like that possible?
if not, is it possible to deduce the username by means of the authheader?
I think you can use context property api.ut.userId in your sequence.
For example
<property name="user" expression="substring-before(get-property('api.ut.userId'), '#')" />
You can get the username from JWT token. Look here for enabling JWT token. Then extract any user claim youwant. I had explained it at,
http://lahiruwrites.blogspot.com/2016/06/access-jwt-token-in-mediator-extension.html.
Pasting below for your reference(You can see how to get enduser),
<?xml version="1.0" encoding="UTF-8"?>
<sequence
xmlns="http://ws.apache.org/ns/synapse" name="Test:v1.0.0--In">
<log level="custom">
<property name="--TRACE-- " value="API Mediation Extension"/>
</log>
<property name="authheader" expression="get-property('transport','X-JWT-Assertion')"></property>
<script language="js"> var temp_auth = mc.getProperty('authheader').trim();var val = new Array();val= temp_auth.split("\\."); var auth=val[1];var jsonStr = Packages.java.lang.String(Packages.org.apache.axiom.om.util.Base64.decode(auth), "UTF-8"); var tempStr = new Array();tempStr= jsonStr.split('http://wso2.org/claims/enduser\":\"'); var decoded = new Array();decoded = tempStr[1].split("\"");mc.setProperty("enduser",decoded[0]); </script>
<log level="custom">
<property name=" Enduser " expression="get-property('enduser')"/>
</log>
</sequence>
Related
<property name="Code" expression="json-eval($.Code)" scope="default" type="STRING"/>
<property name="Endpoint" expression="json-eval($.data.InternalConfig.Events.Code.Endpoint)" scope="default"
<property expression="fn:concat(json-eval($.data.InternalConfig.Events'.'get-property('Code')'.'Endpoint)" name="URL" type="STRING" scope="default"/>
one property is fetching from payload and another from respository , i am trying to merge into 1 property
I believe that you are trying to extract the data from the payload using dynamic values during the runtime. If yes, we can make use of Script Mediator in the WSO2 platform to access the JSON payloads.
For example:
Given below is a sample payload, and you are trying to extract the data: 'some value here' from the payload using the code and endpoint values
{
"userId": 10,
"code": 1,
"body": {
"id": 2,
"endpoint": "some-key",
"1": {
"anotherId": 30,
"title": "Lorum ipsum",
"some-key": "some value here"
}
}
}
Given below is a sample mediation sequence with the Script mediator to achieve your requirement
<?xml version="1.0" encoding="UTF-8"?><sequence xmlns="http://ws.apache.org/ns/synapse" name="mediation-sequence">
<script language="js">
<![CDATA[
// read the JSON payload from the message context
var payload = mc.getPayloadJSON();
// read the property values
var code = payload["code"];
var endpoint = payload["body"]["endpoint"];
var extracted_value = payload["body"][code][endpoint];
// set the extracted value as property to message context
mc.setProperty("ExtractedValue", extracted_value);
]]>
</script>
<log level="custom">
<property name="Extracted value" expression="$ctx:ExtractedValue" />
</log>
</sequence>
Hope this helps you to achieve your requirement.
I have a special requirement.
I want to access WSO2 backen API.
So,I want to publish it on WSO2.
So that,my service can access WSO2'API.
Can someone tell me how to do it?
WSO2 API Manager exposes a REST API to for operations like publish and subscribe. You can see the list of all the services here: https://docs.wso2.com/display/AM200/Published+APIs.
It also offers Swagger definition files for those same APIs: https://raw.githubusercontent.com/wso2/carbon-apimgt/v6.0.4/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher/src/main/resources/publisher-api.yaml.
I haven't tried it, but given the fact that all you need to publish a managed API in WSO2 is a Swagger file and an existing endpoint, there is nothing preventing you to create an API for WSO2 APIM inside itself.
Theoretically, this should be fine.
WSO2 API manger plays the middleware role for its own APIs just as for any other third party API.
Let's say that you want to publish any of the Admin APIs of the api manager through the api manager itself. You just need to add endpoint information just as you would do for any other api.
Then, once a user wants to access the api, they have to first get a access token by calling the token endpoint, then use that token to execute the published api.
Access you API-Manager on: http://localhost:9443/publisher
Click on your api
Click on tab "Lifecycle"
Click on "Publish"
WS02 API means are you referring to Wso2 API manager?
Because you can also implement API's using Wso2 ESB.
You can have more control over the code of API using Wso2 ESB but you cannot have throttling and other control using ESB you have to use APIM.
You shoould have an endpoint to connect your API.
Then follow the below steps
Login in your API Manager (Publisher) Instance.
+ Add new API
If you have an endpoint: Click on Design a new Rest API
Fill the values like name, context, version and description.
Add a new API Specification. (i.e: GET /test)
Click on Next:Implement
Select Managed API
Endpoint Type: HTTP/REST Endpoint
Endpoint: Fill your endpoint's url without context.
Click on Next: Manage
Fill values like type of subscription.
If you have a public API, don't forget change the second column of your API specification resources. Change the value for: None
Click on Save & Publish
Go to WSO2 Store and check
While going through the answers and the replies that you have provided, I believe you know how to publish an API with a WSO2 API as an endpoint. However, your concern is how to handle the authorization since the backend itself needs a valid OAuth token to be invoked? Please correct me if my understanding is wrong.
If that is the case, I believe you can simply achieve it with a help of a custom mediation. The below sample mediation is to invoke the token endpoint and generate a token. Once the token is generated you can simply add that to the request header.
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="simple-token-gen" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property description="access_token" expression="get-property('registry', 'local:/api-backend-credentials/pizzaOrderingAPI/access_Token')" name="access_token" scope="default" type="STRING"/>
<property description="generated_time" expression="get-property('registry','local:/api-backend-credentials/pizzaOrderingAPI/generated_Time')" name="generated-time" scope="default" type="LONG"/>
<property description="client_credentials" name="app-client-auth" scope="default" type="STRING" value="{base64encoded(clientKey:clientSecret)}"/>
<property expression="json-eval($)" name="message-body" scope="default" type="STRING"/>
<property expression="get-property('axis2','REST_URL_POSTFIX')" name="resource" scope="default" type="STRING"/>
<filter description="" xpath="get-property('SYSTEM_TIME') - get-property('generated-time') > 3600000 or get-property('access_token') = ''">
<then>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root xmlns="">
<grant_type>client_credentials</grant_type>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args/>
</payloadFactory>
<header expression="fn:concat('Basic ', get-property('app-client-auth'))" name="Authorization" scope="transport"/>
<header name="Content-Type" scope="transport" value="application/x-www-form-urlencoded"/>
<property description="messageType" name="messageType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<property description="REST_URL_POSTFIx" name="REST_URL_POSTFIX" scope="axis2" type="STRING" value=""/>
<call blocking="true">
<endpoint name="token">
<http method="post" uri-template="{token-endpoint-url}"/>
</endpoint>
</call>
<property expression="get-property('resource')" name="REST_URL_POSTFIX" scope="axis2" type="STRING"/>
<property description="generated Time Setter" expression="get-property('SYSTEM_TIME')" name="local:/api-backend-credentials/pizzaOrderingAPI/generated_Time" scope="registry" type="LONG"/>
<property description="generated_token" expression="json-eval($.access_token)" name="generated-access-token" scope="default" type="STRING"/>
<property description="new Token setter" expression="get-property('generated-access-token')" name="local:/api-backend-credentials/pizzaOrderingAPI/access_Token" scope="registry" type="STRING"/>
<header expression="fn:concat('Bearer ', get-property('generated-access-token'))" name="Authorization" scope="transport"/>
<payloadFactory media-type="json">
<format>
$1
</format>
<args>
<arg evaluator="xml" expression="get-property('message-body')"/>
</args>
</payloadFactory>
</then>
<else>
<header expression="fn:concat('Bearer ', get-property('access_token'))" name="Authorization" scope="transport"/>
</else>
</filter>
</sequence>
Replace the placeholders with corresponding values.
{base64encoded(clientKey:clientSecret)} - The client key and client
secret, separated by a colon and base64 encoded. {token-endpoint-url}
The token endpoint URL of the backend authorization server.
I believe this helps you with your concern.
If I understood correctly, It has no sense to publish WSO2 AM APIs in the API Manager. First reason is that WSO2 AM APIs are accesed by Basic Auth, that it is not implemented by default in WSO2 AM. The default security for APIs en WSO2 is OAuth2, so you would have to do a extension for that. You may check here: https://docs.wso2.com/display/AM260/apidocs/publisher/#guide
Also, these internal APIs for WSO2 AM are meant to be accesed by an admin or so, so it has no sense to expose these as an API to be consumed for other suscriptors.
Anyway, if you implemented an authenticator to run with Basic Auth, you may expose this APIs in API Manager, or expose these APIs disabling default OAuth2 security.
BR
How to retrieve HTTP REST METHOD(GET,PUT,POST,DELETE,OPTIONS) in WSO2 Api Manager's Sequence at runtime? I tried to $ctx:REST_METHOD which returns 'null' value.
<sequence name="ec_rest_dynamic_ep" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property expression="$ctx:REST_METHOD" name="restmethod"
scope="default" type="STRING"/>
<log>
<property expression="get-property('restmethod')" name="*******************REST_METHOD***********"/>
</log>
</sequence>
Basically, HTTP REST METHOD value of current service & URL context of that service needed to identify the service in order redirect the service to its endpoint dynamically at runtime.
Try the following property.
<property name="Http_Method" expression="get-property('axis2', 'HTTP_METHOD')"/>
You can find more useful properties in [1].
#Pubci's answer is correct. Here is another way.
<property name="Method" scope="transport" expression="$ctx:api.ut.HTTP_METHOD"/>
Some other properties can be found here.
I want to get a URI VAR value from request to call correct case in switch in WSO2 ESB API resource, like this:
<api name="apk" context="/apk"><resource methods="GET" uri-
template="/apk/{appName}"><inSequence><header name="App"
scope="transport" action="remove"/><switch source="get-
property('uri.var.appName')"><case regex="BEBE"><send><endpoint><http
method="GET" uri-template="http://localhost/apk/Bebe.apk></http>
</endpoint></send></case><case regex="CITAS"><send><endpoint><http
method="GET" uri-template="http://localhost/apk/Citas.apk></http>
</endpoint></send></case></switch></inSequence></resource></api>
In switch, source="get-property('uri.var.appName')" it's not correct.
Can I get this value using $url SynapseXpath valiables like $url?
What you have done is correct. Please try the same with a log mediator and see whether you get the value properly.
<log level="custom">
<property name="AppName" expression="get-property('uri.var.appName')"/>
</log>
Alternatively you can assign this to a property and use that inside your switch mediator.
I am building a ReST to ReST proxy service. I need to be able to pass along some query parameters to that service that are incoming with the request. E.g.
myhost.zz/proxyService?foo=1&bar=2
When I define such proxy - and later try to extract the value of 'foo' I get null.
So is it possible to achieve?
You shouls define an API (if you really want a proxy service, look at the end of this answer) :
<api xmlns="http://ws.apache.org/ns/synapse" name="proxyService" context="/proxyService">
<resource methods="POST GET OPTIONS DELETE PUT">
<inSequence>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"></property>
<log level="custom">
<property name="foo" expression="get-property('query.param.foo')"></property>
<property name="bar" expression="get-property('query.param.bar')"></property>
</log>
</inSequence>
</resource>
</api>
call it with this url : http://host:port/proxyService?foo=12&bar=14
look at wso2-esb-service.log : INFO __SynapseService foo = 12, bar = 14
in the "resource", you can define a uri-template (URL Style = uri-template) with, for exemple, "/{scope}/*" and then when you call your api with http://host:port/proxyService/toto?foo=12&bar=14, you can access the "scope" with get-property('uri.var.scope')
to send a REST request, use a http endpoint with a uri-template using the same logic : uri-template="http://other_host:port/Service/{uri.var.scope}/truc?abc={query.param.foo}&dfc={query.param.bar}"
-->
If you want to use a proxy service, you can access to query parameters like this :
request : http://esb:8280/services/MonService?param1=val1¶m2=val2
<property name="PARAM1"
expression="tokenize(substring-after(syn:get-property('To'),'param1='),'&')"
scope="default"
type="STRING"/>
<property name="PARAM2"
expression="tokenize(substring-after(syn:get-property('To'),'param2='),'&')"
scope="default"
type="STRING"/>
you can use synapse xpath variable $url to read the query parameter values.
check this[1] for example.
Reading Dynamic query parameter in WSO2 APIM