Author: davsclaus Date: Tue Sep 25 06:44:17 2012 New Revision: 1389728 URL: http://svn.apache.org/viewvc?rev=1389728&view=rev Log: CAMEL-4857: Allow components to use rawUri when creating endpoints. This give component developers full control whether to use raw or encoded uri.
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/issues/Camel4857UriIssueTest.java (with props) Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java?rev=1389728&r1=1389727&r2=1389728&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java Tue Sep 25 06:44:17 2012 @@ -26,21 +26,36 @@ public interface Component extends Camel /** * Attempt to resolve an endpoint for the given URI if the component is - * capable of handling the URI + * capable of handling the URI. + * <p/> + * See {@link #useRawUri()} for controlling whether the passed in uri + * should be as-is (raw), or encoded (default). * - * @param uri the URI to create + * @param uri the URI to create; either raw or encoded (default) * @return a newly created {@link Endpoint} or null if this component cannot create * {@link Endpoint} instances using the given uri * @throws Exception is thrown if error creating the endpoint + * @see #useRawUri() */ Endpoint createEndpoint(String uri) throws Exception; - + + /** + * Whether to use raw or encoded uri, when creating endpoints. + * + * @return <tt>true</tt> to use raw uris, <tt>false</tt> to use encoded uris (default). + * + * @since Camel 2.11.0 + */ + boolean useRawUri(); + /** * Attempt to create a configuration object from the given uri - * + * * @param uri the configuration URI * @return a newly created {@link EndpointConfiguration} * @throws Exception is thrown if the configuration URI is invalid + * + * @since Camel 2.9.0 */ EndpointConfiguration createConfiguration(String uri) throws Exception; } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java?rev=1389728&r1=1389727&r2=1389728&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java Tue Sep 25 06:44:17 2012 @@ -437,10 +437,12 @@ public class DefaultCamelContext extends throw new ResolveEndpointFailedException(uri, e); } + final String rawUri = uri; + // normalize uri so we can do endpoint hits with minor mistakes and parameters is not in the same order uri = normalizeEndpointUri(uri); - log.trace("Getting endpoint with normalized uri: {}", uri); + log.trace("Getting endpoint with raw uri: {}, normalized uri: {}", rawUri, uri); Endpoint answer; String scheme = null; @@ -457,7 +459,11 @@ public class DefaultCamelContext extends // Ask the component to resolve the endpoint. if (component != null) { // Have the component create the endpoint if it can. - answer = component.createEndpoint(uri); + if (component.useRawUri()) { + answer = component.createEndpoint(rawUri); + } else { + answer = component.createEndpoint(uri); + } if (answer != null && log.isDebugEnabled()) { log.debug("{} converted to endpoint: {} by component: {}", new Object[]{URISupport.sanitizeUri(uri), answer, component}); Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java?rev=1389728&r1=1389727&r2=1389728&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java Tue Sep 25 06:44:17 2012 @@ -71,7 +71,7 @@ public abstract class DefaultComponent e // check URI string to the unsafe URI characters String encodedUri = preProcessUri(uri); URI u = new URI(encodedUri); - String path = u.getSchemeSpecificPart(); + String path = useRawUri() ? u.getRawSchemeSpecificPart() : u.getSchemeSpecificPart(); // lets trim off any query arguments if (path.startsWith("//")) { @@ -83,12 +83,14 @@ public abstract class DefaultComponent e } Map<String, Object> parameters = URISupport.parseParameters(u); - validateURI(encodedUri, path, parameters); + // use encoded or raw uri? + uri = useRawUri() ? uri : encodedUri; + validateURI(uri, path, parameters); if (LOG.isDebugEnabled()) { - LOG.debug("Creating endpoint uri=[{}], path=[{}], parameters=[{}]", new Object[]{URISupport.sanitizeUri(encodedUri), URISupport.sanitizePath(path), parameters}); + LOG.debug("Creating endpoint uri=[{}], path=[{}], parameters=[{}]", new Object[]{URISupport.sanitizeUri(uri), URISupport.sanitizePath(path), parameters}); } - Endpoint endpoint = createEndpoint(encodedUri, path, parameters); + Endpoint endpoint = createEndpoint(uri, path, parameters); if (endpoint == null) { return null; } @@ -102,11 +104,11 @@ public abstract class DefaultComponent e // if endpoint is strict (not lenient) and we have unknown parameters configured then // fail if there are parameters that could not be set, then they are probably misspell or not supported at all if (!endpoint.isLenientProperties()) { - validateParameters(encodedUri, parameters, null); + validateParameters(uri, parameters, null); } } - afterConfiguration(encodedUri, path, endpoint, parameters); + afterConfiguration(uri, path, endpoint, parameters); return endpoint; } @@ -116,12 +118,19 @@ public abstract class DefaultComponent e return config; } + public boolean useRawUri() { + // should use encoded uri by default + return false; + } + /** * Strategy to do post configuration logic. * <p/> * Can be used to construct an URI based on the remaining parameters. For example the parameters that configures * the endpoint have been removed from the parameters which leaves only the additional parameters left. * + * @param uri the uri + * @param remaining the remaining part of the URI without the query parameters or component prefix * @param endpoint the created endpoint * @param parameters the remaining parameters after the endpoint has been created and parsed the parameters * @throws Exception can be thrown to indicate error creating the endpoint @@ -133,7 +142,7 @@ public abstract class DefaultComponent e /** * Strategy for validation of parameters, that was not able to be resolved to any endpoint options. * - * @param uri the uri - the uri the end user provided untouched + * @param uri the uri * @param parameters the parameters, an empty map if no parameters given * @param optionPrefix optional prefix to filter the parameters for validation. Use <tt>null</tt> for validate all. * @throws ResolveEndpointFailedException should be thrown if the URI validation failed @@ -155,7 +164,7 @@ public abstract class DefaultComponent e /** * Strategy for validation of the uri when creating the endpoint. * - * @param uri the uri - the uri the end user provided untouched + * @param uri the uri * @param path the path - part after the scheme * @param parameters the parameters, an empty map if no parameters given * @throws ResolveEndpointFailedException should be thrown if the URI validation failed @@ -206,6 +215,7 @@ public abstract class DefaultComponent e * @param parameters the optional parameters passed in * @return a newly created endpoint or null if the endpoint cannot be * created based on the inputs + * @throws Exception is thrown if error creating the endpoint */ protected abstract Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception; Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java?rev=1389728&r1=1389727&r2=1389728&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java Tue Sep 25 06:44:17 2012 @@ -239,6 +239,11 @@ public class ConfigurationHelperTest { } return null; } + + @Override + public boolean useRawUri() { + return false; + } } public static class UriDumpConfiguration extends DefaultEndpointConfiguration { Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java?rev=1389728&r1=1389727&r2=1389728&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java Tue Sep 25 06:44:17 2012 @@ -91,5 +91,10 @@ public class EndpointConfigurationTest { public EndpointConfiguration createConfiguration(String uri) throws Exception { return new MappedEndpointConfiguration(getCamelContext()); } + + @Override + public boolean useRawUri() { + return false; + } } } Added: camel/trunk/camel-core/src/test/java/org/apache/camel/issues/Camel4857UriIssueTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/issues/Camel4857UriIssueTest.java?rev=1389728&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/issues/Camel4857UriIssueTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/issues/Camel4857UriIssueTest.java Tue Sep 25 06:44:17 2012 @@ -0,0 +1,100 @@ +/** + * 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.camel.issues; + +import java.util.Map; + +import org.apache.camel.Consumer; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Endpoint; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.impl.DefaultComponent; +import org.apache.camel.impl.DefaultEndpoint; + +/** + * CAMEL-4857 issue test + */ +public class Camel4857UriIssueTest extends ContextTestSupport { + + /** + * An URI of Camel Beanstalk component consists of a hostname, port and a list + * of tube names. Tube names are separated by "+" character (which is more or less + * usually used on the Web to make lists), but every tube name may contain URI special + * characters like ? or + + */ + class MyEndpoint extends DefaultEndpoint { + String uri; + String remaining; + + public MyEndpoint(final String uri, final String remaining) { + this.uri = uri; + this.remaining = remaining; + } + + public Producer createProducer() throws Exception { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Consumer createConsumer(Processor processor) throws Exception { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean isSingleton() { + return true; + } + + public String getUri() { + return uri; + } + } + + class MyComponent extends DefaultComponent { + + @Override + protected Endpoint createEndpoint(final String uri, final String remaining, final Map<String, Object> parameters) throws Exception { + return new MyEndpoint(uri, remaining); + } + + @Override + public boolean useRawUri() { + // we want the raw uri, so our component can understand the endpoint configuration as it was typed + return true; + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + context.addComponent("my", new MyComponent()); + } + + public void testExclamationInUri() { + // %3F is not an ?, it's part of tube name. + MyEndpoint endpoint = context.getEndpoint("my:host:11303/tube1+tube%2B+tube%3F", MyEndpoint.class); + assertNotNull("endpoint", endpoint); + assertEquals("my:host:11303/tube1+tube%2B+tube%3F", endpoint.getUri()); + } + + public void testPath() { + // Here a tube name is "tube+" and written in URI as "tube%2B", but it gets + // normalized, so that an endpoint sees "tube1+tube+" + MyEndpoint endpoint = context.getEndpoint("my:host:11303/tube1+tube%2B", MyEndpoint.class); + assertEquals("Path contains several tube names, every tube name may have + or ? characters", "host:11303/tube1+tube%2B", endpoint.remaining); + } + +} Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/issues/Camel4857UriIssueTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/issues/Camel4857UriIssueTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date