package org.wso2.carbon.mediation.initializer.handler;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.synapse.SynapseConstants;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
/**
* This handler is use to set ThreadLocal carbon context when message is comes via non-servlet transports
*/
public class CarbonContextConfigurator extends AbstractHandler {
public InvocationResponse invoke(MessageContext messageContext) throws AxisFault {
PrivilegedCarbonContext cc = PrivilegedCarbonContext.getThreadLocalCarbonContext();
//if cc is already populated ( servlet transport ) just return
//TODO: Ideally only tenant domain need to check, but there are some admin calls comes with null domain and tenant ID
if (!isDispatchingToSynapse(messageContext) && (cc.getTenantDomain() != null
|| cc.getTenantId() != MultitenantConstants.INVALID_TENANT_ID)) {
return InvocationResponse.CONTINUE;
}
//for non-http we assume that it's for ST
if (messageContext.getTransportIn() != null && messageContext.getTransportIn().getName() != null &&
!messageContext.getTransportIn().getName().contains("http")) {
cc.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
cc.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
return InvocationResponse.CONTINUE;
}
try {
EndpointReference epr = messageContext.getTo();
if (epr != null) {
String to = epr.getAddress();
if (to != null && to.indexOf("/" + MultitenantConstants.TENANT_AWARE_URL_PREFIX + "/") != -1) {
String str1 = to.substring(to.indexOf("/t/") + 3);
String domain = str1.substring(0, str1.indexOf("/"));
cc.setTenantDomain(domain, true);
} else {
cc.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
cc.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
}
}
} catch (Throwable ignore) {
//don't care if anything failed
}
return InvocationResponse.CONTINUE;
}
/**
* Check whether request is going to a Proxy service, API or Main Sequence
*
* @param messageContext axis2 message context
* @return whether request is going to synapse artifact
*/
private boolean isDispatchingToSynapse(MessageContext messageContext) {
AxisService axisService = messageContext.getAxisService();
if (axisService != null) {
// For API and Main Sequence
if (SynapseConstants.SYNAPSE_SERVICE_NAME.equalsIgnoreCase(axisService.getName())) {
return true;
}
// For Proxy Service
Parameter val = axisService.getParameter("serviceType");
if (val != null && val.getValue().toString().equalsIgnoreCase("Proxy")) {
return true;
}
}
return false;
}
}