From 950dea86f4e945fbf376ef3843c0101a2ca569b8 Mon Sep 17 00:00:00 2001 From: Anu Engineer Date: Thu, 31 May 2018 11:28:42 -0700 Subject: [PATCH] HDDS-112. OzoneShell should support commands with url without scheme. Contributed by Lokesh Jain. --- .../acceptance/ozone-shell.robot | 21 ++++++++ .../hadoop/ozone/web/ozShell/Handler.java | 49 ++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/acceptance-test/src/test/robotframework/acceptance/ozone-shell.robot b/hadoop-ozone/acceptance-test/src/test/robotframework/acceptance/ozone-shell.robot index 0f01b8d8f0..7ff491057f 100644 --- a/hadoop-ozone/acceptance-test/src/test/robotframework/acceptance/ozone-shell.robot +++ b/hadoop-ozone/acceptance-test/src/test/robotframework/acceptance/ozone-shell.robot @@ -189,6 +189,27 @@ Test ozone shell (RpcClient without hostname) Execute on datanode ozone oz -deleteBucket o3:///hive/bb1 Execute on datanode ozone oz -deleteVolume o3:///hive -user bilbo +Test ozone shell (no scheme - RpcClient used by default) + Execute on datanode ozone oz -createVolume /hive -user bilbo -quota 100TB -root + ${result} = Execute on datanode ozone oz -listVolume / -user bilbo | grep -Ev 'Removed|WARN|DEBUG|ERROR|INFO|TRACE' | jq -r '.[] | select(.volumeName=="hive")' + Should contain ${result} createdOn + Execute on datanode ozone oz -updateVolume /hive -user bill -quota 10TB + ${result} = Execute on datanode ozone oz -infoVolume /hive | grep -Ev 'Removed|WARN|DEBUG|ERROR|INFO|TRACE' | jq -r '. | select(.volumeName=="hive") | .owner | .name' + Should Be Equal ${result} bill + ${result} = Execute on datanode ozone oz -infoVolume /hive | grep -Ev 'Removed|WARN|DEBUG|ERROR|INFO|TRACE' | jq -r '. | select(.volumeName=="hive") | .quota | .size' + Should Be Equal ${result} 10 + Execute on datanode ozone oz -createBucket /hive/bb1 + ${result} = Execute on datanode ozone oz -infoBucket /hive/bb1 | grep -Ev 'Removed|WARN|DEBUG|ERROR|INFO|TRACE' | jq -r '. | select(.bucketName=="bb1") | .storageType' + Should Be Equal ${result} DISK + ${result} = Execute on datanode ozone oz -updateBucket /hive/bb1 -addAcl user:frodo:rw,group:samwise:r | grep -Ev 'Removed|WARN|DEBUG|ERROR|INFO|TRACE' | jq -r '. | select(.bucketName=="bb1") | .acls | .[] | select(.name=="samwise") | .type' + Should Be Equal ${result} GROUP + ${result} = Execute on datanode ozone oz -updateBucket /hive/bb1 -removeAcl group:samwise:r | grep -Ev 'Removed|WARN|DEBUG|ERROR|INFO|TRACE' | jq -r '. | select(.bucketName=="bb1") | .acls | .[] | select(.name=="frodo") | .type' + Should Be Equal ${result} USER + ${result} = Execute on datanode ozone oz -listBucket /hive/ | grep -Ev 'Removed|WARN|DEBUG|ERROR|INFO|TRACE' | jq -r '.[] | select(.bucketName=="bb1") | .volumeName' + Should Be Equal ${result} hive + Execute on datanode ozone oz -deleteBucket /hive/bb1 + Execute on datanode ozone oz -deleteVolume /hive -user bilbo + *** Keywords *** Startup Ozone Cluster diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java index 7fe6bb86c1..a66e227d5c 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java @@ -69,13 +69,16 @@ protected URI verifyURI(String uri) throw new OzoneClientException( "Ozone URI is needed to execute this command."); } - URIBuilder ozoneURI = new URIBuilder(uri); + URIBuilder ozoneURI = new URIBuilder(stringToUri(uri)); if (ozoneURI.getPort() == 0) { ozoneURI.setPort(Shell.DEFAULT_OZONE_PORT); } Configuration conf = new OzoneConfiguration(); String scheme = ozoneURI.getScheme(); + if (ozoneURI.getScheme() == null || scheme.isEmpty()) { + scheme = OZONE_URI_SCHEME; + } if (scheme.equals(OZONE_HTTP_SCHEME)) { if (ozoneURI.getHost() != null) { if (ozoneURI.getPort() == -1) { @@ -87,7 +90,7 @@ protected URI verifyURI(String uri) } else { client = OzoneClientFactory.getRestClient(conf); } - } else if (scheme.equals(OZONE_URI_SCHEME) || scheme.isEmpty()) { + } else if (scheme.equals(OZONE_URI_SCHEME)) { if (ozoneURI.getHost() != null) { if (ozoneURI.getPort() == -1) { client = OzoneClientFactory.getRpcClient(ozoneURI.getHost()); @@ -103,4 +106,46 @@ protected URI verifyURI(String uri) } return ozoneURI.build(); } + + /** Construct a URI from a String with unescaped special characters + * that have non-standard semantics. e.g. /, ?, #. A custom parsing + * is needed to prevent misbehavior. + * @param pathString The input path in string form + * @return URI + */ + private static URI stringToUri(String pathString) throws IOException { + // parse uri components + String scheme = null; + String authority = null; + int start = 0; + + // parse uri scheme, if any + int colon = pathString.indexOf(':'); + int slash = pathString.indexOf('/'); + if (colon > 0 && (slash == colon +1)) { + // has a non zero-length scheme + scheme = pathString.substring(0, colon); + start = colon + 1; + } + + // parse uri authority, if any + if (pathString.startsWith("//", start) && + (pathString.length()-start > 2)) { + start += 2; + int nextSlash = pathString.indexOf('/', start); + int authEnd = nextSlash > 0 ? nextSlash : pathString.length(); + authority = pathString.substring(start, authEnd); + start = authEnd; + } + // uri path is the rest of the string. ? or # are not interpreted, + // but any occurrence of them will be quoted by the URI ctor. + String path = pathString.substring(start, pathString.length()); + + // Construct the URI + try { + return new URI(scheme, authority, path, null, null); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } + } }