Repository: camel Updated Branches: refs/heads/master 6826e7a47 -> cbaeb0481
[CAMEL-11487] provided support for resources load through custom defined protocols by registering custom UrlHandlers Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cbaeb048 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cbaeb048 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cbaeb048 Branch: refs/heads/master Commit: cbaeb048175938b4268741a0ebf7f4aeaedbed22 Parents: 6826e7a Author: Andrea Tarocchi <ataro...@redhat.com> Authored: Fri Jun 30 16:18:15 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Tue Jul 4 09:14:16 2017 +0200 ---------------------------------------------------------------------- .../org/apache/camel/util/ResourceHelper.java | 10 ++ .../test/java/org/apache/camel/TestSupport.java | 34 +++++- .../ValidatorEndpointClearCachedSchemaTest.java | 68 +---------- .../apache/camel/urlhandler/custom/Handler.java | 42 +++++++ .../org/apache/camel/urlhandler/pd/Handler.java | 113 +++++++++++++++++++ .../apache/camel/util/ResourceHelperTest.java | 74 ++++++++++++ 6 files changed, 272 insertions(+), 69 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java b/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java index 316c179..6f28dac 100644 --- a/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java +++ b/camel-core/src/main/java/org/apache/camel/util/ResourceHelper.java @@ -128,6 +128,8 @@ public final class ResourceHelper { * <il>http:uri - to load the resource using HTTP</il> * <il>ref:nameOfBean - to lookup the resource in the {@link org.apache.camel.spi.Registry}</il> * <il>bean:nameOfBean.methodName - to lookup a bean in the {@link org.apache.camel.spi.Registry} and call the method</il> + * <il><customProtocol>:uri - to lookup the resource using a custom {@link java.net.URLStreamHandler} registered for the <customProtocol>, + * on how to register it @see java.net.URL#URL(java.lang.String, java.lang.String, int, java.lang.String)</il> * </ul> * If no prefix has been given, then the resource is loaded from the classpath * <p/> @@ -236,6 +238,11 @@ public final class ResourceHelper { } else if (uri.startsWith("classpath:")) { uri = ObjectHelper.after(uri, "classpath:"); uri = tryDecodeUri(uri); + } else if (uri.contains(":")) { + LOG.trace("Loading resource: {} with UrlHandler for protocol {}", uri, uri.split(":")[0]); + URL url = new URL(uri); + URLConnection con = url.openConnection(); + return con.getInputStream(); } // load from classpath by default @@ -288,6 +295,9 @@ public final class ResourceHelper { } else if (uri.startsWith("classpath:")) { uri = ObjectHelper.after(uri, "classpath:"); uri = tryDecodeUri(uri); + } else if (uri.contains(":")) { + LOG.trace("Loading resource: {} with UrlHandler for protocol {}", uri, uri.split(":")[0]); + return new URL(uri); } // load from classpath by default http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/TestSupport.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/TestSupport.java b/camel-core/src/test/java/org/apache/camel/TestSupport.java index 85a710c..70ee0bf 100644 --- a/camel-core/src/test/java/org/apache/camel/TestSupport.java +++ b/camel-core/src/test/java/org/apache/camel/TestSupport.java @@ -74,7 +74,7 @@ public abstract class TestSupport extends TestCase { /** * Returns a value builder for the given exchange property - * + * * @deprecated use {@link #exchangeProperty(String)} */ @Deprecated @@ -107,7 +107,7 @@ public abstract class TestSupport extends TestCase { /** * Returns a predicate and value builder for the outbound body on an * exchange - * + * * @deprecated use {@link #body()} */ @Deprecated @@ -118,7 +118,7 @@ public abstract class TestSupport extends TestCase { /** * Returns a predicate and value builder for the outbound message body as a * specific type - * + * * @deprecated use {@link #bodyAs(Class)} */ @Deprecated @@ -137,7 +137,7 @@ public abstract class TestSupport extends TestCase { /** * Returns a predicate and value builder for the fault message body as a * specific type - * + * * @deprecated use {@link #bodyAs(Class)} */ @Deprecated @@ -530,7 +530,7 @@ public abstract class TestSupport extends TestCase { * <p/> * Uses <tt>java.version</tt> from the system properties to determine the version. * - * @param version such as 1.6 or 6 + * @param version such as 1.6 or 6 * @return <tt>true</tt> if its that vendor. */ public static boolean isJavaVersion(String version) { @@ -556,4 +556,28 @@ public abstract class TestSupport extends TestCase { return Integer.parseInt(javaSpecVersion); } } + + /** + * Used for registering a sysetem property. + * <p/> + * if the property already contains the passed value nothing will happen. + * If the system property has already a value, the passed value will be appended separated by <tt>separator</tt> + * + * @param sysPropertyName the name of the system property to be set + * @param sysPropertyValue the value to be set for the system property passed as sysPropertyName + * @param separator the property separator to be used to append sysPropertyValue + * + */ + public static void registerSystemProperty(String sysPropertyName, String sysPropertyValue, String separator) { + synchronized (System.getProperties()) { + if (System.getProperties().contains(sysPropertyName)) { + String current = System.getProperty(sysPropertyName); + if (!current.contains(sysPropertyValue)) { + System.setProperty(sysPropertyName, current + separator + sysPropertyValue); + } + } else { + System.setProperty(sysPropertyName, sysPropertyValue); + } + } + } } http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java b/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java index e144208..e9151f1 100644 --- a/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java +++ b/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java @@ -90,9 +90,12 @@ public class ValidatorEndpointClearCachedSchemaTest extends ContextTestSupport { @Override protected CamelContext createCamelContext() throws Exception { + String handlerPackageSystemProp = "java.protocol.handler.pkgs"; + String customUrlHandlerPackage = "org.apache.camel.urlhandler"; + registerSystemProperty(handlerPackageSystemProp, customUrlHandlerPackage, "|"); + simpleReg = new SimpleRegistry(); context = new DefaultCamelContext(simpleReg); - context.setClassResolver(new ClassResolverImpl()); return context; } @@ -159,67 +162,4 @@ public class ValidatorEndpointClearCachedSchemaTest extends ContextTestSupport { } } - /** - * Class to simulate a change of the XSD document. During the first call of - * the resource a XSD is returned which does not fit to the XML document. In - * the second call a XSD fitting to the XML document is returned. - */ - static class ClassResolverImpl extends DefaultClassResolver { - - private final String xsdtemplate1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + // - "<xsd:schema targetNamespace=\"http://apache.camel.org/test\" xmlns=\"http://apache.camel.org/test\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" - + // - " <xsd:complexType name=\"TestMessage\">" + // - " <xsd:sequence>" + // - " <xsd:element name=\"Content\" type=\"xsd:string\" />" + // // - // wrong - // element - // name - // will - // cause - // the - // validation - // to - // fail - " </xsd:sequence>" + // - " <xsd:attribute name=\"attr\" type=\"xsd:string\" default=\"xsd1\"/>" + // - " </xsd:complexType>" + // - " <xsd:element name=\"TestMessage\" type=\"TestMessage\" />" + // - "</xsd:schema>"; // - - private final String xsdtemplate2 = xsdtemplate1.replace("\"Content\"", "\"MessageContent\""); // correct - // element - // name - // --> - // validation - // will - // be - // correct - - private byte[] xsd1 = xsdtemplate1.getBytes(StandardCharsets.UTF_8); - - private byte[] xsd2 = xsdtemplate2.getBytes(StandardCharsets.UTF_8); - - private volatile short counter; - - @Override - public InputStream loadResourceAsStream(String uri) { - if (uri.startsWith("pd:")) { - byte[] xsd; - if (counter == 0) { - xsd = xsd1; - LOG.info("resolved XSD1"); - } else { - xsd = xsd2; - LOG.info("resolved XSD2"); - } - counter++; - return new ByteArrayInputStream(xsd); - } else { - return super.loadResourceAsStream(uri); - } - } - - } - } http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java b/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java new file mode 100644 index 0000000..54aef4b --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/urlhandler/custom/Handler.java @@ -0,0 +1,42 @@ +/** + * 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.urlhandler.custom; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +public class Handler extends URLStreamHandler { + @Override + protected URLConnection openConnection(URL u) throws IOException { + final String echo = u.getHost(); + return new URLConnection(u) { + @Override + public void connect() throws IOException { + connected = true; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(echo.getBytes()); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java b/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java new file mode 100644 index 0000000..c14b9c1 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/urlhandler/pd/Handler.java @@ -0,0 +1,113 @@ +/** + * 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.urlhandler.pd; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.nio.charset.StandardCharsets; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class to simulate a change of the XSD document. During the first call of + * the resource a XSD is returned which does not fit to the XML document. In + * the second call a XSD fitting to the XML document is returned. + * Used in org.apache.camel.component.validator.ValidatorEndpointClearCachedSchemaTest + */ +public class Handler extends URLStreamHandler { + private static int counter; + private static final Logger LOG = LoggerFactory.getLogger(Handler.class); + + private final String xsdtemplate1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + // + "<xsd:schema targetNamespace=\"http://apache.camel.org/test\" xmlns=\"http://apache.camel.org/test\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" + + // + " <xsd:complexType name=\"TestMessage\">" + // + " <xsd:sequence>" + // + " <xsd:element name=\"Content\" type=\"xsd:string\" />" + // // + // wrong + // element + // name + // will + // cause + // the + // validation + // to + // fail + " </xsd:sequence>" + // + " <xsd:attribute name=\"attr\" type=\"xsd:string\" default=\"xsd1\"/>" + // + " </xsd:complexType>" + // + " <xsd:element name=\"TestMessage\" type=\"TestMessage\" />" + // + "</xsd:schema>"; // + + private final String xsdtemplate2 = xsdtemplate1.replace("\"Content\"", "\"MessageContent\""); // correct + // element + // name + // --> + // validation + // will + // be + // correct + + private byte[] xsd1 = xsdtemplate1.getBytes(StandardCharsets.UTF_8); + private byte[] xsd2 = xsdtemplate2.getBytes(StandardCharsets.UTF_8); + + @Override + protected URLConnection openConnection(URL u) throws IOException { + if (getCounter() == 0) { + LOG.info("resolved XSD1"); + incrementCounter(); + return new URLConnection(u) { + @Override + public void connect() throws IOException { + connected = true; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(xsd1); + } + }; + } else { + LOG.info("resolved XSD2"); + incrementCounter(); + return new URLConnection(u) { + @Override + public void connect() throws IOException { + connected = true; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(xsd2); + } + }; + } + } + + public static synchronized void incrementCounter() { + counter++; + } + + public static synchronized int getCounter() { + return counter; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/cbaeb048/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java b/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java index b0448e9..b6a4592 100644 --- a/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java +++ b/camel-core/src/test/java/org/apache/camel/util/ResourceHelperTest.java @@ -17,17 +17,28 @@ package org.apache.camel.util; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; import java.util.LinkedHashMap; import java.util.Map; +import static javax.imageio.ImageIO.read; + import org.apache.camel.CamelContext; import org.apache.camel.TestSupport; +import org.apache.camel.converter.IOConverter; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.impl.SimpleRegistry; +import static org.junit.Assert.assertThat; + /** * */ @@ -98,6 +109,7 @@ public class ResourceHelperTest extends TestSupport { context.stop(); } + public void testLoadClasspathDefault() throws Exception { CamelContext context = new DefaultCamelContext(); context.start(); @@ -169,6 +181,68 @@ public class ResourceHelperTest extends TestSupport { context.stop(); } + public void testLoadCustomUrlasInputStream() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.start(); + + String handlerPackageSystemProp = "java.protocol.handler.pkgs"; + String customUrlHandlerPackage = "org.apache.camel.urlhandler"; + + registerSystemProperty(handlerPackageSystemProp, customUrlHandlerPackage, "|"); + + InputStream is = ResourceHelper.resolveMandatoryResourceAsInputStream(context, "custom://hello"); + assertNotNull(is); + + assertEquals("hello", IOConverter.toString(IOHelper.buffered(new InputStreamReader(is, "UTF-8")))); + + context.stop(); + } + + public void testLoadCustomUrlasInputStreamFail() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.start(); + + try { + InputStream is = ResourceHelper.resolveMandatoryResourceAsInputStream(context, "custom://hello"); + assertNotNull(is); + } catch (Exception e) { + assertEquals("unknown protocol: custom", e.getMessage()); + } + + context.stop(); + } + + public void testLoadCustomUrl() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.start(); + + String handlerPackageSystemProp = "java.protocol.handler.pkgs"; + String customUrlHandlerPackage = "org.apache.camel.urlhandler"; + registerSystemProperty(handlerPackageSystemProp, customUrlHandlerPackage, "|"); + + URL url = ResourceHelper.resolveResourceAsUrl(context.getClassResolver(), "custom://hello"); + assertNotNull(url); + + String text = context.getTypeConverter().convertTo(String.class, url); + assertNotNull(text); + assertTrue(text.contains("hello")); + + context.stop(); + } + + public void testLoadCustomUrlFail() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.start(); + + try { + URL url = ResourceHelper.resolveResourceAsUrl(context.getClassResolver(), "custom://hello"); + } catch (Exception e) { + assertEquals("unknown protocol: custom", e.getMessage()); + } + + context.stop(); + } + public void testIsHttp() throws Exception { assertFalse(ResourceHelper.isHttpUri("direct:foo")); assertFalse(ResourceHelper.isHttpUri(""));