}
}
public boolean mediate(MessageContext synCtx) {
SynapseLog synLog = getLog(synCtx);
boolean isResponse = synCtx.isResponse();
ConfigurationContext cc;
org.apache.axis2.context.MessageContext axisMC;
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Start : Throttle mediator");
if (synLog.isTraceTraceEnabled()) {
synLog.traceTrace("Message : " + synCtx.getEnvelope());
}
}
// To ensure the creation of throttle is thread safe – It is possible create same throttle
// object multiple times by multiple threads.
synchronized (throttleLock) {
// get Axis2 MessageContext and ConfigurationContext
axisMC = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
cc = axisMC.getConfigurationContext();
//To ensure check for clustering environment only happens one time
if ((throttle == null && !isResponse) || (isResponse
&& concurrentAccessController == null)) {
ClusteringAgent clusteringAgent = cc.getAxisConfiguration().getClusteringAgent();
if (clusteringAgent != null &&
clusteringAgent.getStateManager() != null) {
isClusteringEnable = true;
}
}
// Throttle only will be created ,if the massage flow is IN
if (!isResponse) {
//check the availability of the ConcurrentAccessControler
//if this is a clustered environment
if (isClusteringEnable) {
concurrentAccessController =
(ConcurrentAccessController) cc.getProperty(key);
}
// for request messages, read the policy for throttling and initialize
if (inLinePolicy != null) {
// this uses a static policy
if (throttle == null) { // only one time creation
if (synLog.isTraceTraceEnabled()) {
synLog.traceTrace("Initializing using static throttling policy : "
+ inLinePolicy);
}
try {
// process the policy
throttle = ThrottleFactory.createMediatorThrottle(
PolicyEngine.getPolicy(inLinePolicy));
//At this point concurrent access controller definitely 'null'
// f the clustering is disable.
//For a clustered environment,it is 'null' ,
//if this is the first instance on the cluster ,
// that message mediation has occurred through this mediator.
if (throttle != null && concurrentAccessController == null) {
concurrentAccessController =
throttle.getConcurrentAccessController();
if (concurrentAccessController != null) {
cc.setProperty(key, concurrentAccessController);
}
}
} catch (ThrottleException e) {
handleException("Error processing the throttling policy", e, synCtx);
}
}
} else if (policyKey != null) {
// If the policy has specified as a registry key.
// load or re-load policy from registry or local entry if not already available
Entry entry = synCtx.getConfiguration().getEntryDefinition(policyKey);
if (entry == null) {
handleException("Cannot find throttling policy using key : "
+ policyKey, synCtx);
} else {
boolean reCreate = false;
// if the key refers to a dynamic resource
if (entry.isDynamic()) {
if (!entry.isCached() || entry.isExpired()) {
reCreate = true;
}
}
if (reCreate || throttle == null) {
Object entryValue = synCtx.getEntry(policyKey);
if (entryValue == null) {
handleException(
"Null throttling policy returned by Entry : "
+ policyKey, synCtx);
} else {
if (!(entryValue instanceof OMElement)) {
handleException("Policy returned from key : " + policyKey +
" is not an OMElement", synCtx);
} else {
//Check for reload in a cluster environment –
// For clustered environment ,if the concurrent access controller
// is not null and throttle is not null , then must reload.
if (isClusteringEnable && concurrentAccessController != null
&& throttle != null) {
concurrentAccessController = null; // set null ,
// because need reload
}
try {
// Creates the throttle from the policy
throttle = ThrottleFactory.createMediatorThrottle(
PolicyEngine.getPolicy((OMElement) entryValue));
//For non-clustered environment , must re-initiates
//For clustered environment,
//concurrent access controller is null ,
//then must re-initiates
if (throttle != null && (concurrentAccessController == null
|| !isClusteringEnable)) {
concurrentAccessController =
throttle.getConcurrentAccessController();
if (concurrentAccessController != null) {
cc.setProperty(key, concurrentAccessController);
} else {
cc.removeProperty(key);
}
}
} catch (ThrottleException e) {
handleException("Error processing the throttling policy",
e, synCtx);
}
}
}
}
}
}
} else {
// if the message flow path is OUT , then must lookp from ConfigurationContext -
// never create ,just get the existing one
concurrentAccessController =
(ConcurrentAccessController) cc.getProperty(key);
}
}
//perform concurrency throttling
boolean canAccess = doThrottleByConcurrency(isResponse, synLog);
//if the access is success through concurrency throttle and if this is a request message
//then do access rate based throttling
if (throttle != null && !isResponse && canAccess) {
canAccess = throttleByAccessRate(synCtx, axisMC, cc, synLog);
}
// all the replication functionality of the access rate based throttling handles by itself
// Just replicate the current state of ConcurrentAccessController
if (isClusteringEnable && concurrentAccessController != null) {
if (cc != null) {
try {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Going to replicates the " +
"states of the ConcurrentAccessController with key : " + key);
}
Replicator.replicate(cc);
} catch (ClusteringFault clusteringFault) {
handleException("Error during the replicating states ",
clusteringFault, synCtx);
}
}
}
if (canAccess) {
if (onAcceptSeqKey != null) {
Mediator mediator = synCtx.getSequence(onAcceptSeqKey);
if (mediator != null) {
return mediator.mediate(synCtx);
} else {
handleException("Unable to find onAccept sequence with key : "
+ onAcceptSeqKey, synCtx);
}
} else if (onAcceptMediator != null) {
return onAcceptMediator.mediate(synCtx);
} else {
return true;
}
} else {
if (onRejectSeqKey != null) {
Mediator mediator = synCtx.getSequence(onRejectSeqKey);
if (mediator != null) {
return mediator.mediate(synCtx);
} else {
handleException("Unable to find onReject sequence with key : "
+ onRejectSeqKey, synCtx);
}
} else if (onRejectMediator != null) {
return onRejectMediator.mediate(synCtx);
} else {
return false;
}
}
synLog.traceOrDebug("End : Throttle mediator");
return canAccess;
}