logging payload of request in wso2am - wso2-api-manager

with the following mediation i log headers of a request
<sequence xmlns="http://ws.apache.org/ns/synapse" name="WSO2AM--Ext--In">
<log level="custom">
<property name="system_time" expression="get-property('SYSTEM_TIME')"/>
<property name="application" scope="transport" expression="get-property('api.ut.application.name')"/>
<property name="api name" scope="transport" expression="get-property('api.ut.api')"/>
<property name="method" scope="transport" expression="get-property('api.ut.HTTP_METHOD')"/>
<property name="resource" scope="transport" expression="get-property('api.ut.resource')"/>
</log>
</sequence>
but i also want to log payload of request. how can i do it?

You can use log level as full and it will log the payload.
. However, this will parse the message content and will have a performance hit.
For more info, please visit documentation

Related

Not able to call Dynamic Endpoints/URLs on the basis of Message Mediation polices in WSO2 API Manager

I'm using APIM-3.1.0 and I need to Redirect APIs’ based upon header or request parameter. I have tried for request parameter but unable to call different API's. I have used below custom mediation policy and added it to a test API, but unable to call the different URLs. Every time I was calling API, I was getting output for the else part (URL mention in the else part) in below code even if I am passing the value of operation as menu.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="dynamic-endpoint-seq">
<property expression="json-eval($.operation)" name="operation" />
<filter regex="menu" source="$ctx:operation">
<then>
<property name="C" expression="fn:concat('http://localhost:8080/Test/','getC')"/>
<header name="To" expression="get-property('C')"/>
</then>
<else>
<property name="B" expression="fn:concat('http://localhost:8080/Test/','getB')"/>
<header name="To" expression="get-property('B')"/>
</else>
</filter>
</sequence>
I was getting warning in Console even passing value of parameter as shown below:
[2020-07-24 17:20:38,643] WARN - SynapseJsonPath Json Payload is empty.
Is there a way to do the same or there is any error in mediation policy?
Here, you can pass value in header with some variable name and define the same in mediation policies.
The below Code calls different endpoints on the basis of variable "check" is present or not,
if it is present in header with any value,the endpoint_B will get called, if value of check is not present or check is not present in header, then it will call endpoint_C.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="dynamic-endpoint-seq-boolean">
<!--it checks the value for variabe check in header if there exist value for check
then it will call B, if value not exist or check is not present then C called-->
<property name="uri.var.check" expression="get-property('transport','check')"/>
<filter source="boolean(get-property('uri.var.check'))" regex="false">
<then>
<property name="C" expression="fn:concat('http://localhost:8080/Test/','getC')"/>
<header name="To" expression="get-property('C')"/>
</then>
<else>
<property name="B" expression="fn:concat('http://localhost:8080/Test/','getB')"/>
<header name="To" expression="get-property('B')"/>
</else>
</filter>
</sequence>
There is one more way to do the same thing, you can use Switch case in XML,as shown below and configure multiple endpoints. Here, if you pass the value of check as 'B' in header, endpoint_B will called, else if you pass value of 'check' as 'C' in header, then endpoint_C will get called, and if you pass any other value than 'B' or 'C' or not pass any value or even not pass check in header than default endpoint here endpoint_A will get called.
<sequence name="dynamic_ep_switch" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property name="uri.var.check" expression="get-property('transport','check')"/>
<switch source="get-property('uri.var.check')">
<case regex="B">
<!-- We are then assigning the endpoint which we need to route to in a property named service_ep in this step -->
<property name="B" expression="fn:concat('http://localhost:8080/Test/','getB')"/>
<header name="To" expression="get-property('B')"/>
</case>
<case regex="C">
<property name="C" expression="fn:concat('http://localhost:8080/Test/','getC')"/>
<header name="To" expression="get-property('C')"/>
</case>
<default>
<property name="A" expression="fn:concat('http://localhost:8080/Test/','getA')"/>
<header name="To" expression="get-property('A')"/>
</default>
</switch>
There is one more way to use switch if your endpoint are running on same host and port by using property="rest_url_postfix" as shown in below code. Here,output will be same as above but some changes that you need to make are for the above code you need to select dynamic endpoint in Endpoints tab in WSO2-APIM publisher while for the below code, you select REST Endpoints and select value of endpoint as http://<host_name>:<port_number>// . For example,
http://localhost:8080/Test/
<sequence name="dynamic_same_ep_switch" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<!-- The property which is retrieved as get-property('To')" stores the request URI for the API. Based on this value we will determine the endpoint which the request needs to be routed to.-->
<property name="uri.var.check" expression="get-property('transport','check')"/>
<switch source="get-property('uri.var.check')">
<case regex="B">
<!-- We are then assigning the endpoint which we need to route to in a property named service_ep in this step -->
<property name="REST_URL_POSTFIX" value="getB" scope="axis2"/>
</case>
<case regex="C">
<property name="REST_URL_POSTFIX" value="getC" scope="axis2"/>
</case>
<default>
<property name="REST_URL_POSTFIX" value="getA" scope="axis2"/>
</default>
</switch>
</sequence>
For anymore information regarding sample mediation sequences refer following links:
https://docs.wso2.com/display/APICloud/Sample+Mediation+Sequences
https://docs.wso2.com/display/ESB480/HTTP+Transport+Properties
Hope. This resolves your Query.

integration between bmc remedy and serviceNow using wso2

we would like to integrate incident module between BMC Remedy and ServiceNow ITSM applications using ESB-WSO2, need assistance on this to achieve this integration.
Use case: Service now has to create incident then WSO2 will consume the request and process then processed request will be send to Remedy. This is nothing but a e-bonding or you can call it as ticket replication.
Any help would be much appreciated
Here is a sample API for you. Supposing that you have already installed ServiceNow connector.
You can call it from Postman using GET or browser, http://{yourWso2EiServer}:8280/serviceNow/test
After testing you can change method to POST and try to send different messages using POSTMAN. Then you will have to evaluate properties from a message, using like"expression"="json-eval($.tablename)" instead of "value"= in you Property mediators and your message must be an application/json and contain this field, like
{"tablename":"incident"....
<api xmlns="http://ws.apache.org/ns/synapse" name="ServiceNowApi" context="/serviceNow" version-type="context">
<resource methods="GET" uri-template="/test" outSequence="" faultSequence="">
<inSequence>
<property name="tablename" value="incident" description="here you can set your request variables with constants for test or read it from request using json-evalng "/>
<property name="sysparmDisplayValue" value="true"/>
<property name="sysparmFields" value="short_description,number,sys_id"/>
<property name="sysparmView" value="short_description,number,sys_id"/>
<property name="number" value="12345678"/>
<property name="shortDescription" value="Testing integration using ServiceNow connector"/>
<property name="active" value="true"/>
<property name="approval" value="owner"/>
<property name="category" value="inquery"/>
<property name="contactType" value="phone"/>
<servicenow.init>
<serviceNowInstanceURL>dev85868.service-now.com</serviceNowInstanceURL>
<username>rest_test</username>
<password>12345678</password>
</servicenow.init>
<servicenow.postRecord>
<tableName>{$ctx:tableName}</tableName>
<sysparmDisplayValue>{$ctx:sysparmDisplayValue}</sysparmDisplayValue>
<sysparmFields>{$ctx:sysparmFields}</sysparmFields>
<sysparmView>{$ctx:sysparmView}</sysparmView>
<sysparmExcludeReferenceLink>{$ctx:sysparmExcludeReferenceLink}</sysparmExcludeReferenceLink>
<sysparmInputDisplayValue>{$ctx:sysparmInputDisplayValue}</sysparmInputDisplayValue>
<number>{$ctx:number}</number>
<shortDescription>{$ctx:shortDescription}</shortDescription>
<active>{$ctx:active}</active>
<approval>{$ctx:approval}</approval>
<category>{$ctx:category}</category>
<contactType>{$ctx:contactType}</contactType>
<apiColumns>{$ctx:apiColumns}</apiColumns>
</servicenow.postRecord>
</respond>
</inSequence>
</inSequence>
</resource>
</api>

wso2 am 2.0 ApiKeyValidator Authentication Errors

We've recently upgraded our fully functional WSO2 AM 1.10 to 2.0. The installation process gave no errors and seems to be complete. We can use the Publisher just fine. However, when we go to the Store, and go to a tab that lists all of the user's Applications, it fails, and the page is empty. The log shows:
WARN - CarbonAuthenticationUtil Failed Administrator login attempt 'MyUser[-1234]' at [2017-01-10 09:47:09,380-0500]
WARN - AuthenticationHandler Illegal access attempt at [2017-01-10 09:47:09,0380] from IP address IP-ADDRESS while trying to authenticate access to service APIKeyMgtSubscriberService
ERROR - AMDefaultKeyManagerImpl Can not retrieve OAuth application for the given consumer key : BigLongStringOfStuff org.apache.axis2.AxisFault: Access Denied. Authentication failed - Invalid credentials provided.
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:531)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:370)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:445)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:225)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:149)
at org.wso2.carbon.apimgt.keymgt.stub.subscriber.APIKeyMgtSubscriberServiceStub.retrieveOAuthApplication(APIKeyMgtSubscriberServiceStub.java:1683)
at org.wso2.carbon.apimgt.keymgt.client.SubscriberKeyMgtClient.getOAuthApplication(SubscriberKeyMgtClient.java:89)
at org.wso2.carbon.apimgt.impl.AMDefaultKeyManagerImpl.retrieveApplication(AMDefaultKeyManagerImpl.java:234)
at org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO.getClientOfApplication(ApiMgtDAO.java:2389)
at org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO.getOAuthApplications(ApiMgtDAO.java:2353)
at org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO.getApplications(ApiMgtDAO.java:4649)
at org.wso2.carbon.apimgt.impl.APIConsumerImpl.getApplications(APIConsumerImpl.java:3136)
at org.wso2.carbon.apimgt.impl.UserAwareAPIConsumer.getApplications(UserAwareAPIConsumer.java:36)
at org.wso2.carbon.apimgt.hostobjects.APIStoreHostObject.jsFunction_getApplications(APIStoreHostObject.java:3225)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
We are using a Read Only LDAP store, the configuration is here:
<UserManager>
<Realm>
<Configuration>
<AddAdmin>False</AddAdmin>
<AdminRole>AdminGroup</AdminRole>
<AdminUser>
<UserName>MyUser</UserName>
<Password>MyPW</Password>
</AdminUser>
<EveryOneRoleName>everyone</EveryOneRoleName> <!-- By default users in this role sees the registry root -->
<Property name="dataSource">jdbc/WSO2CarbonDB</Property>
</Configuration>
<UserStoreManager class="org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager">
<Property name="TenantManager">org.wso2.carbon.user.core.tenant.CommonHybridLDAPTenantManager</Property>
<Property name="ReadOnly">true</Property>
<Property name="Disabled">false</Property>
<Property name="MaxUserNameListLength">100</Property>
<Property name="ConnectionURL">ldap://MyServer:389</Property>
<Property name="ConnectionName">CN=MyUser,OU=1,OU=2,DC=a,DC=b,DC=c</Property>
<Property name="ConnectionPassword">MyPW</Property>
<Property name="UserSearchBase">DC=a,DC=b,DC=c</Property>
<Property name="UserNameListFilter">(objectClass=user)(|(memberOf=CN=MyGroup-Subscriber,OU=1,OU=2,DC=a,DC=b,DC=c)(sAMAccountName=MyUser))</Property>
<Property name="UserNameSearchFilter">(|(&(objectClass=person)(sAMAccountName=?)(memberOf=CN=MyGroup-Subscriber,OU=1,OU=2,DC=a,DC=b,DC=c))(sAMAccountName=MyUser))</Property>
<Property name="UserNameAttribute">sAMAccountName</Property>
<Property name="DisplayNameAttribute">displayName</Property>
<Property name="ReadGroups">true</Property>
<Property name="GroupSearchBase">OU=Groups,OU=1,OU=2,DC=a,DC=b,DC=c</Property>
<Property name="GroupNameListFilter">(&(objectClass=group)(cn=MyGroup*))</Property>
<Property name="GroupNameSearchFilter">(&(objectClass=group)(cn=MyGroup?))</Property>
<Property name="GroupNameAttribute">cn</Property>
<Property name="MembershipAttribute">member</Property>
<Property name="MemberOfAttribute">memberOf</Property>
<Property name="MultipleAttributeSeparator">,</Property>
<Property name="PasswordHashMethod">PLAIN_TEXT</Property>
<Property name="UserRolesCacheEnabled">true</Property>
<Property name="ReplaceEscapeCharactersAtUserLogin">true</Property>
<Property name="MaxRoleNameListLength">100</Property>
<Property name="MaxUserNameListLength">100</Property>
<Property name="SCIMEnabled">false</Property>
</UserStoreManager>
<AuthorizationManager
class="org.wso2.carbon.user.core.authorization.JDBCAuthorizationManager">
<Property name="AdminRoleManagementPermissions">/permission</Property>
<Property name="AuthorizationCacheEnabled">true</Property>
</AuthorizationManager>
</Realm>
</UserManager>
In the Api-Manager.xml configuration for the ApiKeyValidator Key We have:
<APIKeyValidator>
<!-- Server URL of the API key manager -->
<ServerURL>https://MyURL:${mgt.transport.https.port}${carbon.context}services/</ServerURL>
<!-- Admin username for API key manager.
<Username>MyUser</Username>
<!-- Admin password for API key manager. -->
<Password>MyPW</Password>
<KeyValidatorClientType>ThriftClient</KeyValidatorClientType>
<ThriftClientConnectionTimeOut>10000</ThriftClientConnectionTimeOut>
<EnableThriftServer>true</EnableThriftServer>
<ThriftServerHost>localhost</ThriftServerHost>
<KeyValidationHandlerClassName>org.wso2.carbon.apimgt.keymgt.handlers.DefaultKeyValidationHandler</KeyValidationHandlerClassName>
This error did not occur in 1.10 with the same config file entries. Is there any idea as to why this happens?
So I figured out why this occurred - This will happen if the incorrect provider is listed in the user-mgt.xml file. If you see my file above, I am trying to use ReadOnly LDAP, but I have the RDBMS provider listed instead.
Changed this line and boom, everythign is functional again.

How to Load lables via Properties file in FreeMarker

I am using Spring MVC + FreeMarker integration. As I am new to FreeMarker i am not able to find out a way to configure FreeMarker labels from properties file.
Kindly help me out on this.
Thanks.
You can use, 'ResourceBundleMessageSource', message source for this.
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
<property name="basename" value="classpath:messages/messages" />
<property name="defaultEncoding" value="UTF-8"/>
/>
Define the locale resolver,
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
Define localeChangeInterceptor which detects the language parameter from the user session and call locale resolve. And register the interceptor in handler Mappings.
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" >
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
Property files need to be defined like,
messages_en.properties
messages_ar.properties
inside the messages folder path.
'ReloadableResourceBundleMessageSource' can be used if the language property files frequently changes. That means you don't have to restart the application in each language file change.
You need to import spring macro,
<#import "/spring.ftl" as spring/>
and
messages can be accessed inside a .ftl as follows.
<#spring.message "customMessageKey"/>

Configure an External LDAP User Store with WSO2 Identity Server

My Current configuration is
#
<UserManager>
<Realm>
<Configuration>
<AdminRole>admin</AdminRole>
<AdminUser>
<UserName>admin</UserName>
<Password>XXXXXX</Password>
</AdminUser>
<EveryOneRoleName>everyone</EveryOneRoleName> <!-- By default users in thsi role sees the registry root -->
<!-- <ReadOnly>false</ReadOnly> -->
<MaxUserNameListLength>500</MaxUserNameListLength>
<Property name="url">jdbc:h2:repository/database/WSO2CARBON_DB</Property>
<Property name="userName">wso2carbon</Property>
<Property name="password">wso2carbon</Property>
<Property name="driverName">org.h2.Driver</Property>
<Property name="maxActive">50</Property>
<Property name="maxWait">60000</Property>
<Property name="minIdle">5</Property>
</Configuration>
<UserStoreManager
class="org.wso2.carbon.user.core.ldap.LDAPUserStoreManager">
<Property name="ConnectionURL">ldap://localhost:389</Property>
<Property name="ConnectionName">cn=admin,dc=ysd,dc=com</Property>
<Property name="ConnectionPassword">admin32</Property>
<Property name="UserSearchBase">ou=People,dc=ysd,dc=com</Property>
<Property name="UserNameListFilter">(objectClass=person)</Property>
<Property name="UserNameAttribute">uid</Property>
<Property name="ReadLDAPGroups">false</Property>
<Property name="GroupSearchBase">ou=People,dc=ysd,dc=com</Property>
<Property name="GroupSearchFilter">(objectClass=groupOfNames)</Property>
<Property name="GroupNameAttribute">cn</Property>
<Property name="MembershipAttribute">member</Property>
</UserStoreManager>
<AuthorizationManager
class="org.wso2.carbon.user.core.authorization.JDBCAuthorizationManager">
</AuthorizationManager>
</Realm>
</UserManager>`
#
Iam geeting following error while starting server.
*ERROR {org.wso2.carbon.user.core.common.DefaultRealm} - Cannot create org.wso2.carbon.user.core.ldap.LDAPUserStoreManager . Error is : null
java.lang.reflect.InvocationTargetException*
..............
............
............
Caused by: org.wso2.carbon.user.core.UserStoreException: LDAPUserStoreManager is unable to operate in Read-Write mode. This is invalid configuration. It can only operate in ReadOnly mode
at org.wso2.carbon.user.core.ldap.LDAPUserStoreManager.(LDAPUserStoreManager.java:97)
... 25 more
What is your exact requirement ? Do you want the Identity Server to do Read-Write operation on the external LDAP or do you want to do only the Read operations ?
You get this exception because you are trying to use the read only ldap user store for both read-write operations. Set the parameter <ReadOnly>false</ReadOnly>to true, then this error would go away.
But if your requirement is to use IS for both read write operations use the ApacheDSUserStoreManager. You can use the LDAPUserStoreManager for that.

Resources