mattcasters commented on code in PR #8552:
URL: https://github.com/apache/hop/pull/8552#discussion_r4083710237


##########
plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/wsdl/Wsdl.java:
##########
@@ -315,65 +346,87 @@ private WSDLReader getReader() throws WSDLException {
    * Load and parse the WSDL file using the wsdlLocator.
    *
    * @param wsdlLocator A WSDLLocator instance.
-   * @param username to use for authentication
-   * @param password to use for authentication
    * @return wsdl Definition.
    * @throws WSDLException on error.
    */
-  private Definition parse(WSDLLocator wsdlLocator, String username, String 
password)
-      throws WSDLException, HopException {
-
-    WSDLReader wsdlReader = getReader();
-    try {
-
-      return wsdlReader.readWSDL(wsdlLocator);
-    } catch (WSDLException we) {
-      readWsdl(wsdlReader, wsdlURI.toString(), username, password);
-      return null;
-    }
+  private Definition parse(WSDLLocator wsdlLocator) throws WSDLException {
+    return getReader().readWSDL(wsdlLocator);
   }
 
   /**
-   * Load and parse the WSDL file at the specified URI.
+   * Load and parse the WSDL file at the specified location.
    *
-   * @param wsdlURI URI of the WSDL file.
-   * @param username to use for authentication
-   * @param password to use for authentication
+   * @param wsdlLocation http(s) URL or Hop VFS file name of the WSDL file.
+   * @param variables to find the named VFS connections with, can be null
+   * @param username to use for HTTP authentication
+   * @param password to use for HTTP authentication
    * @return wsdl Definition
    * @throws WSDLException on error.
    */
-  private Definition parse(URI wsdlURI, String username, String password)
+  private Definition parse(
+      String wsdlLocation, IVariables variables, String username, String 
password)
       throws WSDLException, HopException {
+    if (StringUtils.isBlank(wsdlLocation)) {
+      throw new HopException("No WSDL location was specified");
+    }
+    String location = wsdlLocation.trim();
     WSDLReader wsdlReader = getReader();
-    return readWsdl(wsdlReader, wsdlURI.toString(), username, password);
+    if (isHttpLocation(location)) {
+      return readWsdl(wsdlReader, location, openHttpStream(location, username, 
password));
+    }
+
+    // Anything that isn't served over HTTP is a file: a plain path like the 
file dialog hands out,
+    // a file: URL or any other location Hop VFS knows about.
+    //
+    FileObject wsdlFile =
+        variables == null
+            ? HopVfs.getFileObject(location)
+            : HopVfs.getFileObject(location, variables);
+    try {
+      if (!wsdlFile.exists()) {
+        throw new HopException("WSDL file " + wsdlLocation + " does not 
exist");
+      }
+      // Imports in the WSDL are resolved relative to this URI.
+      //
+      String baseUri = wsdlFile.getName().getURI();
+      return readWsdl(wsdlReader, baseUri, HopVfs.getInputStream(wsdlFile));

Review Comment:
   **[bug]** Relative `<import>` and `schemaLocation` references are not read 
through Hop VFS. `readWSDL(baseUri, doc)` has no `WSDLLocator`, so WSDL4J opens 
them with `java.net.URL` (`StringUtils.getURL` / `openStream`). A `file:` URI 
works, which is what `WsdlTest.resolvesImportsRelativeToTheFile` covers, but 
`FileName.getURI()` for `s3://`, Azure, HDFS, and similar schemes is not a 
protocol Java can open. On `MalformedURLException`, WSDL4J falls back to `new 
File(spec).toURL()`, so a WSDL that Hop VFS already read fails as soon as it 
has a relative import or schema include. The new manual text says those imports 
are looked up next to the file on any filesystem Hop can read; a self-contained 
WSDL still loads.
   
   **Suggestion:** Resolve the main document and each relative location with a 
`WSDLLocator` that uses `HopVfs.getFileObject` against the WSDL parent (and 
close those streams). The same locator can attach the basic-auth header for 
`http(s)` imports. If that is out of scope, narrow the tooltip and the "WSDL 
files and imports" section to local and `file:` URLs.



##########
plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/wsdl/Wsdl.java:
##########
@@ -315,65 +346,87 @@ private WSDLReader getReader() throws WSDLException {
    * Load and parse the WSDL file using the wsdlLocator.
    *
    * @param wsdlLocator A WSDLLocator instance.
-   * @param username to use for authentication
-   * @param password to use for authentication
    * @return wsdl Definition.
    * @throws WSDLException on error.
    */
-  private Definition parse(WSDLLocator wsdlLocator, String username, String 
password)
-      throws WSDLException, HopException {
-
-    WSDLReader wsdlReader = getReader();
-    try {
-
-      return wsdlReader.readWSDL(wsdlLocator);
-    } catch (WSDLException we) {
-      readWsdl(wsdlReader, wsdlURI.toString(), username, password);
-      return null;
-    }
+  private Definition parse(WSDLLocator wsdlLocator) throws WSDLException {
+    return getReader().readWSDL(wsdlLocator);
   }
 
   /**
-   * Load and parse the WSDL file at the specified URI.
+   * Load and parse the WSDL file at the specified location.
    *
-   * @param wsdlURI URI of the WSDL file.
-   * @param username to use for authentication
-   * @param password to use for authentication
+   * @param wsdlLocation http(s) URL or Hop VFS file name of the WSDL file.
+   * @param variables to find the named VFS connections with, can be null
+   * @param username to use for HTTP authentication
+   * @param password to use for HTTP authentication
    * @return wsdl Definition
    * @throws WSDLException on error.
    */
-  private Definition parse(URI wsdlURI, String username, String password)
+  private Definition parse(
+      String wsdlLocation, IVariables variables, String username, String 
password)
       throws WSDLException, HopException {
+    if (StringUtils.isBlank(wsdlLocation)) {
+      throw new HopException("No WSDL location was specified");
+    }
+    String location = wsdlLocation.trim();
     WSDLReader wsdlReader = getReader();
-    return readWsdl(wsdlReader, wsdlURI.toString(), username, password);
+    if (isHttpLocation(location)) {
+      return readWsdl(wsdlReader, location, openHttpStream(location, username, 
password));
+    }
+
+    // Anything that isn't served over HTTP is a file: a plain path like the 
file dialog hands out,
+    // a file: URL or any other location Hop VFS knows about.
+    //
+    FileObject wsdlFile =

Review Comment:
   **[suggestion]** `wsdlFile` is never closed. `HopVfs.getInputStream` only 
yields a content stream, which `readWsdl` / `XmlHandler.loadXmlFile` close; the 
`FileObject` stays referenced by the shared VFS cache, and a remote provider 
can keep a connection open. The "does not exist" throw leaves the same leak.
   
   **Suggestion:** Open the file in try-with-resources so it is closed after 
`readWsdl` returns, including on failure. Keep wrapping `FileSystemException` 
in `HopException` (it does not extend `HopException`) so the constructor still 
reports the location.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to