You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by hi...@apache.org on 2010/08/27 07:06:24 UTC
svn commit: r990019 - in /synapse/trunk/java/modules/core/src:
main/java/org/apache/synapse/config/xml/
main/java/org/apache/synapse/mediators/transform/url/
test/java/org/apache/synapse/mediators/transform/url/
Author: hiranya
Date: Fri Aug 27 05:06:23 2010
New Revision: 990019
URL: http://svn.apache.org/viewvc?rev=990019&view=rev
Log:
Adding the new URL rewrite mediator (SYNAPSE-681) and some basic tests. More test cases and documentation to follow.
Added:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorFactory.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorSerializer.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteAction.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteRule.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URIFragments.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URLRewriteMediator.java
synapse/trunk/java/modules/core/src/test/java/org/apache/synapse/mediators/transform/url/
synapse/trunk/java/modules/core/src/test/java/org/apache/synapse/mediators/transform/url/URLRewriteMediatorTest.java
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java?rev=990019&r1=990018&r2=990019&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java Fri Aug 27 05:06:23 2010
@@ -76,7 +76,8 @@ public class MediatorFactoryFinder imple
TransactionMediatorFactory.class,
EnqueueMediatorFactory.class,
ConditionalRouterMediatorFactory.class,
- SamplingThrottleMediatorFactory.class
+ SamplingThrottleMediatorFactory.class,
+ URLRewriteMediatorFactory.class
};
private final static MediatorFactoryFinder instance = new MediatorFactoryFinder();
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorFactory.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorFactory.java?rev=990019&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorFactory.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorFactory.java Fri Aug 27 05:06:23 2010
@@ -0,0 +1,204 @@
+/*
+ * 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.config.xml;
+
+import org.apache.synapse.Mediator;
+import org.apache.synapse.util.xpath.SynapseXPath;
+import org.apache.synapse.commons.evaluators.Evaluator;
+import org.apache.synapse.commons.evaluators.EvaluatorException;
+import org.apache.synapse.commons.evaluators.config.EvaluatorFactoryFinder;
+import org.apache.synapse.mediators.transform.url.URLRewriteMediator;
+import org.apache.synapse.mediators.transform.url.RewriteRule;
+import org.apache.synapse.mediators.transform.url.RewriteAction;
+import org.apache.synapse.mediators.transform.url.URIFragments;
+import org.apache.axiom.om.OMElement;
+import org.jaxen.JaxenException;
+
+import javax.xml.namespace.QName;
+import java.util.Iterator;
+
+/**
+ * Creates an instance of the URLRewriteMediator given an XML configuration which
+ * adheres to the following grammar.
+ *
+ * <pre>
+ * <rewrite [inProperty="inputURL"] [outProperty="outputURL"]>
+ * <rule>
+ * <condition>
+ * evaluator configuration
+ * </condition> ?
+ * <action
+ * value="value"
+ * xpath="xpath"
+ * [type="set | append | prepend | replace | remove"]
+ * [fragment="protocol | user | host | port | path | query | ref | full"]
+ * [regex="regex"] /> +
+ * </rule> *
+ * </rewrite>
+ * </pre>
+ */
+public class URLRewriteMediatorFactory extends AbstractMediatorFactory {
+
+ private static final QName REWRITE_Q = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "rewrite");
+
+ private static final QName RULE_Q = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "rule");
+ private static final QName CONDITION_Q = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "condition");
+ private static final QName ACTION_Q = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "action");
+
+ private static final QName ATT_IN_PROPERTY = new QName("inProperty");
+ private static final QName ATT_OUT_PROPERTY = new QName("outProperty");
+ private static final QName ATT_TYPE = new QName("type");
+ private static final QName ATT_FRAGMENT = new QName("fragment");
+
+ public static final String ACTION_SET = "set";
+ public static final String ACTION_APPEND = "append";
+ public static final String ACTION_PREPEND = "prepend";
+ public static final String ACTION_REPLACE = "replace";
+ public static final String ACTION_REMOVE = "remove";
+
+ public static final String FRAGMENT_PROTOCOL = "protocol";
+ public static final String FRAGMENT_USER_INFO = "user";
+ public static final String FRAGMENT_HOST = "host";
+ public static final String FRAGMENT_PORT = "port";
+ public static final String FRAGMENT_PATH = "path";
+ public static final String FRAGMENT_QUERY = "query";
+ public static final String FRAGMENT_REF = "ref";
+ public static final String FRAGMENT_FULL_URI = "full";
+
+ protected Mediator createSpecificMediator(OMElement element) {
+ Iterator rules = element.getChildrenWithName(RULE_Q);
+ String inputProperty = element.getAttributeValue(ATT_IN_PROPERTY);
+ String outputProperty = element.getAttributeValue(ATT_OUT_PROPERTY);
+
+ URLRewriteMediator mediator = new URLRewriteMediator();
+ if (inputProperty != null) {
+ mediator.setInputProperty(inputProperty);
+ }
+ if (outputProperty != null) {
+ mediator.setOutputProperty(outputProperty);
+ }
+
+ while (rules.hasNext()) {
+ mediator.addRule(parseRule((OMElement) rules.next()));
+ }
+ processAuditStatus(mediator, element);
+ return mediator;
+ }
+
+ private RewriteRule parseRule(OMElement ruleElement) {
+ Iterator actions = ruleElement.getChildrenWithName(ACTION_Q);
+ if (actions == null) {
+ handleException("At least one rewrite action is required per rule");
+ return null;
+ }
+
+ RewriteRule rule = new RewriteRule();
+ while (actions.hasNext()) {
+ rule.addRewriteAction(parseAction((OMElement) actions.next()));
+ }
+
+ OMElement condition = ruleElement.getFirstChildWithName(CONDITION_Q);
+ if (condition != null) {
+ OMElement child = condition.getFirstElement();
+ if (child != null) {
+ try {
+ Evaluator eval = EvaluatorFactoryFinder.getInstance().getEvaluator(child);
+ rule.setCondition(eval);
+ } catch (EvaluatorException e) {
+ handleException("Error while parsing the rule condition", e);
+ }
+ }
+ }
+
+ return rule;
+ }
+
+ private RewriteAction parseAction(OMElement actionElement) {
+ String value = actionElement.getAttributeValue(ATT_VALUE);
+ String xpath = actionElement.getAttributeValue(ATT_XPATH);
+ String type = actionElement.getAttributeValue(ATT_TYPE);
+
+ if (value == null && xpath == null && !ACTION_REMOVE.equals(type)) {
+ handleException("value or xpath attribute is required on the action element");
+ }
+
+ RewriteAction action = new RewriteAction();
+ if (xpath != null) {
+ try {
+ action.setXpath(new SynapseXPath(xpath));
+ } catch (JaxenException e) {
+ handleException("Error while parsing the XPath expression: " + xpath, e);
+ }
+ } else if (value != null) {
+ action.setValue(value);
+ }
+
+ String fragment = actionElement.getAttributeValue(ATT_FRAGMENT);
+ if (fragment != null) {
+ if (FRAGMENT_PROTOCOL.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.PROTOCOL);
+ } else if (FRAGMENT_USER_INFO.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.USER_INFO);
+ } else if (FRAGMENT_HOST.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.HOST);
+ } else if (FRAGMENT_PORT.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.PORT);
+ } else if (FRAGMENT_PATH.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.PATH);
+ } else if (FRAGMENT_QUERY.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.QUERY);
+ } else if (FRAGMENT_REF.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.REF);
+ } else if (FRAGMENT_FULL_URI.equals(fragment)) {
+ action.setFragmentIndex(URIFragments.FULL_URI);
+ } else {
+ handleException("Unknown URL fragment name: " + fragment);
+ }
+ }
+
+ if (type != null) {
+ if (ACTION_SET.equals(type)) {
+ action.setActionType(RewriteAction.ACTION_SET);
+ } else if (ACTION_APPEND.equals(type)) {
+ action.setActionType(RewriteAction.ACTION_APPEND);
+ } else if (ACTION_PREPEND.equals(type)) {
+ action.setActionType(RewriteAction.ACTION_PREPEND);
+ } else if (ACTION_REPLACE.equals(type)) {
+ action.setActionType(RewriteAction.ACTION_REPLACE);
+ String regex = actionElement.getAttributeValue(ATT_REGEX);
+ if (regex != null) {
+ action.setRegex(regex);
+ } else {
+ handleException("regex attribute is required for replace action");
+ }
+ } else if (ACTION_REMOVE.equals(type)) {
+ action.setActionType(RewriteAction.ACTION_REMOVE);
+ } else {
+ handleException("Unknown URL rewrite action type: " + type);
+ }
+ }
+
+ return action;
+ }
+
+ public QName getTagQName() {
+ return REWRITE_Q;
+ }
+}
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorSerializer.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorSerializer.java?rev=990019&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorSerializer.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/URLRewriteMediatorSerializer.java Fri Aug 27 05:06:23 2010
@@ -0,0 +1,158 @@
+/*
+ * 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.config.xml;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.synapse.Mediator;
+import org.apache.synapse.commons.evaluators.Evaluator;
+import org.apache.synapse.commons.evaluators.EvaluatorException;
+import org.apache.synapse.commons.evaluators.config.EvaluatorSerializer;
+import org.apache.synapse.commons.evaluators.config.EvaluatorSerializerFinder;
+import org.apache.synapse.mediators.transform.url.URLRewriteMediator;
+import org.apache.synapse.mediators.transform.url.RewriteRule;
+import org.apache.synapse.mediators.transform.url.RewriteAction;
+import org.apache.synapse.mediators.transform.url.URIFragments;
+
+import java.util.List;
+
+public class URLRewriteMediatorSerializer extends AbstractMediatorSerializer {
+
+ protected OMElement serializeSpecificMediator(Mediator m) {
+ if (!(m instanceof URLRewriteMediator)) {
+ handleException("Unsupported mediator passed in for serialization : " + m.getType());
+ return null;
+ }
+
+ URLRewriteMediator mediator = (URLRewriteMediator) m;
+ OMElement rewrite = fac.createOMElement("rewrite", synNS);
+ saveTracingState(rewrite, mediator);
+
+ List<RewriteRule> rules = mediator.getRules();
+ try {
+ for (RewriteRule r : rules) {
+ OMElement rule = serializeRule(r);
+ rewrite.addChild(rule);
+ }
+ } catch (EvaluatorException e) {
+ handleException("Error while serializing the rewrite rule", e);
+ }
+
+ return rewrite;
+ }
+
+ private OMElement serializeRule(RewriteRule r) throws EvaluatorException {
+ OMElement rule = fac.createOMElement("rule", synNS);
+ Evaluator condition = r.getCondition();
+ if (condition != null) {
+ OMElement conditionElt = fac.createOMElement("condition", synNS);
+ EvaluatorSerializer serializer = EvaluatorSerializerFinder.getInstance().
+ getSerializer(condition.getName());
+ serializer.serialize(conditionElt, condition);
+ rule.addChild(conditionElt);
+ }
+
+ List<RewriteAction> actions = r.getActions();
+ for (RewriteAction a : actions) {
+ OMElement action = serializeAction(a);
+ rule.addChild(action);
+ }
+
+ return rule;
+ }
+
+ private OMElement serializeAction(RewriteAction a) {
+ OMElement action = fac.createOMElement("action", synNS);
+ if (a.getValue() != null) {
+ action.addAttribute("value", a.getValue(), null);
+ } else if (a.getXpath() != null) {
+ action.addAttribute("xpath", a.getValue(), null);
+ }
+
+ if (a.getRegex() != null) {
+ action.addAttribute("regex", a.getRegex(), null);
+ }
+
+ int type = a.getActionType();
+ String typeStr;
+ switch (type) {
+ case RewriteAction.ACTION_APPEND:
+ typeStr = URLRewriteMediatorFactory.ACTION_APPEND;
+ break;
+
+ case RewriteAction.ACTION_PREPEND:
+ typeStr = URLRewriteMediatorFactory.ACTION_PREPEND;
+ break;
+
+ case RewriteAction.ACTION_REPLACE:
+ typeStr = URLRewriteMediatorFactory.ACTION_REPLACE;
+ break;
+
+ case RewriteAction.ACTION_REMOVE:
+ typeStr = URLRewriteMediatorFactory.ACTION_REMOVE;
+ break;
+
+ default:
+ typeStr = URLRewriteMediatorFactory.ACTION_SET;
+ }
+ action.addAttribute("type", typeStr, null);
+
+ int fragment = a.getFragmentIndex();
+ String fragmentStr;
+ switch (fragment) {
+ case URIFragments.PROTOCOL:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_PROTOCOL;
+ break;
+
+ case URIFragments.USER_INFO:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_USER_INFO;
+ break;
+
+ case URIFragments.HOST:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_HOST;
+ break;
+
+ case URIFragments.PORT:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_PORT;
+ break;
+
+ case URIFragments.PATH:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_PATH;
+ break;
+
+ case URIFragments.QUERY:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_QUERY;
+ break;
+
+ case URIFragments.REF:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_REF;
+ break;
+
+ default:
+ fragmentStr = URLRewriteMediatorFactory.FRAGMENT_FULL_URI;
+ }
+ action.addAttribute("fragment", fragmentStr, null);
+
+ return action;
+ }
+
+ public String getMediatorClassName() {
+ return URLRewriteMediator.class.getName();
+ }
+}
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteAction.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteAction.java?rev=990019&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteAction.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteAction.java Fri Aug 27 05:06:23 2010
@@ -0,0 +1,138 @@
+/*
+ * 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.transform.url;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.synapse.util.xpath.SynapseXPath;
+import org.apache.synapse.MessageContext;
+
+import java.net.URISyntaxException;
+import java.net.URI;
+
+/**
+ * Represents a URL rewrite action. The action could be rewriting the entire URL
+ * or rewriting a fragment of the URL.
+ */
+public class RewriteAction {
+
+ private static final Log log = LogFactory.getLog(RewriteAction.class);
+
+ public static final int ACTION_SET = 0;
+ public static final int ACTION_APPEND = 1;
+ public static final int ACTION_PREPEND = 2;
+ public static final int ACTION_REPLACE = 3;
+ public static final int ACTION_REMOVE = 4;
+
+ private String value;
+ private SynapseXPath xpath;
+ private String regex;
+ private int fragmentIndex = URIFragments.FULL_URI;
+ private int actionType = ACTION_SET;
+
+ public void execute(URIFragments fragments,
+ MessageContext messageContext) throws URISyntaxException {
+
+ String result;
+ if (xpath != null) {
+ result = xpath.stringValueOf(messageContext);
+ } else {
+ result = value;
+ }
+
+ if (fragmentIndex == URIFragments.FULL_URI) {
+ URI uri;
+ if (result != null) {
+ uri = new URI(result);
+ if (log.isTraceEnabled()) {
+ log.trace("Setting the URI to: " + result);
+ }
+ } else {
+ uri = new URI("");
+ }
+
+ // Since the entire URL has been rewritten we need to reinit all the fragments
+ fragments.setFragments(uri);
+
+ } else if (fragmentIndex == URIFragments.PORT) {
+ // When setting the port we must first convert the value into an integer
+ if (result != null) {
+ fragments.setPort(Integer.parseInt(result));
+ } else {
+ fragments.setPort(-1);
+ }
+ } else {
+ String str;
+ String currentValue = fragments.getStringFragment(fragmentIndex);
+ if (currentValue == null) {
+ currentValue = "";
+ }
+
+ switch (actionType) {
+ case ACTION_PREPEND : str = result.concat(currentValue); break;
+ case ACTION_APPEND : str = currentValue.concat(result); break;
+ case ACTION_REPLACE : str = currentValue.replaceAll(regex, result); break;
+ case ACTION_REMOVE : str = null; break;
+ default : str = result;
+ }
+ fragments.setStringFragment(fragmentIndex, str);
+ }
+ }
+
+ public int getFragmentIndex() {
+ return fragmentIndex;
+ }
+
+ public void setFragmentIndex(int fragmentIndex) {
+ this.fragmentIndex = fragmentIndex;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public SynapseXPath getXpath() {
+ return xpath;
+ }
+
+ public void setXpath(SynapseXPath xpath) {
+ this.xpath = xpath;
+ }
+
+ public String getRegex() {
+ return regex;
+ }
+
+ public void setRegex(String regex) {
+ this.regex = regex;
+ }
+
+ public int getActionType() {
+ return actionType;
+ }
+
+ public void setActionType(int actionType) {
+ this.actionType = actionType;
+ }
+}
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteRule.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteRule.java?rev=990019&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteRule.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/RewriteRule.java Fri Aug 27 05:06:23 2010
@@ -0,0 +1,97 @@
+/*
+ * 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.transform.url;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.synapse.commons.evaluators.Evaluator;
+import org.apache.synapse.commons.evaluators.EvaluatorContext;
+import org.apache.synapse.commons.evaluators.EvaluatorException;
+import org.apache.synapse.MessageContext;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.net.URISyntaxException;
+
+/**
+ * Represents a URL rewrite rule. A rule can consist of an optional condition
+ * and one or more rewrite actions. If the condition is present, actions will be
+ * executed only when the condition evaluates to true. If the condition is not
+ * present, all the provided actions will be executed. If an error occurs while
+ * evaluating the condition, the condition is treated as evaluated to false.
+ * Condition evaluation is handled by Synapse evaluator framework. When executing
+ * multiple rewrite actions, they are executed in the specified order.
+ */
+public class RewriteRule {
+
+ private static final Log log = LogFactory.getLog(RewriteRule.class);
+
+ private Evaluator condition;
+ private List<RewriteAction> actions = new ArrayList<RewriteAction>();
+
+ public void rewrite(URIFragments fragments, MessageContext messageContext,
+ Map<String,String> headers) throws URISyntaxException {
+
+ if (condition != null) {
+ String uriString = fragments.toURIString();
+ EvaluatorContext ctx = new EvaluatorContext(uriString, headers);
+ if (log.isTraceEnabled()) {
+ log.trace("Evaluating condition with URI: " + uriString);
+ }
+
+ try {
+ if (!condition.evaluate(ctx)) {
+ if (log.isTraceEnabled()) {
+ log.trace("Condition evaluated to 'false' - Skipping the current action");
+ }
+ return;
+ }
+
+ if (log.isTraceEnabled()) {
+ log.trace("Condition evaluated to 'true' - Performing the stated action");
+ }
+ } catch (EvaluatorException e) {
+ log.warn("Error while evaluating the condition - Skipping the rule as it failed", e);
+ return;
+ }
+ }
+
+ for (RewriteAction action : actions) {
+ action.execute(fragments, messageContext);
+ }
+ }
+
+ public Evaluator getCondition() {
+ return condition;
+ }
+
+ public void setCondition(Evaluator condition) {
+ this.condition = condition;
+ }
+
+ public void addRewriteAction(RewriteAction action) {
+ actions.add(action);
+ }
+
+ public List<RewriteAction> getActions() {
+ return actions;
+ }
+}
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URIFragments.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URIFragments.java?rev=990019&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URIFragments.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URIFragments.java Fri Aug 27 05:06:23 2010
@@ -0,0 +1,117 @@
+/*
+ * 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.transform.url;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * This class represents a URI, fragmented into 7 major components. These components are
+ * namely scheme, user info, host, port, path, query and ref. Out of these seven components,
+ * port is an integer whereas all other components are strings. These fragments can be
+ * combined to form a valid URI according to RFC-2396. This collection strictly deals
+ * with URI fragments and not URL fragments. Therefore this abstraction can be used to
+ * represent any URI, URL or URN thus allowing room for a wider range of usecases.
+ */
+public class URIFragments {
+
+ public static final int FULL_URI = -2;
+ public static final int PORT = -1;
+
+ public static final int PROTOCOL = 0;
+ public static final int USER_INFO = 1;
+ public static final int HOST = 2;
+ public static final int PATH = 3;
+ public static final int QUERY = 4;
+ public static final int REF = 5;
+
+ private int port = -1;
+ // Using an array is lightweight and enables fast lookup through array indexing
+ private String[] fragments = new String[6];
+
+ public URIFragments() {
+
+ }
+
+ public URIFragments(URI uri) {
+ setFragments(uri);
+ }
+
+ /**
+ * Break down the given URI into fragments and reinitialize the current
+ * fragments set
+ *
+ * @param uri the URI to be assigned to the fragments
+ */
+ public void setFragments(URI uri) {
+ fragments[PROTOCOL] = uri.getScheme();
+ fragments[USER_INFO] = uri.getUserInfo();
+ fragments[HOST] = uri.getHost();
+ // getPath method returns empty string when a path is not present
+ // Better to set 'null' instead
+ fragments[PATH] = ("".equals(uri.getPath()) ? null : uri.getPath());
+ fragments[QUERY] = uri.getQuery();
+ fragments[REF] = uri.getFragment();
+ port = uri.getPort();
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setStringFragment(int index, String value) {
+ fragments[index] = value;
+ }
+
+ public String getStringFragment(int index) {
+ return fragments[index];
+ }
+
+ /**
+ * Construct a valid URI by combining the current fragment values
+ *
+ * @return a valid URI instance
+ * @throws URISyntaxException if the fragments form a malformed URI
+ */
+ public URI toURI() throws URISyntaxException {
+ return new URI(
+ fragments[PROTOCOL],
+ fragments[USER_INFO],
+ fragments[HOST],
+ port,
+ fragments[PATH],
+ fragments[QUERY],
+ fragments[REF]);
+ }
+
+ /**
+ * Construct a valid URI string by combining the current fragment values
+ *
+ * @return a string representation of a valid URI
+ * @throws URISyntaxException if the fragments form a malformed URI
+ */
+ public String toURIString() throws URISyntaxException {
+ return toURI().toString();
+ }
+}
Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URLRewriteMediator.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URLRewriteMediator.java?rev=990019&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URLRewriteMediator.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/url/URLRewriteMediator.java Fri Aug 27 05:06:23 2010
@@ -0,0 +1,137 @@
+/*
+ * 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.transform.url;
+
+import org.apache.synapse.mediators.AbstractMediator;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.core.axis2.Axis2MessageContext;
+import org.apache.axis2.addressing.EndpointReference;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * A mediator capable of rewriting URLs in messages. The input URL can be
+ * extracted from the To header of the message or any of the message properties.
+ * The rewritten URL can be set as the To header or a message property. URL
+ * rewriting is carried out based on a user defined set of rules. This mediator
+ * support rewriting entire URLs as well as URL fragments.
+ */
+public class URLRewriteMediator extends AbstractMediator {
+
+ private List<RewriteRule> rules = new ArrayList<RewriteRule>();
+ private String inputProperty;
+ private String outputProperty;
+
+ public boolean mediate(MessageContext messageContext) {
+ URIFragments fragments;
+ URI inputURI = getInputAddress(messageContext);
+ if (inputURI != null) {
+ fragments = new URIFragments(inputURI);
+ } else {
+ fragments = new URIFragments();
+ }
+
+ Map<String, String> headers = getHeaders(messageContext);
+
+ try {
+ for (RewriteRule r : rules) {
+ r.rewrite(fragments, messageContext, headers);
+ }
+
+ if (outputProperty != null) {
+ messageContext.setProperty(outputProperty, fragments.toURIString());
+ } else {
+ messageContext.setTo(new EndpointReference(fragments.toURIString()));
+ }
+ } catch (URISyntaxException e) {
+ handleException("Error while constructing a URI from the fragments", e, messageContext);
+ }
+ return true;
+ }
+
+ private URI getInputAddress(MessageContext messageContext) {
+ String uriString = null;
+ if (inputProperty != null) {
+ Object prop = messageContext.getProperty(inputProperty);
+ if (prop != null && prop instanceof String) {
+ uriString = (String) prop;
+ }
+ } else if (messageContext.getTo() != null) {
+ uriString = messageContext.getTo().getAddress();
+ }
+
+ if (uriString != null) {
+ try {
+ return new URI(uriString);
+ } catch (URISyntaxException e) {
+ handleException("Malformed input URI: " + uriString, e, messageContext);
+ }
+ }
+ return null;
+ }
+
+ private Map<String, String> getHeaders(MessageContext synCtx) {
+ Axis2MessageContext axis2smc = (Axis2MessageContext) synCtx;
+ org.apache.axis2.context.MessageContext axis2MessageCtx =
+ axis2smc.getAxis2MessageContext();
+ Object headers = axis2MessageCtx.getProperty(
+ org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
+ Map<String, String> evaluatorHeaders = new HashMap<String, String>();
+
+ if (headers != null && headers instanceof Map) {
+ Map headersMap = (Map) headers;
+ for (Object key : headersMap.keySet()) {
+ if (key instanceof String && headersMap.get(key) instanceof String) {
+ evaluatorHeaders.put((String) key, (String) headersMap.get(key));
+ }
+ }
+ }
+ return evaluatorHeaders;
+ }
+
+ public void addRule(RewriteRule rule) {
+ rules.add(rule);
+ }
+
+ public List<RewriteRule> getRules() {
+ return rules;
+ }
+
+ public String getInputProperty() {
+ return inputProperty;
+ }
+
+ public void setInputProperty(String inputProperty) {
+ this.inputProperty = inputProperty;
+ }
+
+ public String getOutputProperty() {
+ return outputProperty;
+ }
+
+ public void setOutputProperty(String outputProperty) {
+ this.outputProperty = outputProperty;
+ }
+}
Added: synapse/trunk/java/modules/core/src/test/java/org/apache/synapse/mediators/transform/url/URLRewriteMediatorTest.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/test/java/org/apache/synapse/mediators/transform/url/URLRewriteMediatorTest.java?rev=990019&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/test/java/org/apache/synapse/mediators/transform/url/URLRewriteMediatorTest.java (added)
+++ synapse/trunk/java/modules/core/src/test/java/org/apache/synapse/mediators/transform/url/URLRewriteMediatorTest.java Fri Aug 27 05:06:23 2010
@@ -0,0 +1,192 @@
+/*
+ * 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.transform.url;
+
+import junit.framework.TestCase;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.commons.evaluators.EqualEvaluator;
+import org.apache.synapse.commons.evaluators.EvaluatorConstants;
+import org.apache.synapse.commons.evaluators.MatchEvaluator;
+import org.apache.synapse.commons.evaluators.source.URLTextRetriever;
+import org.apache.synapse.util.xpath.SynapseXPath;
+import org.apache.synapse.mediators.TestUtils;
+import org.apache.axis2.addressing.EndpointReference;
+
+import java.util.regex.Pattern;
+
+public class URLRewriteMediatorTest extends TestCase {
+
+ private String targetURL = "http://localhost:9000/services/SimpleStockQuoteService";
+
+ public void testUnconditionalRewriteScenario1() throws Exception {
+ URLRewriteMediator mediator = new URLRewriteMediator();
+
+ RewriteAction action = new RewriteAction();
+ action.setValue(targetURL);
+
+ RewriteRule rule = new RewriteRule();
+ rule.addRewriteAction(action);
+ mediator.addRule(rule);
+
+ MessageContext msgCtx = TestUtils.createLightweightSynapseMessageContext("<empty/>");
+ mediator.mediate(msgCtx);
+
+ assertEquals(targetURL, msgCtx.getTo().getAddress());
+ }
+
+ public void testUnconditionalRewriteScenario2() throws Exception {
+ URLRewriteMediator mediator = new URLRewriteMediator();
+ mediator.setOutputProperty("outURL");
+
+ RewriteAction action = new RewriteAction();
+ action.setValue(targetURL);
+
+ RewriteRule rule = new RewriteRule();
+ rule.addRewriteAction(action);
+ mediator.addRule(rule);
+
+ MessageContext msgCtx = TestUtils.createLightweightSynapseMessageContext("<empty/>");
+ mediator.mediate(msgCtx);
+
+ assertEquals(targetURL, msgCtx.getProperty("outURL"));
+ }
+
+ public void testUnconditionalRewriteScenario3() throws Exception {
+ URLRewriteMediator mediator = new URLRewriteMediator();
+ mediator.setOutputProperty("outURL");
+
+ RewriteAction action1 = new RewriteAction();
+ action1.setValue(targetURL);
+ RewriteRule rule1 = new RewriteRule();
+ rule1.addRewriteAction(action1);
+ mediator.addRule(rule1);
+
+ RewriteAction action2 = new RewriteAction();
+ action2.setValue("/services/SimpleStockQuoteService");
+ action2.setFragmentIndex(URIFragments.PATH);
+
+ RewriteAction action3 = new RewriteAction();
+ action3.setXpath(new SynapseXPath("get-property('port')"));
+ action3.setFragmentIndex(URIFragments.PORT);
+
+ RewriteRule rule2 = new RewriteRule();
+ rule2.addRewriteAction(action2);
+ rule2.addRewriteAction(action3);
+ mediator.addRule(rule2);
+
+ MessageContext msgCtx = TestUtils.createLightweightSynapseMessageContext("<empty/>");
+ msgCtx.setTo(new EndpointReference("http://localhost:8280"));
+ msgCtx.setProperty("port", 9000);
+ mediator.mediate(msgCtx);
+
+ assertEquals(targetURL, msgCtx.getProperty("outURL"));
+ }
+
+ public void testConditionalRewriteScenario1() throws Exception {
+ URLRewriteMediator mediator = new URLRewriteMediator();
+
+ RewriteAction action = new RewriteAction();
+ action.setValue(targetURL);
+
+ RewriteRule rule = new RewriteRule();
+ EqualEvaluator eval = new EqualEvaluator();
+ URLTextRetriever txtRtvr = new URLTextRetriever();
+ txtRtvr.setFragment(EvaluatorConstants.URI_FRAGMENTS.port.name());
+ eval.setTextRetriever(txtRtvr);
+ eval.setValue("8280");
+ rule.setCondition(eval);
+ rule.addRewriteAction(action);
+ mediator.addRule(rule);
+
+ MessageContext msgCtx = TestUtils.createLightweightSynapseMessageContext("<empty/>");
+ msgCtx.setTo(new EndpointReference("http://localhost:8280"));
+ mediator.mediate(msgCtx);
+
+ assertEquals(targetURL, msgCtx.getTo().getAddress());
+ }
+
+ public void testConditionalRewriteScenario2() throws Exception {
+ URLRewriteMediator mediator = new URLRewriteMediator();
+ mediator.setOutputProperty("outURL");
+
+ RewriteAction action = new RewriteAction();
+ action.setValue(targetURL);
+
+ RewriteRule rule = new RewriteRule();
+ EqualEvaluator eval = new EqualEvaluator();
+ URLTextRetriever txtRtvr = new URLTextRetriever();
+ txtRtvr.setFragment(EvaluatorConstants.URI_FRAGMENTS.port.name());
+ eval.setTextRetriever(txtRtvr);
+ eval.setValue("8280");
+ rule.setCondition(eval);
+ rule.addRewriteAction(action);
+ mediator.addRule(rule);
+
+ MessageContext msgCtx = TestUtils.createLightweightSynapseMessageContext("<empty/>");
+ msgCtx.setTo(new EndpointReference("http://localhost:8280"));
+ mediator.mediate(msgCtx);
+
+ assertEquals(targetURL, msgCtx.getProperty("outURL"));
+ }
+
+ public void testConditionalRewriteScenario3() throws Exception {
+ URLRewriteMediator mediator = new URLRewriteMediator();
+ mediator.setOutputProperty("outURL");
+
+ RewriteAction action1 = new RewriteAction();
+ action1.setValue("localhost");
+ action1.setFragmentIndex(URIFragments.HOST);
+ RewriteRule rule1 = new RewriteRule();
+ rule1.addRewriteAction(action1);
+ EqualEvaluator eval1 = new EqualEvaluator();
+ URLTextRetriever txtRtvr1 = new URLTextRetriever();
+ txtRtvr1.setFragment(EvaluatorConstants.URI_FRAGMENTS.host.name());
+ eval1.setTextRetriever(txtRtvr1);
+ eval1.setValue("myhost");
+ rule1.setCondition(eval1);
+ mediator.addRule(rule1);
+
+ RewriteAction action2 = new RewriteAction();
+ action2.setValue("/services/SimpleStockQuoteService");
+ action2.setFragmentIndex(URIFragments.PATH);
+
+ RewriteAction action3 = new RewriteAction();
+ action3.setXpath(new SynapseXPath("get-property('port')"));
+ action3.setFragmentIndex(URIFragments.PORT);
+
+ RewriteRule rule2 = new RewriteRule();
+ rule2.addRewriteAction(action2);
+ rule2.addRewriteAction(action3);
+ MatchEvaluator eval2 = new MatchEvaluator();
+ URLTextRetriever txtRtvr2 = new URLTextRetriever();
+ txtRtvr2.setFragment(EvaluatorConstants.URI_FRAGMENTS.path.name());
+ eval2.setTextRetriever(txtRtvr2);
+ eval2.setRegex(Pattern.compile(".*/MyService"));
+ rule2.setCondition(eval2);
+ mediator.addRule(rule2);
+
+ MessageContext msgCtx = TestUtils.createLightweightSynapseMessageContext("<empty/>");
+ msgCtx.setTo(new EndpointReference("http://myhost:8280/MyService"));
+ msgCtx.setProperty("port", 9000);
+ mediator.mediate(msgCtx);
+
+ assertEquals(targetURL, msgCtx.getProperty("outURL"));
+ }
+}