This is an automated email from the ASF dual-hosted git repository.

mcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new abfd2e0bd2 Issues #1947 (WebService Lookup XML cleanup) (#6894)
abfd2e0bd2 is described below

commit abfd2e0bd26d4232ee008d93fe8350db72b42c79
Author: Matt Casters <[email protected]>
AuthorDate: Fri Mar 27 13:19:50 2026 +0100

    Issues #1947 (WebService Lookup XML cleanup) (#6894)
---
 .../transforms/webservices/WebServiceField.java    |  51 +--
 .../transforms/webservices/WebServiceMeta.java     | 382 +++------------------
 .../transforms/webservices/WebServiceMetaTest.java | 283 +++------------
 .../src/test/resources/webservice-lookup.xml       |  67 ++++
 4 files changed, 189 insertions(+), 594 deletions(-)

diff --git 
a/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceField.java
 
b/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceField.java
index c387d4e965..8c4642f271 100644
--- 
a/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceField.java
+++ 
b/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceField.java
@@ -17,56 +17,43 @@
 
 package org.apache.hop.pipeline.transforms.webservices;
 
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.hop.core.row.IValueMeta;
+import org.apache.hop.metadata.api.HopMetadataProperty;
 import org.apache.hop.pipeline.transforms.webservices.wsdl.XsdType;
 
+@Getter
+@Setter
 public class WebServiceField implements Cloneable {
+  @HopMetadataProperty(key = "name")
   private String name;
 
+  @HopMetadataProperty(key = "wsName")
   private String wsName;
 
+  @HopMetadataProperty(key = "xsdType")
   private String xsdType;
 
+  public WebServiceField() {}
+
+  public WebServiceField(WebServiceField f) {
+    this();
+    this.name = f.name;
+    this.wsName = f.wsName;
+    this.xsdType = f.xsdType;
+  }
+
   @Override
   public WebServiceField clone() {
-    try {
-      return (WebServiceField) super.clone();
-    } catch (CloneNotSupportedException e) {
-      e.printStackTrace();
-      return null;
-    }
+    return new WebServiceField(this);
   }
 
   @Override
   public String toString() {
-
     return name != null ? name : super.toString();
   }
 
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public String getWsName() {
-    return wsName;
-  }
-
-  public void setWsName(String wsName) {
-    this.wsName = wsName;
-  }
-
-  public String getXsdType() {
-    return xsdType;
-  }
-
-  public void setXsdType(String xsdType) {
-    this.xsdType = xsdType;
-  }
-
   public int getType() {
     return XsdType.xsdTypeToHopType(xsdType);
   }
@@ -75,7 +62,7 @@ public class WebServiceField implements Cloneable {
    * We consider a field to be complex if it's a type we don't recognize. In 
that case, we will give
    * back XML as a string.
    *
-   * @return
+   * @return true if the field is complex
    */
   public boolean isComplex() {
     return getType() == IValueMeta.TYPE_NONE;
diff --git 
a/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java
 
b/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java
index 9f0b64696e..ac8cce35ea 100644
--- 
a/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java
+++ 
b/plugins/transforms/webservices/src/main/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMeta.java
@@ -19,23 +19,22 @@ package org.apache.hop.pipeline.transforms.webservices;
 
 import java.util.ArrayList;
 import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.hop.core.CheckResult;
-import org.apache.hop.core.Const;
 import org.apache.hop.core.ICheckResult;
 import org.apache.hop.core.annotations.Transform;
 import org.apache.hop.core.exception.HopTransformException;
-import org.apache.hop.core.exception.HopXmlException;
 import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.core.row.IValueMeta;
 import org.apache.hop.core.row.value.ValueMetaFactory;
 import org.apache.hop.core.util.Utils;
 import org.apache.hop.core.variables.IVariables;
-import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.metadata.api.HopMetadataProperty;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.transform.BaseTransformMeta;
 import org.apache.hop.pipeline.transform.TransformMeta;
-import org.w3c.dom.Node;
 
 @Transform(
     id = "WebServiceLookup",
@@ -45,6 +44,8 @@ import org.w3c.dom.Node;
     categoryDescription = 
"i18n:org.apache.hop.pipeline.transform:BaseTransform.Category.Lookup",
     keywords = "i18n::WebServiceMeta.keyword",
     documentationUrl = "/pipeline/transforms/webservices.html")
+@Getter
+@Setter
 public class WebServiceMeta extends BaseTransformMeta<WebService, 
WebServiceData> {
   public static final String XSD_NS_URI = "http://www.w3.org/2001/XMLSchema";;
 
@@ -55,70 +56,112 @@ public class WebServiceMeta extends 
BaseTransformMeta<WebService, WebServiceData
   public static final String CONST_FIELD = "field";
 
   /** The input web service fields */
+  @HopMetadataProperty(key = "field", groupKey = "fieldsIn")
   private List<WebServiceField> fieldsIn;
 
   /** The output web service fields */
+  @HopMetadataProperty(key = "field", groupKey = "fieldsOut")
   private List<WebServiceField> fieldsOut;
 
   /** Web service URL */
+  @HopMetadataProperty(key = "wsURL")
   private String url;
 
   /** Name of the web service operation to use */
+  @HopMetadataProperty(key = "wsOperation")
   private String operationName;
 
   /** Name of the operation request name: optional, can be different from the 
operation name */
+  @HopMetadataProperty(key = "wsOperationRequest")
   private String operationRequestName;
 
   /** The name-variables of the operation */
+  @HopMetadataProperty(key = "wsOperationNamespace")
   private String operationNamespace;
 
   /**
    * The name of the object that encapsulates the input fields in case we're 
dealing with a table
    */
+  @HopMetadataProperty(key = "wsInFieldContainer")
   private String inFieldContainerName;
 
   /** Name of the input object */
+  @HopMetadataProperty(key = "wsInFieldArgument")
   private String inFieldArgumentName;
 
   /** Name of the object that encapsulates the output fields in case we're 
dealing with a table */
+  @HopMetadataProperty(key = "wsOutFieldContainer")
   private String outFieldContainerName;
 
   /** Name of the output object */
+  @HopMetadataProperty(key = "wsOutFieldArgument")
   private String outFieldArgumentName;
 
+  @HopMetadataProperty(key = "proxyHost")
   private String proxyHost;
 
+  @HopMetadataProperty(key = "proxyPort")
   private String proxyPort;
 
+  @HopMetadataProperty(key = "httpLogin")
   private String httpLogin;
 
+  @HopMetadataProperty(key = "httpPassword", password = true)
   private String httpPassword;
 
   /** Flag to allow input data to pass to the output */
+  @HopMetadataProperty(key = "passingInputData")
   private boolean passingInputData;
 
   /** The number of rows to send with each call */
-  private int callTransform = DEFAULT_TRANSFORM;
+  @HopMetadataProperty(key = "callTransform")
+  private int callTransform;
 
   /** Use the 2.5/3.0 parsing logic (available for compatibility reasons) */
+  @HopMetadataProperty(key = "compatible")
   private boolean compatible;
 
   /** The name of the repeating element name. Empty = a single row return */
+  @HopMetadataProperty(key = "repeating_element")
   private String repeatingElementName;
 
   /** Is this transform giving back the complete reply from the service as an 
XML string? */
+  @HopMetadataProperty(key = "reply_as_string")
   private boolean returningReplyAsString;
 
   public WebServiceMeta() {
     super();
+    callTransform = DEFAULT_TRANSFORM;
     fieldsIn = new ArrayList<>();
     fieldsOut = new ArrayList<>();
   }
 
-  public WebServiceMeta(Node transformNode, IHopMetadataProvider 
metadataProvider)
-      throws HopXmlException {
+  public WebServiceMeta(WebServiceMeta m) {
     this();
-    loadXml(transformNode, metadataProvider);
+    this.callTransform = m.callTransform;
+    this.compatible = m.compatible;
+    this.httpLogin = m.httpLogin;
+    this.httpPassword = m.httpPassword;
+    this.inFieldArgumentName = m.inFieldArgumentName;
+    this.inFieldContainerName = m.inFieldContainerName;
+    this.operationName = m.operationName;
+    this.operationNamespace = m.operationNamespace;
+    this.operationRequestName = m.operationRequestName;
+    this.outFieldArgumentName = m.outFieldArgumentName;
+    this.outFieldContainerName = m.outFieldContainerName;
+    this.passingInputData = m.passingInputData;
+    this.proxyHost = m.proxyHost;
+    this.proxyPort = m.proxyPort;
+    this.repeatingElementName = m.repeatingElementName;
+    this.returningReplyAsString = m.returningReplyAsString;
+    this.url = m.url;
+    m.fieldsIn.forEach(field -> fieldsIn.add(new WebServiceField(field)));
+    m.fieldsOut.forEach(field -> fieldsOut.add(new WebServiceField(field)));
+  }
+
+  @Override
+  public WebServiceMeta clone() {
+    return new WebServiceMeta(this);
   }
 
   @Override
@@ -157,20 +200,6 @@ public class WebServiceMeta extends 
BaseTransformMeta<WebService, WebServiceData
     }
   }
 
-  @Override
-  public WebServiceMeta clone() {
-    WebServiceMeta retval = (WebServiceMeta) super.clone();
-    retval.fieldsIn = new ArrayList<>();
-    for (WebServiceField field : fieldsIn) {
-      retval.fieldsIn.add(field.clone());
-    }
-    retval.fieldsOut = new ArrayList<>();
-    for (WebServiceField field : fieldsOut) {
-      retval.fieldsOut.add(field.clone());
-    }
-    return retval;
-  }
-
   @Override
   public void setDefault() {
     passingInputData = true; // Pass input data by default.
@@ -222,138 +251,6 @@ public class WebServiceMeta extends 
BaseTransformMeta<WebService, WebServiceData
     }
   }
 
-  @Override
-  public String getXml() {
-    StringBuilder retval = new StringBuilder();
-
-    // Store the WebService URL
-    //
-    retval.append("    " + XmlHandler.addTagValue("wsURL", getUrl()));
-
-    // Store the operation
-    //
-    retval.append("    " + XmlHandler.addTagValue("wsOperation", 
getOperationName()));
-    retval.append("    " + XmlHandler.addTagValue("wsOperationRequest", 
getOperationRequestName()));
-    retval.append("    " + XmlHandler.addTagValue("wsOperationNamespace", 
getOperationNamespace()));
-    retval.append("    " + XmlHandler.addTagValue("wsInFieldContainer", 
getInFieldContainerName()));
-    retval.append("    " + XmlHandler.addTagValue("wsInFieldArgument", 
getInFieldArgumentName()));
-    retval.append(
-        "    " + XmlHandler.addTagValue("wsOutFieldContainer", 
getOutFieldContainerName()));
-    retval.append("    " + XmlHandler.addTagValue("wsOutFieldArgument", 
getOutFieldArgumentName()));
-    retval.append("    " + XmlHandler.addTagValue("proxyHost", 
getProxyHost()));
-    retval.append("    " + XmlHandler.addTagValue("proxyPort", 
getProxyPort()));
-    retval.append("    " + XmlHandler.addTagValue("httpLogin", 
getHttpLogin()));
-    retval.append("    " + XmlHandler.addTagValue("httpPassword", 
getHttpPassword()));
-    retval.append("    " + XmlHandler.addTagValue("callTransform", 
getCallTransform()));
-    retval.append("    " + XmlHandler.addTagValue("passingInputData", 
isPassingInputData()));
-    retval.append("    " + XmlHandler.addTagValue("compatible", 
isCompatible()));
-    retval.append("    " + XmlHandler.addTagValue("repeating_element", 
getRepeatingElementName()));
-    retval.append("    " + XmlHandler.addTagValue("reply_as_string", 
isReturningReplyAsString()));
-
-    // Store the field parameters
-    //
-
-    // Store the link between the input fields and the WebService input
-    //
-    retval.append("    <fieldsIn>" + Const.CR);
-    for (int i = 0; i < getFieldsIn().size(); i++) {
-      WebServiceField vField = getFieldsIn().get(i);
-      retval.append("    <field>" + Const.CR);
-      retval.append(CONST_SPACES + XmlHandler.addTagValue("name", 
vField.getName()));
-      retval.append(CONST_SPACES + XmlHandler.addTagValue(CONST_WS_NAME, 
vField.getWsName()));
-      retval.append(CONST_SPACES + XmlHandler.addTagValue(CONST_XSD_TYPE, 
vField.getXsdType()));
-      retval.append("    </field>" + Const.CR);
-    }
-    retval.append("      </fieldsIn>" + Const.CR);
-
-    // Store the link between the input fields and the WebService output
-    //
-    retval.append("    <fieldsOut>" + Const.CR);
-    for (int i = 0; i < getFieldsOut().size(); i++) {
-      WebServiceField vField = getFieldsOut().get(i);
-      retval.append("    <field>" + Const.CR);
-      retval.append(CONST_SPACES + XmlHandler.addTagValue("name", 
vField.getName()));
-      retval.append(CONST_SPACES + XmlHandler.addTagValue(CONST_WS_NAME, 
vField.getWsName()));
-      retval.append(CONST_SPACES + XmlHandler.addTagValue(CONST_XSD_TYPE, 
vField.getXsdType()));
-      retval.append("    </field>" + Const.CR);
-    }
-    retval.append("      </fieldsOut>" + Const.CR);
-
-    return retval.toString();
-  }
-
-  @Override
-  public void loadXml(Node transformNode, IHopMetadataProvider 
metadataProvider)
-      throws HopXmlException {
-    // Load the URL
-    //
-    setUrl(XmlHandler.getTagValue(transformNode, "wsURL"));
-
-    // Load the operation
-    //
-    setOperationName(XmlHandler.getTagValue(transformNode, "wsOperation"));
-    setOperationRequestName(XmlHandler.getTagValue(transformNode, 
"wsOperationRequest"));
-    setOperationNamespace(XmlHandler.getTagValue(transformNode, 
"wsOperationNamespace"));
-    setInFieldContainerName(XmlHandler.getTagValue(transformNode, 
"wsInFieldContainer"));
-    setInFieldArgumentName(XmlHandler.getTagValue(transformNode, 
"wsInFieldArgument"));
-    setOutFieldContainerName(XmlHandler.getTagValue(transformNode, 
"wsOutFieldContainer"));
-    setOutFieldArgumentName(XmlHandler.getTagValue(transformNode, 
"wsOutFieldArgument"));
-    setProxyHost(XmlHandler.getTagValue(transformNode, "proxyHost"));
-    setProxyPort(XmlHandler.getTagValue(transformNode, "proxyPort"));
-    setHttpLogin(XmlHandler.getTagValue(transformNode, "httpLogin"));
-    setHttpPassword(XmlHandler.getTagValue(transformNode, "httpPassword"));
-    setCallTransform(
-        Const.toInt(XmlHandler.getTagValue(transformNode, "callTransform"), 
DEFAULT_TRANSFORM));
-    setPassingInputData(
-        "Y".equalsIgnoreCase(XmlHandler.getTagValue(transformNode, 
"passingInputData")));
-    String compat = XmlHandler.getTagValue(transformNode, "compatible");
-    setCompatible(Utils.isEmpty(compat) || "Y".equalsIgnoreCase(compat));
-    setRepeatingElementName(XmlHandler.getTagValue(transformNode, 
"repeating_element"));
-    setReturningReplyAsString(
-        "Y".equalsIgnoreCase(XmlHandler.getTagValue(transformNode, 
"reply_as_string")));
-
-    // Load the input fields mapping
-    //
-    getFieldsIn().clear();
-    Node fields = XmlHandler.getSubNode(transformNode, "fieldsIn");
-    int nrFields = XmlHandler.countNodes(fields, CONST_FIELD);
-
-    for (int i = 0; i < nrFields; ++i) {
-      Node fnode = XmlHandler.getSubNodeByNr(fields, CONST_FIELD, i);
-
-      WebServiceField field = new WebServiceField();
-      field.setName(XmlHandler.getTagValue(fnode, "name"));
-      field.setWsName(XmlHandler.getTagValue(fnode, CONST_WS_NAME));
-      field.setXsdType(XmlHandler.getTagValue(fnode, CONST_XSD_TYPE));
-      getFieldsIn().add(field);
-    }
-
-    // Load the output fields mapping
-    //
-    getFieldsOut().clear();
-
-    fields = XmlHandler.getSubNode(transformNode, "fieldsOut");
-    nrFields = XmlHandler.countNodes(fields, CONST_FIELD);
-
-    for (int i = 0; i < nrFields; ++i) {
-      Node fnode = XmlHandler.getSubNodeByNr(fields, CONST_FIELD, i);
-
-      WebServiceField field = new WebServiceField();
-      field.setName(XmlHandler.getTagValue(fnode, "name"));
-      field.setWsName(XmlHandler.getTagValue(fnode, CONST_WS_NAME));
-      field.setXsdType(XmlHandler.getTagValue(fnode, CONST_XSD_TYPE));
-      getFieldsOut().add(field);
-    }
-  }
-
-  public String getOperationName() {
-    return operationName;
-  }
-
-  public void setOperationName(String operationName) {
-    this.operationName = operationName;
-  }
-
   public WebServiceField getFieldInFromName(String name) {
     WebServiceField param = null;
     for (WebServiceField paramCour : getFieldsIn()) {
@@ -371,7 +268,7 @@ public class WebServiceMeta extends 
BaseTransformMeta<WebService, WebServiceData
    * @param wsName The name of the WebServiceField to return
    * @param ignoreWsNsPrefix If true the lookup of the cache of 
WebServiceFields will not include
    *     the target namespace prefix.
-   * @return
+   * @return The field for the given web service
    */
   public WebServiceField getFieldOutFromWsName(String wsName, boolean 
ignoreWsNsPrefix) {
     WebServiceField param = null;
@@ -398,14 +295,6 @@ public class WebServiceMeta extends 
BaseTransformMeta<WebService, WebServiceData
     return param;
   }
 
-  public List<WebServiceField> getFieldsIn() {
-    return fieldsIn;
-  }
-
-  public void setFieldsIn(List<WebServiceField> fieldsIn) {
-    this.fieldsIn = fieldsIn;
-  }
-
   public boolean hasFieldsIn() {
     return !Utils.isEmpty(fieldsIn);
   }
@@ -414,174 +303,7 @@ public class WebServiceMeta extends 
BaseTransformMeta<WebService, WebServiceData
     fieldsIn.add(field);
   }
 
-  public List<WebServiceField> getFieldsOut() {
-    return fieldsOut;
-  }
-
-  public void setFieldsOut(List<WebServiceField> fieldsOut) {
-    this.fieldsOut = fieldsOut;
-  }
-
   public void addFieldOut(WebServiceField field) {
     fieldsOut.add(field);
   }
-
-  public String getInFieldArgumentName() {
-    return inFieldArgumentName;
-  }
-
-  public void setInFieldArgumentName(String inFieldArgumentName) {
-    this.inFieldArgumentName = inFieldArgumentName;
-  }
-
-  public String getOutFieldArgumentName() {
-    return outFieldArgumentName;
-  }
-
-  public void setOutFieldArgumentName(String outFieldArgumentName) {
-    this.outFieldArgumentName = outFieldArgumentName;
-  }
-
-  public String getUrl() {
-    return url;
-  }
-
-  public void setUrl(String url) {
-    this.url = url;
-  }
-
-  public int getCallTransform() {
-    return callTransform;
-  }
-
-  public void setCallTransform(int callTransform) {
-    this.callTransform = callTransform;
-  }
-
-  public String getOperationNamespace() {
-    return operationNamespace;
-  }
-
-  public void setOperationNamespace(String operationNamespace) {
-    this.operationNamespace = operationNamespace;
-  }
-
-  public String getHttpLogin() {
-    return httpLogin;
-  }
-
-  public void setHttpLogin(String httpLogin) {
-    this.httpLogin = httpLogin;
-  }
-
-  public String getHttpPassword() {
-    return httpPassword;
-  }
-
-  public void setHttpPassword(String httpPassword) {
-    this.httpPassword = httpPassword;
-  }
-
-  public String getProxyHost() {
-    return proxyHost;
-  }
-
-  public void setProxyHost(String proxyHost) {
-    this.proxyHost = proxyHost;
-  }
-
-  public String getProxyPort() {
-    return proxyPort;
-  }
-
-  public void setProxyPort(String proxyPort) {
-    this.proxyPort = proxyPort;
-  }
-
-  public String getInFieldContainerName() {
-    return inFieldContainerName;
-  }
-
-  public void setInFieldContainerName(String inFieldContainerName) {
-    this.inFieldContainerName = inFieldContainerName;
-  }
-
-  public String getOutFieldContainerName() {
-    return outFieldContainerName;
-  }
-
-  public void setOutFieldContainerName(String outFieldContainerName) {
-    this.outFieldContainerName = outFieldContainerName;
-  }
-
-  /**
-   * @return the passingInputData
-   */
-  public boolean isPassingInputData() {
-    return passingInputData;
-  }
-
-  /**
-   * @param passingInputData the passingInputData to set
-   */
-  public void setPassingInputData(boolean passingInputData) {
-    this.passingInputData = passingInputData;
-  }
-
-  /**
-   * @return the compatible
-   */
-  public boolean isCompatible() {
-    return compatible;
-  }
-
-  /**
-   * @param compatible the compatible to set
-   */
-  public void setCompatible(boolean compatible) {
-    this.compatible = compatible;
-  }
-
-  /**
-   * @return the repeatingElementName
-   */
-  public String getRepeatingElementName() {
-    return repeatingElementName;
-  }
-
-  /**
-   * @param repeatingElementName the repeatingElementName to set
-   */
-  public void setRepeatingElementName(String repeatingElementName) {
-    this.repeatingElementName = repeatingElementName;
-  }
-
-  /**
-   * @return true if the reply from the service is simply passed on as a 
String, mostly in XML
-   */
-  public boolean isReturningReplyAsString() {
-    return returningReplyAsString;
-  }
-
-  /**
-   * @param returningReplyAsString true if the reply from the service is 
simply passed on as a
-   *     String, mostly in XML
-   */
-  public void setReturningReplyAsString(boolean returningReplyAsString) {
-    this.returningReplyAsString = returningReplyAsString;
-  }
-
-  /**
-   * @return the operationRequestName
-   */
-  public String getOperationRequestName() {
-    return operationRequestName;
-  }
-
-  /**
-   * @param operationRequestName the operationRequestName to set
-   */
-  public void setOperationRequestName(String operationRequestName) {
-    this.operationRequestName = operationRequestName;
-  }
 }
diff --git 
a/plugins/transforms/webservices/src/test/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMetaTest.java
 
b/plugins/transforms/webservices/src/test/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMetaTest.java
index 550ae0c2a1..cd039c2bb8 100644
--- 
a/plugins/transforms/webservices/src/test/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMetaTest.java
+++ 
b/plugins/transforms/webservices/src/test/java/org/apache/hop/pipeline/transforms/webservices/WebServiceMetaTest.java
@@ -18,254 +18,73 @@
 package org.apache.hop.pipeline.transforms.webservices;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotSame;
-import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
 import org.apache.hop.core.HopClientEnvironment;
-import org.apache.hop.core.ICheckResult;
-import org.apache.hop.core.database.DatabaseMeta;
-import org.apache.hop.core.exception.HopXmlException;
-import org.apache.hop.core.row.IRowMeta;
-import org.apache.hop.core.row.IValueMeta;
-import org.apache.hop.core.row.value.ValueMetaString;
-import org.apache.hop.core.variables.Variables;
-import org.apache.hop.core.xml.XmlHandler;
-import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
-import org.apache.hop.metadata.api.IHopMetadataProvider;
-import org.apache.hop.pipeline.PipelineMeta;
-import org.apache.hop.pipeline.transform.TransformMeta;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.junit.jupiter.api.BeforeAll;
+import org.apache.hop.pipeline.transform.TransformSerializationTestUtil;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-import org.w3c.dom.Node;
 
 class WebServiceMetaTest {
-  @RegisterExtension
-  static RestoreHopEngineEnvironmentExtension env = new 
RestoreHopEngineEnvironmentExtension();
 
-  @BeforeAll
-  static void setUpBeforeClass() throws Exception {
+  @BeforeEach
+  void beforeEach() throws Exception {
     HopClientEnvironment.init();
   }
 
   @Test
-  void testLoadXml() throws Exception {
-    Node node = getTestNode();
-    DatabaseMeta dbMeta = mock(DatabaseMeta.class);
-    IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
-    WebServiceMeta webServiceMeta = new WebServiceMeta(node, metadataProvider);
-    assertEquals("httpUser", webServiceMeta.getHttpLogin());
-    assertEquals("tryandguess", webServiceMeta.getHttpPassword());
-    assertEquals(
-        "http://webservices.gama-system.com/exchangerates.asmx?WSDL";, 
webServiceMeta.getUrl());
-    assertEquals("GetCurrentExchangeRate", webServiceMeta.getOperationName());
-    assertEquals("opRequestName", webServiceMeta.getOperationRequestName());
-    assertEquals("GetCurrentExchangeRateResult", 
webServiceMeta.getOutFieldArgumentName());
-    assertEquals("aProxy", webServiceMeta.getProxyHost());
-    assertEquals("4444", webServiceMeta.getProxyPort());
-    assertEquals(1, webServiceMeta.getCallTransform());
-    assertFalse(webServiceMeta.isPassingInputData());
-    assertTrue(webServiceMeta.isCompatible());
-    assertFalse(webServiceMeta.isReturningReplyAsString());
-    List<WebServiceField> fieldsIn = webServiceMeta.getFieldsIn();
-    assertEquals(3, fieldsIn.size());
-    assertWebServiceField(fieldsIn.get(0), "Bank", "strBank", "string", 2);
-    assertWebServiceField(fieldsIn.get(1), "ToCurrency", "strCurrency", 
"string", 2);
-    assertWebServiceField(fieldsIn.get(2), "Rank", "intRank", "int", 5);
-    List<WebServiceField> fieldsOut = webServiceMeta.getFieldsOut();
-    assertEquals(1, fieldsOut.size());
-    assertWebServiceField(
-        fieldsOut.get(0),
-        "GetCurrentExchangeRateResult",
-        "GetCurrentExchangeRateResult",
-        "decimal",
-        6);
-    WebServiceMeta clone = webServiceMeta.clone();
-    assertNotSame(clone, webServiceMeta);
-    assertEquals(clone.getXml(), webServiceMeta.getXml());
-  }
-
-  void assertWebServiceField(
-      WebServiceField webServiceField, String name, String wsName, String 
xsdType, int type) {
-    assertEquals(name, webServiceField.getName());
-    assertEquals(wsName, webServiceField.getWsName());
-    assertEquals(xsdType, webServiceField.getXsdType());
-    assertEquals(type, webServiceField.getType());
-  }
-
-  @Test
-  void testGetFields() throws Exception {
-    WebServiceMeta webServiceMeta = new WebServiceMeta();
-    webServiceMeta.setDefault();
-    IRowMeta rmi = mock(IRowMeta.class);
-    IRowMeta rmi2 = mock(IRowMeta.class);
-    TransformMeta nextTransform = mock(TransformMeta.class);
-    IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
-    WebServiceField field1 = new WebServiceField();
-    field1.setName("field1");
-    field1.setWsName("field1WS");
-    field1.setXsdType("string");
-    WebServiceField field2 = new WebServiceField();
-    field2.setName("field2");
-    field2.setWsName("field2WS");
-    field2.setXsdType("string");
-    WebServiceField field3 = new WebServiceField();
-    field3.setName("field3");
-    field3.setWsName("field3WS");
-    field3.setXsdType("string");
-    webServiceMeta.setFieldsOut(Arrays.asList(field1, field2, field3));
-    webServiceMeta.getFields(
-        rmi, "idk", new IRowMeta[] {rmi2}, nextTransform, new Variables(), 
metadataProvider);
-    // verify(rmi).addValueMeta(argThat(matchValueMetaString("field1")));
-    // verify(rmi).addValueMeta(argThat(matchValueMetaString("field2")));
-    // verify(rmi).addValueMeta(argThat(matchValueMetaString("field3")));
-  }
+  void testSerializationRoundTrip() throws Exception {
+    WebServiceMeta meta =
+        TransformSerializationTestUtil.testSerialization(
+            "/webservice-lookup.xml", WebServiceMeta.class);
 
-  private Matcher<IValueMeta> matchValueMetaString(final String fieldName) {
-    return new BaseMatcher<>() {
-      @Override
-      public boolean matches(Object item) {
-        return fieldName.equals(((ValueMetaString) item).getName());
-      }
+    assertEquals("url", meta.getUrl());
+    assertEquals("operation", meta.getOperationName());
+    assertEquals("operationRequest", meta.getOperationRequestName());
+    assertEquals("operationNameSpace", meta.getOperationNamespace());
+    assertEquals("wsInFieldContainer", meta.getInFieldContainerName());
+    assertEquals("wsInFieldArg", meta.getInFieldArgumentName());
+    assertEquals("outFieldContainer", meta.getOutFieldContainerName());
+    assertEquals("outFieldArgument", meta.getOutFieldArgumentName());
+    assertEquals("proxy-host", meta.getProxyHost());
+    assertEquals("proxy-port", meta.getProxyPort());
+    assertEquals("http-login", meta.getHttpLogin());
+    assertEquals("http-password", meta.getHttpPassword());
+    assertEquals(1000, meta.getCallTransform());
+    assertTrue(meta.isPassingInputData());
+    assertTrue(meta.isCompatible());
+    assertEquals("repeating-element", meta.getRepeatingElementName());
+    assertTrue(meta.isReturningReplyAsString());
 
-      @Override
-      public void describeTo(Description description) {
-        // Do nothing
-      }
-    };
+    validateFieldsIn(meta);
+    validateFieldsOut(meta);
   }
 
-  @Test
-  void testCheck() {
-    WebServiceMeta webServiceMeta = new WebServiceMeta();
-    PipelineMeta pipelineMeta = mock(PipelineMeta.class);
-    TransformMeta transformMeta = mock(TransformMeta.class);
-    IRowMeta prev = mock(IRowMeta.class);
-    IRowMeta info = mock(IRowMeta.class);
-    IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
-    String[] input = {"one"};
-    ArrayList<ICheckResult> remarks = new ArrayList<>();
-    webServiceMeta.check(
-        remarks,
-        pipelineMeta,
-        transformMeta,
-        null,
-        input,
-        null,
-        info,
-        new Variables(),
-        metadataProvider);
-    assertEquals(2, remarks.size());
-    assertEquals("Not receiving any fields from previous transforms!", 
remarks.get(0).getText());
-    assertEquals("Transform is receiving info from other transforms.", 
remarks.get(1).getText());
-
-    remarks.clear();
-    webServiceMeta.setInFieldArgumentName("ifan");
-    when(prev.size()).thenReturn(2);
-    webServiceMeta.check(
-        remarks,
-        pipelineMeta,
-        transformMeta,
-        prev,
-        new String[] {},
-        null,
-        info,
-        new Variables(),
-        metadataProvider);
-    assertEquals(2, remarks.size());
-    assertEquals(
-        "Transform is connected to previous one, receiving 2 fields", 
remarks.get(0).getText());
-    assertEquals("No input received from other transforms!", 
remarks.get(1).getText());
-  }
-
-  @Test
-  void testGetFieldOut() throws Exception {
-    DatabaseMeta dbMeta = mock(DatabaseMeta.class);
-    IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
-    WebServiceMeta webServiceMeta = new WebServiceMeta(getTestNode(), 
metadataProvider);
-    assertNull(webServiceMeta.getFieldOutFromWsName("", true));
-    assertEquals(
-        "GetCurrentExchangeRateResult",
-        webServiceMeta.getFieldOutFromWsName("GetCurrentExchangeRateResult", 
false).getName());
-    assertEquals(
-        "GetCurrentExchangeRateResult",
-        webServiceMeta
-            .getFieldOutFromWsName("something:GetCurrentExchangeRateResult", 
true)
-            .getName());
+  private static void validateFieldsOut(WebServiceMeta meta) {
+    assertEquals(3, meta.getFieldsOut().size());
+    WebServiceField o = meta.getFieldsOut().getFirst();
+    assertEquals("out1", o.getName());
+    assertEquals("wsOut1", o.getWsName());
+    assertEquals("outType1", o.getXsdType());
+    o = meta.getFieldsOut().get(1);
+    assertEquals("out2", o.getName());
+    assertEquals("wsOut2", o.getWsName());
+    assertEquals("outType2", o.getXsdType());
+    o = meta.getFieldsOut().getLast();
+    assertEquals("out3", o.getName());
+    assertEquals("wsOut3", o.getWsName());
+    assertEquals("outType3", o.getXsdType());
   }
 
-  private Node getTestNode() throws HopXmlException {
-    String xml =
-        "  <transform>\n"
-            + "    <name>Web services lookup</name>\n"
-            + "    <type>WebServiceLookup</type>\n"
-            + "    <description/>\n"
-            + "    <distribute>Y</distribute>\n"
-            + "    <custom_distribution/>\n"
-            + "    <copies>1</copies>\n"
-            + "         <partitioning>\n"
-            + "           <method>none</method>\n"
-            + "           <schema_name/>\n"
-            + "           </partitioning>\n"
-            + "    
<wsURL>http&#x3a;&#x2f;&#x2f;webservices.gama-system.com&#x2f;exchangerates.asmx&#x3f;WSDL</wsURL>\n"
-            + "    <wsOperation>GetCurrentExchangeRate</wsOperation>\n"
-            + "    <wsOperationRequest>opRequestName</wsOperationRequest>\n"
-            + "    
<wsOperationNamespace>http&#x3a;&#x2f;&#x2f;www.gama-system.com&#x2f;"
-            + "webservices</wsOperationNamespace>\n"
-            + "    <wsInFieldContainer/>\n"
-            + "    <wsInFieldArgument/>\n"
-            + "    
<wsOutFieldContainer>GetCurrentExchangeRateResult</wsOutFieldContainer>\n"
-            + "    
<wsOutFieldArgument>GetCurrentExchangeRateResult</wsOutFieldArgument>\n"
-            + "    <proxyHost>aProxy</proxyHost>\n"
-            + "    <proxyPort>4444</proxyPort>\n"
-            + "    <httpLogin>httpUser</httpLogin>\n"
-            + "    <httpPassword>tryandguess</httpPassword>\n"
-            + "    <callTransform>1</callTransform>\n"
-            + "    <passingInputData>N</passingInputData>\n"
-            + "    <compatible>Y</compatible>\n"
-            + "    <repeating_element/>\n"
-            + "    <reply_as_string>N</reply_as_string>\n"
-            + "    <fieldsIn>\n"
-            + "    <field>\n"
-            + "        <name>Bank</name>\n"
-            + "        <wsName>strBank</wsName>\n"
-            + "        <xsdType>string</xsdType>\n"
-            + "    </field>\n"
-            + "    <field>\n"
-            + "        <name>ToCurrency</name>\n"
-            + "        <wsName>strCurrency</wsName>\n"
-            + "        <xsdType>string</xsdType>\n"
-            + "    </field>\n"
-            + "    <field>\n"
-            + "        <name>Rank</name>\n"
-            + "        <wsName>intRank</wsName>\n"
-            + "        <xsdType>int</xsdType>\n"
-            + "    </field>\n"
-            + "      </fieldsIn>\n"
-            + "    <fieldsOut>\n"
-            + "    <field>\n"
-            + "        <name>GetCurrentExchangeRateResult</name>\n"
-            + "        <wsName>GetCurrentExchangeRateResult</wsName>\n"
-            + "        <xsdType>decimal</xsdType>\n"
-            + "    </field>\n"
-            + "      </fieldsOut>\n"
-            + "     <cluster_schema/>\n"
-            + "    <GUI>\n"
-            + "      <xloc>331</xloc>\n"
-            + "      <yloc>207</yloc>\n"
-            + "      <draw>Y</draw>\n"
-            + "      </GUI>\n"
-            + "    </transform>\n";
-    return XmlHandler.loadXmlString(xml, "transform");
+  private static void validateFieldsIn(WebServiceMeta meta) {
+    assertEquals(2, meta.getFieldsIn().size());
+    WebServiceField i = meta.getFieldsIn().getFirst();
+    assertEquals("name1", i.getName());
+    assertEquals("wsName1", i.getWsName());
+    assertEquals("wsType1", i.getXsdType());
+    i = meta.getFieldsIn().getLast();
+    assertEquals("name2", i.getName());
+    assertEquals("wsName2", i.getWsName());
+    assertEquals("wsType2", i.getXsdType());
   }
 }
diff --git 
a/plugins/transforms/webservices/src/test/resources/webservice-lookup.xml 
b/plugins/transforms/webservices/src/test/resources/webservice-lookup.xml
new file mode 100644
index 0000000000..0cd5961c3d
--- /dev/null
+++ b/plugins/transforms/webservices/src/test/resources/webservice-lookup.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<transform>
+    <wsURL>url</wsURL>
+    <wsOperation>operation</wsOperation>
+    <wsOperationRequest>operationRequest</wsOperationRequest>
+    <wsOperationNamespace>operationNameSpace</wsOperationNamespace>
+    <wsInFieldContainer>wsInFieldContainer</wsInFieldContainer>
+    <wsInFieldArgument>wsInFieldArg</wsInFieldArgument>
+    <wsOutFieldContainer>outFieldContainer</wsOutFieldContainer>
+    <wsOutFieldArgument>outFieldArgument</wsOutFieldArgument>
+    <proxyHost>proxy-host</proxyHost>
+    <proxyPort>proxy-port</proxyPort>
+    <httpLogin>http-login</httpLogin>
+    <httpPassword>http-password</httpPassword>
+    <callTransform>1000</callTransform>
+    <passingInputData>Y</passingInputData>
+    <compatible>Y</compatible>
+    <repeating_element>repeating-element</repeating_element>
+    <reply_as_string>Y</reply_as_string>
+    <fieldsIn>
+        <field>
+            <name>name1</name>
+            <wsName>wsName1</wsName>
+            <xsdType>wsType1</xsdType>
+        </field>
+        <field>
+            <name>name2</name>
+            <wsName>wsName2</wsName>
+            <xsdType>wsType2</xsdType>
+        </field>
+    </fieldsIn>
+    <fieldsOut>
+        <field>
+            <name>out1</name>
+            <wsName>wsOut1</wsName>
+            <xsdType>outType1</xsdType>
+        </field>
+        <field>
+            <name>out2</name>
+            <wsName>wsOut2</wsName>
+            <xsdType>outType2</xsdType>
+        </field>
+        <field>
+            <name>out3</name>
+            <wsName>wsOut3</wsName>
+            <xsdType>outType3</xsdType>
+        </field>
+    </fieldsOut>
+</transform>
+


Reply via email to