| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.synapse.mediators.throttle; |
| |
| import junit.framework.TestCase; |
| import org.apache.axiom.om.OMAbstractFactory; |
| import org.apache.axiom.om.OMDocument; |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.om.OMXMLBuilderFactory; |
| import org.apache.axiom.om.OMXMLParserWrapper; |
| import org.apache.axiom.soap.SOAPEnvelope; |
| import org.apache.synapse.MessageContext; |
| import org.apache.synapse.SynapseException; |
| import org.apache.synapse.config.Entry; |
| import org.apache.synapse.config.SynapseConfiguration; |
| import org.apache.synapse.core.SynapseEnvironment; |
| import org.apache.synapse.core.axis2.Axis2MessageContext; |
| import org.apache.synapse.core.axis2.Axis2SynapseEnvironment; |
| import org.apache.synapse.mediators.AbstractMediator; |
| import org.wso2.throttle.*; |
| |
| import java.io.StringReader; |
| |
| /** |
| * Throttle Mediator Test - This class test throttling when policy has specified as both of |
| * InLine and a registry key |
| */ |
| |
| public class ThrottleMediatorTest extends TestCase { |
| private static final String REMOTE_ADDR = "Remote_Addr"; |
| |
| private static final String POLICY = " <wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\"\n" + |
| " xmlns:throttle=\"http://www.wso2.org/products/wso2commons/throttle\">\n" + |
| " <throttle:ThrottleAssertion>\n" + |
| " <wsp:All>\n" + |
| " <throttle:ID throttle:type=\"IP\">other</throttle:ID>\n" + |
| " <wsp:ExactlyOne>\n" + |
| " <wsp:All>\n" + |
| " <throttle:MaximumCount>8</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>800000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\">10</throttle:ProhibitTimePeriod>\n" + |
| " </wsp:All>\n" + |
| " </wsp:ExactlyOne>\n" + |
| " </wsp:All>\n" + |
| " <wsp:All>\n" + |
| " <throttle:ID throttle:type=\"IP\">192.168.8.200-192.168.8.222</throttle:ID>\n" + |
| " <wsp:ExactlyOne>\n" + |
| " <wsp:All>\n" + |
| " <throttle:MaximumCount>3</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>800000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\">10000</throttle:ProhibitTimePeriod>\n" + |
| " </wsp:All>\n" + |
| " </wsp:ExactlyOne>\n" + |
| " </wsp:All>\n" + |
| " <wsp:All>\n" + |
| " <throttle:ID throttle:type=\"IP\">192.168.8.201</throttle:ID>\n" + |
| " <wsp:ExactlyOne>\n" + |
| " <wsp:All>\n" + |
| " <throttle:MaximumCount>200</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>600000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\"></throttle:ProhibitTimePeriod>\n" + |
| " </wsp:All>\n" + |
| " </wsp:ExactlyOne>\n" + |
| " </wsp:All>\n" + |
| " <wsp:All>\n" + |
| " <throttle:ID throttle:type=\"IP\">192.168.8.198</throttle:ID>\n" + |
| " <wsp:ExactlyOne>\n" + |
| " <wsp:All>\n" + |
| " <throttle:MaximumCount>50</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>500000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\"></throttle:ProhibitTimePeriod>\n" + |
| " </wsp:All>\n" + |
| " </wsp:ExactlyOne>\n" + |
| " </wsp:All>\n" + |
| " </throttle:ThrottleAssertion>\n" + |
| " </wsp:Policy>"; |
| |
| private static final String NEW_POLICY = "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\"\n" + |
| " xmlns:throttle=\"http://www.wso2.org/products/wso2commons/throttle\">\n" + |
| "<throttle:MediatorThrottleAssertion>\n" + |
| " <throttle:MaximumConcurrentAccess>10</throttle:MaximumConcurrentAccess>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:ID throttle:type=\"IP\">other</throttle:ID>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:Control>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:MaximumCount>8</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>800000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\">10\n" + |
| " </throttle:ProhibitTimePeriod>\n" + |
| " </wsp:Policy>\n" + |
| " </throttle:Control>\n" + |
| " </wsp:Policy>\n" + |
| " </wsp:Policy>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:ID throttle:type=\"IP\">192.168.8.200-192.168.8.222</throttle:ID>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:Control>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:MaximumCount>3</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>800000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\">10000\n" + |
| " </throttle:ProhibitTimePeriod>\n" + |
| " </wsp:Policy>\n" + |
| " </throttle:Control>\n" + |
| " </wsp:Policy>\n" + |
| " </wsp:Policy>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:ID throttle:type=\"IP\">192.168.8.201</throttle:ID>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:Control>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:MaximumCount>200</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>600000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\"></throttle:ProhibitTimePeriod>\n" + |
| " </wsp:Policy>\n" + |
| " </throttle:Control>\n" + |
| " </wsp:Policy>\n" + |
| " </wsp:Policy>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:ID throttle:type=\"IP\">192.168.8.198</throttle:ID>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:Control>\n" + |
| " <wsp:Policy>\n" + |
| " <throttle:MaximumCount>50</throttle:MaximumCount>\n" + |
| " <throttle:UnitTime>500000</throttle:UnitTime>\n" + |
| " <throttle:ProhibitTimePeriod wsp:Optional=\"true\"></throttle:ProhibitTimePeriod>\n" + |
| " </wsp:Policy>\n" + |
| " </throttle:Control>\n" + |
| " </wsp:Policy>\n" + |
| " </wsp:Policy>\n" + |
| "</throttle:MediatorThrottleAssertion>\n" + |
| "</wsp:Policy>"; |
| |
| public ThrottleMediatorTest() { |
| super(ThrottleMediatorTest.class.getName()); |
| } |
| |
| public static MessageContext createLightweightSynapseMessageContext( |
| String payload) throws Exception { |
| org.apache.axis2.context.MessageContext mc = |
| new org.apache.axis2.context.MessageContext(); |
| SynapseConfiguration config = new SynapseConfiguration(); |
| SynapseEnvironment env = new Axis2SynapseEnvironment(config); |
| MessageContext synMc = new Axis2MessageContext(mc, config, env); |
| SOAPEnvelope envelope = |
| OMAbstractFactory.getSOAP11Factory().getDefaultEnvelope(); |
| OMDocument omDoc = |
| OMAbstractFactory.getSOAP11Factory().createOMDocument(); |
| omDoc.addChild(envelope); |
| |
| envelope.getBody().addChild(OMXMLBuilderFactory.createOMBuilder(new StringReader(payload)).getDocumentElement()); |
| |
| synMc.setEnvelope(envelope); |
| return synMc; |
| } |
| |
| public void testMediate() throws Exception { |
| OMXMLParserWrapper builder = OMXMLBuilderFactory.createOMBuilder(new StringReader(POLICY)); |
| ThrottleTestMediator throttleMediator = new ThrottleTestMediator(); |
| throttleMediator.setPolicyKey("throttlepolicy"); |
| MessageContext synCtx = createLightweightSynapseMessageContext("<empty/>"); |
| synCtx.setProperty(REMOTE_ADDR, "192.168.8.212"); |
| SynapseConfiguration synCfg = new SynapseConfiguration(); |
| Entry prop = new Entry(); |
| prop.setKey("throttlepolicy"); |
| prop.setType(Entry.INLINE_XML); |
| prop.setValue(builder.getDocumentElement()); |
| synCfg.addEntry("throttlepolicy", prop); |
| synCtx.setConfiguration(synCfg); |
| for (int i = 0; i < 6; i++) { |
| try { |
| throttleMediator.mediate(synCtx); |
| Thread.sleep(1000); |
| } |
| catch (Exception e) { |
| |
| if (i == 3) { |
| assertTrue(e.getMessage().lastIndexOf("IP_BASE") > 0); |
| } |
| if (i == 4) { |
| assertTrue(e.getMessage().lastIndexOf("IP_BASE") > 0); |
| } |
| if (i == 5) { |
| assertTrue(e.getMessage().lastIndexOf("IP_BASE") > 0); |
| } |
| } |
| } |
| |
| } |
| |
| public void testMediateWithInLineXML() throws Exception { |
| OMXMLParserWrapper builder = OMXMLBuilderFactory.createOMBuilder(new StringReader(POLICY)); |
| ThrottleTestMediator throttleMediator = new ThrottleTestMediator(); |
| throttleMediator.setInLinePolicy(builder.getDocumentElement()); |
| MessageContext synCtx = createLightweightSynapseMessageContext("<empty/>"); |
| synCtx.setProperty(REMOTE_ADDR, "192.168.8.212"); |
| SynapseConfiguration synCfg = new SynapseConfiguration(); |
| synCtx.setConfiguration(synCfg); |
| for (int i = 0; i < 6; i++) { |
| try { |
| throttleMediator.mediate(synCtx); |
| Thread.sleep(1000); |
| } |
| catch (Exception e) { |
| |
| if (i == 3) { |
| assertTrue(e.getMessage().lastIndexOf("IP_BASE") > 0); |
| } |
| if (i == 4) { |
| assertTrue(e.getMessage().lastIndexOf("IP_BASE") > 0); |
| } |
| if (i == 5) { |
| assertTrue(e.getMessage().lastIndexOf("IP_BASE") > 0); |
| } |
| } |
| } |
| |
| } |
| |
| public class ThrottleTestMediator extends AbstractMediator { |
| |
| private String policyKey = null; |
| |
| Throttle throttle = null; |
| private OMElement inLinePolicy = null; |
| |
| public boolean mediate(MessageContext synCtx) { |
| |
| init(synCtx); |
| try { |
| return canAccess(synCtx); |
| } |
| catch ( |
| ThrottleException e) { |
| throw new SynapseException(e.getMessage()); |
| } |
| |
| } |
| |
| protected boolean canAccess(MessageContext synContext) |
| throws SynapseException, ThrottleException { |
| |
| if (throttle == null) { |
| throw new ThrottleException("Can not find a throttle"); |
| |
| } |
| //IP based throttling |
| String remoteIP = (String) synContext.getProperty(REMOTE_ADDR); |
| if (remoteIP == null) { |
| throw new ThrottleException("IP address of the caller can not find - " + |
| "Currently only support caller-IP base access control" + |
| "- Throttling will not happen "); |
| |
| } else { |
| ThrottleContext throttleContext |
| = throttle.getThrottleContext(ThrottleConstants.IP_BASED_THROTTLE_KEY); |
| if (throttleContext == null) { |
| throw new ThrottleException("Can not find a configuration for " + |
| "IP Based Throttle"); |
| |
| } |
| AccessRateController accessController; |
| try { |
| accessController = new AccessRateController(); |
| boolean canAccess = accessController.canAccess( |
| throttleContext, remoteIP, ThrottleConstants.IP_BASE).isAccessAllowed(); |
| if (!canAccess) { |
| throw new SynapseException("Access has currently been denied by" + |
| " the IP_BASE throttle for IP :\t" + remoteIP); |
| } |
| return canAccess; |
| } |
| catch (ThrottleException e) { |
| return true; |
| } |
| } |
| } |
| |
| protected void init(MessageContext synContext) { |
| |
| boolean reCreate = false; // It is not need to recreate ,if property is not dyanamic |
| OMElement policyOmElement = null; |
| |
| if (policyKey != null) { |
| Entry entry = synContext.getConfiguration().getEntryDefinition(policyKey); |
| if (entry == null) { |
| return; |
| } |
| Object entryValue = entry.getValue(); |
| |
| if (!(entryValue instanceof OMElement)) { |
| return; |
| } |
| // if entry is dynamic, need to check wheather updated or not |
| if ((!entry.isCached() || entry.isExpired())) { |
| reCreate = true; |
| } |
| policyOmElement = (OMElement) entryValue; |
| } else if (inLinePolicy != null) { |
| policyOmElement = inLinePolicy; |
| } |
| if (policyOmElement == null) { |
| return; |
| } |
| if (!reCreate) { |
| //The first time creation |
| if (throttle == null) { |
| createThrottleMetaData(policyOmElement); |
| } |
| } else { |
| createThrottleMetaData(policyOmElement); |
| } |
| |
| } |
| |
| protected void createThrottleMetaData(OMElement policyOmElement) { |
| |
| try { |
| throttle = ThrottleFactory.createMediatorThrottle(policyOmElement); |
| } |
| catch (ThrottleException e) { |
| |
| throw new SynapseException(e.getMessage()); |
| } |
| } |
| |
| public String getType() { |
| return "ThrottleMediator"; |
| } |
| |
| |
| public String getPolicyKey() { |
| return policyKey; |
| } |
| |
| public void setPolicyKey(String policyKey) { |
| this.policyKey = policyKey; |
| } |
| |
| public OMElement getInLinePolicy() { |
| return inLinePolicy; |
| } |
| |
| public void setInLinePolicy(OMElement inLinePolicy) { |
| this.inLinePolicy = inLinePolicy; |
| } |
| } |
| } |