From 2a3917d6fe0cfc0a765df36140c859ecd4cb5987 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Thu, 7 Mar 2024 12:21:58 -0500 Subject: [PATCH] HPCC4J-581 WsFS Client should add path delim only if needed (#690) - Introduces functionality to strip trailing white space - Adds trimright utility functionality - Adds new test cases - Adjusts pre-existing test cases to expected | actual format - Do not trim original string parameter - Do not duplicate Path URL param Signed-off-by: Rodrigo Pastrana --- .../ws/client/HPCCFileSprayClient.java | 13 +-- .../hpccsystems/ws/client/utils/Utils.java | 43 ++++++++ .../ws/client/utils/UtilsTest.java | 98 +++++++++++-------- 3 files changed, 104 insertions(+), 50 deletions(-) diff --git a/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCFileSprayClient.java b/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCFileSprayClient.java index 87d0c5d61..a7283a6cd 100644 --- a/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCFileSprayClient.java +++ b/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCFileSprayClient.java @@ -1004,9 +1004,8 @@ public ProgressResponseWrapper sprayVariable(DelimitedDataOptions options, DropZ if (targetDropZone == null) throw new Exception("TargetDropZone object not available!"); SprayVariable request = new SprayVariable(); - request.setSourceIP(targetDropZone.getNetAddress()); - request.setSourcePath(targetDropZone.getPath() + "/" + sourceFileName); + request.setSourcePath(Utils.ensureTrailingPathSlash(targetDropZone.getPath()) + sourceFileName); request.setDestGroup(destGroup); request.setDestLogicalName(targetFileName); request.setOverwrite(overwrite); @@ -1162,7 +1161,7 @@ public ProgressResponseWrapper sprayXML(DropZoneWrapper targetDropZone, String s request.setDestGroup(destGroup); request.setSourceIP(targetDropZone.getNetAddress()); - request.setSourcePath(targetDropZone.getPath() + "/" + sourceFileName); + request.setSourcePath(Utils.ensureTrailingPathSlash(targetDropZone.getPath()) + sourceFileName); request.setDestLogicalName(targetFileName); request.setOverwrite(overwrite); request.setSourceFormat(format.getValue()); @@ -1318,7 +1317,7 @@ public ProgressResponseWrapper sprayFixed(DropZoneWrapper targetDropZone, String request.setDestGroup(destGroup); request.setSourceRecordSize(recordSize); request.setSourceIP(targetDropZone.getNetAddress()); - request.setSourcePath(targetDropZone.getPath() + "/" + sourceFileName); + request.setSourcePath(Utils.ensureTrailingPathSlash(targetDropZone.getPath()) + sourceFileName); request.setDestLogicalName(targetFileLabel); request.setOverwrite(overwrite); request.setPrefix(prefix); @@ -1488,15 +1487,11 @@ public boolean uploadLargeFile(File uploadFile, DropZoneWrapper dropZone) return false; } - uploadurlbuilder += "&NetAddress=" + dropZone.getNetAddress() + "&Path=" + dropZone.getPath(); + uploadurlbuilder += "&NetAddress=" + dropZone.getNetAddress() + "&Path=" + Utils.ensureTrailingPathSlash(dropZone.getPath()); if (!dropZone.getName().isEmpty()) uploadurlbuilder += "&DropZoneName=" + dropZone.getName(); - String path = dropZone.getPath().trim(); - if (!path.endsWith("/")) - path += "/"; - uploadurlbuilder += "&Path=" + path; uploadurlbuilder += "&OS=" + (dropZone.getLinux().equalsIgnoreCase("true") ? "2" : "1"); uploadurlbuilder += "&rawxml_=1"; WritableByteChannel outchannel = null; diff --git a/wsclient/src/main/java/org/hpccsystems/ws/client/utils/Utils.java b/wsclient/src/main/java/org/hpccsystems/ws/client/utils/Utils.java index f33d83cf1..df7a56162 100644 --- a/wsclient/src/main/java/org/hpccsystems/ws/client/utils/Utils.java +++ b/wsclient/src/main/java/org/hpccsystems/ws/client/utils/Utils.java @@ -1061,21 +1061,64 @@ public static DocumentBuilder newSafeXMLDocBuilder() throws ParserConfigurationE return safeXMLDocBuilder; } + /** + * Ensures the given path contains a trailing path delimiter. + * Does not introduce duplicate trailing path delimiter if one already exists. + * Defaults to Linux style separator if the given path either contains a Linux style separator, or the path is empty. + * Strips all trailing white space character + * @param path The path to be postfixed + * @return original path with proper trailing path delimiter + */ public static String ensureTrailingPathSlash(String path) { return ensureTrailingPathSlash(path, (path.contains(Character.toString(LINUX_SEP)) || path.length() == 0) ? LINUX_SEP : WIN_SEP); } + /** + * Ensures the given path contains a trailing path delimiter. + * Does not introduce duplicate trailing path delimiter if one already exists. + * Uses Linux style path separator 'useLinuxSep' == "true", otherwise uses windows style path separator + * Strips all trailing white space character + * @param path path The path to be postfixed + * @param useLinuxSep String, if "true" linux styled path delimiter will be used + * @return original path with proper trailing path delimiter + */ public static String ensureTrailingPathSlash(String path, String useLinuxSep) { return ensureTrailingPathSlash(path, useLinuxSep.equalsIgnoreCase("true") ? LINUX_SEP : WIN_SEP); } + /** + * Ensures the given path contains a trailing path delimiter. + * Does not introduce duplicate trailing path delimiter if one already exists. + * Uses provided 'slash' as trailing path delimiter + * Strips all trailing white space character + * @param path The path to be postfixed + * @param slash The character to append + * @return original path with proper trailing path delimiter + */ public static String ensureTrailingPathSlash(String path, char slash) { + path = trimTrailing(path); + if (path.length() == 0 || path.charAt(path.length()-1) != slash) path = path + slash; return path; } + + /** + * Removes trailing whitespace characters from a string. + * + * @param originalStr the original string from which trailing whitespace should be removed + * @return a new string with the same characters as the original string, minus any trailing whitespace + */ + public static String trimTrailing(String originalStr) + { + int strIndex = originalStr.length()-1; + while(strIndex >= 0 && Character.isWhitespace(originalStr.charAt(strIndex))) + strIndex--; + + return originalStr.substring(0,strIndex+1); + } } diff --git a/wsclient/src/test/java/org/hpccsystems/ws/client/utils/UtilsTest.java b/wsclient/src/test/java/org/hpccsystems/ws/client/utils/UtilsTest.java index 1ff309ebf..eef268e47 100644 --- a/wsclient/src/test/java/org/hpccsystems/ws/client/utils/UtilsTest.java +++ b/wsclient/src/test/java/org/hpccsystems/ws/client/utils/UtilsTest.java @@ -8,59 +8,75 @@ public class UtilsTest { + @Test + public void testEnsureTrailingSlashTrailingWhiteSpace() + { + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash("")); + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP)+ " ")); + assertEquals(Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP) + " ")); + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)+"\t")); + assertEquals("C:\\some\\Path\\", Utils.ensureTrailingPathSlash("C:\\some\\Path ")); + assertEquals("C:\\some\\Path\\", Utils.ensureTrailingPathSlash("C:\\some\\Path\\ ")); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path ")); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path/\t\t")); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path/\n")); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path/" + '\u005Cn')); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path/ " + '\u005Ct')); + } + @Test public void testEnsureTrailingSlashNoSlashSpecified() { - assertEquals(Utils.ensureTrailingPathSlash(""), Character.toString(Utils.LINUX_SEP)); //no sep in path, default to lin sep - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP)), Character.toString(Utils.LINUX_SEP));//no change expected - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)), Character.toString(Utils.WIN_SEP)); //no change expected - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)), Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP));//no change expected - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path"), "C:\\some\\Path\\"); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path\\"), "C:\\some\\Path\\"); - assertEquals(Utils.ensureTrailingPathSlash("/another/path"), "/another/path/"); - assertEquals(Utils.ensureTrailingPathSlash("/another/path/"), "/another/path/"); + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash("")); //no sep in path, default to lin sep + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP)));//no change expected + assertEquals(Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP))); //no change expected + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)));//no change expected + assertEquals("C:\\some\\Path\\", Utils.ensureTrailingPathSlash("C:\\some\\Path")); + assertEquals("C:\\some\\Path\\", Utils.ensureTrailingPathSlash("C:\\some\\Path\\")); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path")); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path/")); } @Test public void testEnsureTrailingSlashSlashSpecified() { - assertEquals(Utils.ensureTrailingPathSlash("", Utils.LINUX_SEP), Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash("", Utils.WIN_SEP), Character.toString(Utils.WIN_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), Utils.WIN_SEP), Character.toString(Utils.LINUX_SEP)+Utils.WIN_SEP); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), Utils.LINUX_SEP), Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), Utils.WIN_SEP), Character.toString(Utils.WIN_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), Utils.LINUX_SEP), Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.LINUX_SEP), Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.WIN_SEP), Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)+Character.toString(Utils.WIN_SEP)); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path", Utils.LINUX_SEP), "C:\\some\\Path\\"+Utils.LINUX_SEP); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path", Utils.WIN_SEP), "C:\\some\\Path\\"+Utils.WIN_SEP); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path\\", Utils.LINUX_SEP), "C:\\some\\Path\\" + Utils.LINUX_SEP); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path\\", Utils.WIN_SEP), "C:\\some\\Path\\"); - assertEquals(Utils.ensureTrailingPathSlash("/another/path", Utils.LINUX_SEP), "/another/path" + Utils.LINUX_SEP); - assertEquals(Utils.ensureTrailingPathSlash("/another/path", Utils.WIN_SEP), "/another/path/"+ Utils.WIN_SEP); - assertEquals(Utils.ensureTrailingPathSlash("/another/path/", Utils.LINUX_SEP), "/another/path/"); - assertEquals(Utils.ensureTrailingPathSlash("/another/path/", Utils.WIN_SEP), "/another/path/"+Utils.WIN_SEP); + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash("", Utils.LINUX_SEP)); + assertEquals(Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash("", Utils.WIN_SEP)); + assertEquals(Character.toString(Utils.LINUX_SEP)+Utils.WIN_SEP, Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), Utils.WIN_SEP)); + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), Utils.LINUX_SEP)); + assertEquals(Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), Utils.WIN_SEP)); + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), Utils.LINUX_SEP)); + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.LINUX_SEP)); + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)+Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.WIN_SEP)); + assertEquals("C:\\some\\Path\\"+Utils.LINUX_SEP, Utils.ensureTrailingPathSlash("C:\\some\\Path", Utils.LINUX_SEP)); + assertEquals("C:\\some\\Path\\"+Utils.WIN_SEP, Utils.ensureTrailingPathSlash("C:\\some\\Path", Utils.WIN_SEP)); + assertEquals("C:\\some\\Path\\" + Utils.LINUX_SEP, Utils.ensureTrailingPathSlash("C:\\some\\Path\\", Utils.LINUX_SEP)); + assertEquals("C:\\some\\Path\\", Utils.ensureTrailingPathSlash("C:\\some\\Path\\", Utils.WIN_SEP)); + assertEquals("/another/path" + Utils.LINUX_SEP, Utils.ensureTrailingPathSlash("/another/path", Utils.LINUX_SEP)); + assertEquals("/another/path/"+ Utils.WIN_SEP, Utils.ensureTrailingPathSlash("/another/path", Utils.WIN_SEP)); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path/", Utils.LINUX_SEP)); + assertEquals("/another/path/"+Utils.WIN_SEP, Utils.ensureTrailingPathSlash("/another/path/", Utils.WIN_SEP)); } @Test public void testEnsureTrailingSlashUseLinuxBoolTest() { - assertEquals(Utils.ensureTrailingPathSlash("", "true"), Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash("", "false"), Character.toString(Utils.WIN_SEP)); - assertEquals(Utils.ensureTrailingPathSlash("", "xyz"), Character.toString(Utils.WIN_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), "false"), Character.toString(Utils.LINUX_SEP)+Utils.WIN_SEP); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), "true"), Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), "false"), Character.toString(Utils.WIN_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), "true"), Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), "true"), Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)); - assertEquals(Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), "false"), Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)+Character.toString(Utils.WIN_SEP)); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path", "true"), "C:\\some\\Path\\"+Utils.LINUX_SEP); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path", "false"), "C:\\some\\Path\\"+Utils.WIN_SEP); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path\\", "true"), "C:\\some\\Path\\" + Utils.LINUX_SEP); - assertEquals(Utils.ensureTrailingPathSlash("C:\\some\\Path\\", "false"), "C:\\some\\Path\\"); - assertEquals(Utils.ensureTrailingPathSlash("/another/path", "TRUE"), "/another/path" + Utils.LINUX_SEP); - assertEquals(Utils.ensureTrailingPathSlash("/another/path", "FALSE"), "/another/path/"+ Utils.WIN_SEP); - assertEquals(Utils.ensureTrailingPathSlash("/another/path/", "TrUe"), "/another/path/"); - assertEquals(Utils.ensureTrailingPathSlash("/another/path/", "FalSe"), "/another/path/"+Utils.WIN_SEP); + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash("", "true")); + assertEquals(Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash("", "false")); + assertEquals(Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash("", "xyz")); + assertEquals(Character.toString(Utils.LINUX_SEP)+Utils.WIN_SEP, Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), "false")); + assertEquals(Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.LINUX_SEP), "true")); + assertEquals(Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), "false")); + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP), "true")); + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), "true")); + assertEquals(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP)+Character.toString(Utils.WIN_SEP), Utils.ensureTrailingPathSlash(Character.toString(Utils.WIN_SEP)+Character.toString(Utils.LINUX_SEP), "false")); + assertEquals("C:\\some\\Path\\"+Utils.LINUX_SEP, Utils.ensureTrailingPathSlash("C:\\some\\Path", "true")); + assertEquals("C:\\some\\Path\\"+Utils.WIN_SEP, Utils.ensureTrailingPathSlash("C:\\some\\Path", "false")); + assertEquals("C:\\some\\Path\\" + Utils.LINUX_SEP, Utils.ensureTrailingPathSlash("C:\\some\\Path\\", "true")); + assertEquals("C:\\some\\Path\\", Utils.ensureTrailingPathSlash("C:\\some\\Path\\", "false")); + assertEquals("/another/path" + Utils.LINUX_SEP, Utils.ensureTrailingPathSlash("/another/path", "TRUE")); + assertEquals("/another/path/"+ Utils.WIN_SEP, Utils.ensureTrailingPathSlash("/another/path", "FALSE")); + assertEquals("/another/path/", Utils.ensureTrailingPathSlash("/another/path/", "TrUe")); + assertEquals("/another/path/"+Utils.WIN_SEP, Utils.ensureTrailingPathSlash("/another/path/", "FalSe")); } }