CAMEL-9486: Add support for alternative syntax in Camel @UriEndpoint so we are aware of this.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1a164074 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1a164074 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1a164074 Branch: refs/heads/master Commit: 1a1640747bc35705c6cdad579b8175fb417536fa Parents: b89a7c8 Author: Claus Ibsen <davscl...@apache.org> Authored: Wed Jan 6 16:41:58 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed Jan 6 16:41:58 2016 +0100 ---------------------------------------------------------------------- .../component/file/remote/FtpEndpoint.java | 3 +- .../component/file/remote/FtpsEndpoint.java | 3 +- .../apache/camel/component/ssh/SshEndpoint.java | 3 +- .../camel/catalog/DefaultCamelCatalog.java | 52 +++++++++++++++++++- .../apache/camel/catalog/CamelCatalogTest.java | 27 ++++++++++ .../tools/apt/EndpointAnnotationProcessor.java | 12 +++++ .../camel/tools/apt/model/ComponentModel.java | 9 ++++ .../java/org/apache/camel/spi/UriEndpoint.java | 10 ++++ 8 files changed, 115 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java index 87152ac..f5d0297 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java @@ -37,7 +37,8 @@ import org.apache.commons.net.ftp.FTPFile; * The ftp component is used for uploading or downloading files from FTP servers. */ @UriEndpoint(scheme = "ftp", extendsScheme = "file", title = "FTP", - syntax = "ftp:host:port/directoryName", consumerClass = FtpConsumer.class, label = "file") + syntax = "ftp:host:port/directoryName", alternativeSyntax = "ftp:username:password@host:port/directoryName", + consumerClass = FtpConsumer.class, label = "file") public class FtpEndpoint<T extends FTPFile> extends RemoteFileEndpoint<FTPFile> { protected int soTimeout; protected int dataTimeout; http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpsEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpsEndpoint.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpsEndpoint.java index d2804cd..da6eba2 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpsEndpoint.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpsEndpoint.java @@ -40,7 +40,8 @@ import org.apache.commons.net.ftp.FTPSClient; * The ftps (FTP secure SSL/TLS) component is used for uploading or downloading files from FTP servers. */ @UriEndpoint(scheme = "ftps", extendsScheme = "file", title = "FTPS", - syntax = "ftps:host:port/directoryName", consumerClass = FtpConsumer.class, label = "file") + syntax = "ftps:host:port/directoryName", alternativeSyntax = "ftps:username:password@host:port/directoryName", + consumerClass = FtpConsumer.class, label = "file") public class FtpsEndpoint extends FtpEndpoint<FTPFile> { @UriParam protected FtpsConfiguration configuration; http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java index d4e777a..d7a90c9 100644 --- a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java +++ b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java @@ -29,7 +29,8 @@ import org.slf4j.LoggerFactory; /** * The ssh component enables access to SSH servers such that you can send an SSH command, and process the response. */ -@UriEndpoint(scheme = "ssh", title = "SSH", syntax = "ssh:host:port", consumerClass = SshConsumer.class, label = "file") +@UriEndpoint(scheme = "ssh", title = "SSH", syntax = "ssh:host:port", alternativeSyntax = "ssh:username:password@host:port", + consumerClass = SshConsumer.class, label = "file") public class SshEndpoint extends ScheduledPollEndpoint { protected final Logger log = LoggerFactory.getLogger(getClass()); http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java index db0f5ef..e106897 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java @@ -940,13 +940,34 @@ public class DefaultCamelCatalog implements CamelCatalog { throw new IllegalArgumentException("Cannot find endpoint with scheme " + scheme); } + Map<String, String> userInfoOptions = new LinkedHashMap<String, String>(); + + // do we have user info in authority? + boolean userInfo = false; + String username = null; + String password = null; + if (u.getUserInfo() != null) { + userInfo = true; + String[] parts = u.getUserInfo().split(":"); + if (parts.length == 2) { + username = parts[0]; + password = parts[1]; + } else { + // only username + username = u.getUserInfo(); + } + } + // grab the syntax String syntax = null; + String alternativeSyntax = null; List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("component", json, false); for (Map<String, String> row : rows) { if (row.containsKey("syntax")) { syntax = row.get("syntax"); - break; + } + if (row.containsKey("alternativeSyntax")) { + alternativeSyntax = row.get("alternativeSyntax"); } } if (syntax == null) { @@ -955,11 +976,35 @@ public class DefaultCamelCatalog implements CamelCatalog { // clip the scheme from the syntax syntax = after(syntax, ":"); + if (alternativeSyntax != null) { + alternativeSyntax = after(alternativeSyntax, ":"); + } // clip the scheme from the uri uri = after(uri, ":"); String uriPath = stripQuery(uri); + // do the component support userinfo? + if (alternativeSyntax != null && alternativeSyntax.contains("@")) { + int idx = alternativeSyntax.indexOf("@"); + String fields = alternativeSyntax.substring(0, idx); + String[] names = fields.split(":"); + if (userInfo && names.length == 2) { + userInfoOptions.put(names[0], username); + if (password != null) { + // password is optional + userInfoOptions.put(names[1], password); + } + } + } + // strip user info from uri path + if (userInfo) { + int idx = uriPath.indexOf('@'); + if (idx > -1) { + uriPath = uriPath.substring(idx + 1); + } + } + // strip double slash in the start if (uriPath != null && uriPath.startsWith("//")) { uriPath = uriPath.substring(2); @@ -1016,6 +1061,11 @@ public class DefaultCamelCatalog implements CamelCatalog { // now parse the uri to know which part isw what Map<String, String> options = new LinkedHashMap<String, String>(); + // include the username and password from the userinfo section + if (!userInfoOptions.isEmpty()) { + options.putAll(userInfoOptions); + } + // word contains the syntax path elements Iterator<String> it = word2.iterator(); for (int i = 0; i < word.size(); i++) { http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java index 16627ff..26b4788 100644 --- a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java +++ b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java @@ -392,6 +392,25 @@ public class CamelCatalogTest { } @Test + public void testEndpointPropertiesSshWithUserInfo() throws Exception { + Map<String, String> map = catalog.endpointProperties("ssh:localhost:8101?username=scott&password=tiger"); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals("8101", map.get("port")); + assertEquals("localhost", map.get("host")); + assertEquals("scott", map.get("username")); + assertEquals("tiger", map.get("password")); + + map = catalog.endpointProperties("ssh://scott:tiger@localhost:8101"); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals("8101", map.get("port")); + assertEquals("localhost", map.get("host")); + assertEquals("scott", map.get("username")); + assertEquals("tiger", map.get("password")); + } + + @Test public void validateProperties() throws Exception { // valid EndpointValidationResult result = catalog.validateEndpointProperties("log:mylog"); @@ -505,6 +524,14 @@ public class CamelCatalogTest { // 2 slash after component name result = catalog.validateEndpointProperties("atmos://put?remotePath=/dummy.txt"); assertTrue(result.isSuccess()); + + // userinfo in authority with username and password + result = catalog.validateEndpointProperties("ssh://karaf:karaf@localhost:8101"); + assertTrue(result.isSuccess()); + + // userinfo in authority without password + result = catalog.validateEndpointProperties("ssh://scott@localhost:8101?certResource=classpath:test_rsa&useFixedDelay=true&delay=5000&pollCommand=features:list%0A"); + assertTrue(result.isSuccess()); } @Test http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java index 9c7a65d..02c1af1 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java @@ -135,6 +135,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { ComponentModel componentModel = findComponentProperties(roundEnv, uriEndpoint, classElement, title, scheme, extendsScheme, label); String syntax = componentModel.getSyntax(); + String alternativeSyntax = componentModel.getAlternativeSyntax(); String description = componentModel.getDescription(); writer.println("<html>"); @@ -145,6 +146,9 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { writer.println("<h1>" + title + "</h1>"); writer.println("<b>Scheme:</b> " + scheme + "<br/>"); writer.println("<b>Syntax:</b> " + syntax + "<br/>"); + if (alternativeSyntax != null) { + writer.println("<b>Alternative Syntax:</b> " + alternativeSyntax + "<br/>"); + } writer.println("<b>Description:</b> " + description + "<br/>"); writer.println("<b>Deprecated:</b>" + componentModel.isDeprecated() + "<br/>"); writer.println("<b>Maven:</b> " + componentModel.getGroupId() + "/" + componentModel.getArtifactId() + "/" + componentModel.getVersionId() + "<br/>"); @@ -210,6 +214,9 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { buffer.append("\n \"extendsScheme\": \"").append(componentModel.getExtendsScheme()).append("\","); } buffer.append("\n \"syntax\": \"").append(componentModel.getSyntax()).append("\","); + if (componentModel.getAlternativeSyntax() != null) { + buffer.append("\n \"alternativeSyntax\": \"").append(componentModel.getAlternativeSyntax()).append("\","); + } buffer.append("\n \"title\": \"").append(componentModel.getTitle()).append("\","); buffer.append("\n \"description\": \"").append(componentModel.getDescription()).append("\","); buffer.append("\n \"label\": \"").append(getOrElse(componentModel.getLabel(), "")).append("\","); @@ -435,6 +442,11 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { // if the scheme is an alias then replace the scheme name from the syntax with the alias String syntax = scheme + ":" + Strings.after(uriEndpoint.syntax(), ":"); + // alternative syntax is optional + if (!Strings.isNullOrEmpty(uriEndpoint.alternativeSyntax())) { + String alternativeSyntax = scheme + ":" + Strings.after(uriEndpoint.alternativeSyntax(), ":"); + model.setAlternativeSyntax(alternativeSyntax); + } model.setExtendsScheme(extendsScheme); model.setSyntax(syntax); http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java index 2962e91..7efdbb7 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java @@ -21,6 +21,7 @@ public final class ComponentModel { private String scheme; private String extendsScheme; private String syntax; + private String alternativeSyntax; private String javaType; private String title; private String description; @@ -57,6 +58,14 @@ public final class ComponentModel { this.syntax = syntax; } + public String getAlternativeSyntax() { + return alternativeSyntax; + } + + public void setAlternativeSyntax(String alternativeSyntax) { + this.alternativeSyntax = alternativeSyntax; + } + public String getJavaType() { return javaType; } http://git-wip-us.apache.org/repos/asf/camel/blob/1a164074/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java ---------------------------------------------------------------------- diff --git a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java index b557d51..2b116e1 100644 --- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java +++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java @@ -74,6 +74,16 @@ public @interface UriEndpoint { String syntax(); /** + * If the endpoint supports specifying username and/or password in the UserInfo part of the URI, then the + * alternative syntax can represent this such as: + * <ul> + * <li>ftp:userName:password@host:port/directoryName</li> + * <li>ssh:username:password@host:port</li> + * </ul> + */ + String alternativeSyntax() default ""; + + /** * Represents the consumer class which is injected and created by consumers */ Class<?> consumerClass() default Object.class;