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

bamaer 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 17d8448b04 Issue #8561 : Do not warn about a missing connection when 
Add Sequence uses a counter (#8634)
17d8448b04 is described below

commit 17d8448b04ff5a164ad3d055e8cbe5eb53437697
Author: Matt Casters <[email protected]>
AuthorDate: Sun Sep 27 11:13:31 2026 +0200

    Issue #8561 : Do not warn about a missing connection when Add Sequence uses 
a counter (#8634)
    
    Add Sequence reported a missing database connection when the sequence was
    generated with a counter. The connection is only required when a database
    sequence is selected.
---
 .../metadata/api/IOptionalDatabaseConnection.java  |  34 +++++
 .../ReferencedDatabaseConnectionChecker.java       |  31 +++-
 .../ReferencedDatabaseConnectionCheckerTest.java   |  65 ++++++++
 .../transforms/addsequence/AddSequenceMeta.java    | 164 ++++++++++++---------
 .../addsequence/AddSequenceMetaTest.java           |  89 +++++++++++
 5 files changed, 314 insertions(+), 69 deletions(-)

diff --git 
a/core/src/main/java/org/apache/hop/metadata/api/IOptionalDatabaseConnection.java
 
b/core/src/main/java/org/apache/hop/metadata/api/IOptionalDatabaseConnection.java
new file mode 100644
index 0000000000..9c547aaf29
--- /dev/null
+++ 
b/core/src/main/java/org/apache/hop/metadata/api/IOptionalDatabaseConnection.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package org.apache.hop.metadata.api;
+
+/**
+ * A metadata object whose relational connection is only used for some 
settings.
+ *
+ * <p>Connection checks treat every {@link 
HopMetadataPropertyType#RDBMS_CONNECTION} field as
+ * required. Implement this when a connection can be left unset, and return 
{@code false} for a
+ * field the current settings do not use. That field is left out of the check.
+ */
+public interface IOptionalDatabaseConnection {
+
+  /**
+   * @param key the serialised key of the connection field, or the field name 
when no key is set
+   * @return {@code true} when that connection has to be assigned for the 
current settings
+   */
+  boolean isDatabaseConnectionUsed(String key);
+}
diff --git 
a/engine/src/main/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionChecker.java
 
b/engine/src/main/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionChecker.java
index c9f32d15bd..8ac5c62a8b 100644
--- 
a/engine/src/main/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionChecker.java
+++ 
b/engine/src/main/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionChecker.java
@@ -31,6 +31,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.metadata.api.HopMetadataPropertyType;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.metadata.api.IHopMetadataSerializer;
+import org.apache.hop.metadata.api.IOptionalDatabaseConnection;
 import org.apache.hop.metadata.util.HopMetadataPropertyWalker;
 import org.apache.hop.metadata.util.HopMetadataPropertyWalker.StringProperty;
 import org.apache.hop.pipeline.PipelineMeta;
@@ -44,7 +45,9 @@ import org.apache.hop.workflow.action.ActionMeta;
  *
  * <p>This is an existence check only. It never opens a JDBC connection. Names 
that still contain a
  * variable token after resolving the current {@link IVariables} are skipped, 
because the name
- * cannot be decided at design time.
+ * cannot be decided at design time. A metadata object that implements {@link
+ * IOptionalDatabaseConnection} can say that a connection field is unused for 
the current settings;
+ * that field is left out of this check.
  */
 public final class ReferencedDatabaseConnectionChecker {
 
@@ -159,6 +162,9 @@ public final class ReferencedDatabaseConnectionChecker {
     for (StringProperty property :
         HopMetadataPropertyWalker.collectStrings(
             metadataObject, HopMetadataPropertyType.RDBMS_CONNECTION, true)) {
+      if (!isConnectionUsed(metadataObject, property.key())) {
+        continue;
+      }
       ICheckResult remark =
           checkConnectionName(
               property.value(), ownerKind, ownerName, source, variables, 
serializer);
@@ -169,6 +175,29 @@ public final class ReferencedDatabaseConnectionChecker {
     return remarks;
   }
 
+  /**
+   * A connection field is required unless the metadata object says the 
current settings do not use
+   * it. A failure in that callback is treated as required, so a broken plugin 
still reports a
+   * missing connection.
+   */
+  private static boolean isConnectionUsed(Object metadataObject, String key) {
+    if (!(metadataObject instanceof IOptionalDatabaseConnection optional)) {
+      return true;
+    }
+    try {
+      return optional.isDatabaseConnectionUsed(key);
+    } catch (RuntimeException e) {
+      if (HopLogStore.isInitialized()) {
+        LogChannel.GENERAL.logDebug(
+            "Could not decide whether connection '"
+                + key
+                + "' is used, so it is still checked: "
+                + e.getMessage());
+      }
+      return true;
+    }
+  }
+
   /**
    * Why the lookup failed, in one line fit for a table cell.
    *
diff --git 
a/engine/src/test/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionCheckerTest.java
 
b/engine/src/test/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionCheckerTest.java
index dc370b612b..bac269d681 100644
--- 
a/engine/src/test/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionCheckerTest.java
+++ 
b/engine/src/test/java/org/apache/hop/metadata/validation/ReferencedDatabaseConnectionCheckerTest.java
@@ -32,6 +32,7 @@ import org.apache.hop.metadata.api.HopMetadataProperty;
 import org.apache.hop.metadata.api.HopMetadataPropertyType;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.metadata.api.IHopMetadataSerializer;
+import org.apache.hop.metadata.api.IOptionalDatabaseConnection;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.transform.TransformMeta;
 import org.apache.hop.pipeline.transforms.dummy.DummyMeta;
@@ -324,4 +325,68 @@ class ReferencedDatabaseConnectionCheckerTest {
     @HopMetadataProperty(hopMetadataPropertyType = 
HopMetadataPropertyType.RDBMS_CONNECTION)
     String connection;
   }
+
+  /**
+   * Issue #8561. Add Sequence keeps a connection field for the 
database-sequence option and leaves
+   * it unset when a counter is used. That field must not be reported as a 
missing connection.
+   */
+  static class OptionalConnMeta implements IOptionalDatabaseConnection {
+    @HopMetadataProperty(
+        key = "connection",
+        hopMetadataPropertyType = HopMetadataPropertyType.RDBMS_CONNECTION)
+    String connection;
+
+    boolean used;
+
+    OptionalConnMeta(String connection, boolean used) {
+      this.connection = connection;
+      this.used = used;
+    }
+
+    @Override
+    public boolean isDatabaseConnectionUsed(String key) {
+      return used;
+    }
+  }
+
+  @Test
+  void unusedConnectionIsNotReported() {
+    assertTrue(check(new OptionalConnMeta(null, false), "Add 
sequence").isEmpty());
+    assertTrue(check(new OptionalConnMeta("", false), "Add 
sequence").isEmpty());
+    assertTrue(check(new OptionalConnMeta("missing-db", false), "Add 
sequence").isEmpty());
+  }
+
+  @Test
+  void optionalConnectionIsReportedWhenItIsUsed() {
+    List<ICheckResult> remarks = check(new OptionalConnMeta(null, true), "Add 
sequence");
+
+    assertEquals(1, remarks.size());
+    assertEquals(
+        ReferencedDatabaseConnectionChecker.ERROR_NOT_ASSIGNED, 
remarks.get(0).getErrorCode());
+  }
+
+  @Test
+  void optionalConnectionThatExistsIsSilent() {
+    assertTrue(check(new OptionalConnMeta("sales-db", true), "Add 
sequence").isEmpty());
+  }
+
+  /** A usage callback that throws must not hide a missing connection. */
+  static class ThrowingOptionalConnMeta implements IOptionalDatabaseConnection 
{
+    @HopMetadataProperty(hopMetadataPropertyType = 
HopMetadataPropertyType.RDBMS_CONNECTION)
+    String connection;
+
+    @Override
+    public boolean isDatabaseConnectionUsed(String key) {
+      throw new IllegalStateException("broken");
+    }
+  }
+
+  @Test
+  void aBrokenUsageCallbackStillReportsTheConnection() {
+    List<ICheckResult> remarks = check(new ThrowingOptionalConnMeta(), "Add 
sequence");
+
+    assertEquals(1, remarks.size());
+    assertEquals(
+        ReferencedDatabaseConnectionChecker.ERROR_NOT_ASSIGNED, 
remarks.get(0).getErrorCode());
+  }
 }
diff --git 
a/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMeta.java
 
b/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMeta.java
index 7038ea3873..ade6e663d5 100644
--- 
a/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMeta.java
+++ 
b/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMeta.java
@@ -31,11 +31,13 @@ import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.core.row.IValueMeta;
 import org.apache.hop.core.row.value.ValueMetaInteger;
+import org.apache.hop.core.util.Utils;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.metadata.api.HopMetadataProperty;
 import org.apache.hop.metadata.api.HopMetadataPropertyType;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.metadata.api.IOptionalDatabaseConnection;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.transform.BaseTransformMeta;
 import org.apache.hop.pipeline.transform.TransformMeta;
@@ -51,7 +53,8 @@ import org.apache.hop.pipeline.transform.TransformMeta;
     keywords = "i18n::AddSequenceMeta.keyword")
 @Getter
 @Setter
-public class AddSequenceMeta extends BaseTransformMeta<AddSequence, 
AddSequenceData> {
+public class AddSequenceMeta extends BaseTransformMeta<AddSequence, 
AddSequenceData>
+    implements IOptionalDatabaseConnection {
 
   private static final Class<?> PKG = AddSequenceMeta.class;
 
@@ -154,6 +157,15 @@ public class AddSequenceMeta extends 
BaseTransformMeta<AddSequence, AddSequenceD
     row.addValueMeta(v);
   }
 
+  /**
+   * The connection is only used when a database sequence is selected. A 
counter leaves it unset,
+   * and that must not be reported as a missing connection.
+   */
+  @Override
+  public boolean isDatabaseConnectionUsed(String key) {
+    return databaseUsed;
+  }
+
   @Override
   public void check(
       List<ICheckResult> remarks,
@@ -165,50 +177,14 @@ public class AddSequenceMeta extends 
BaseTransformMeta<AddSequence, AddSequenceD
       IRowMeta info,
       IVariables variables,
       IHopMetadataProvider metadataProvider) {
-    CheckResult cr;
-    Database db = null;
-
-    try {
-      DatabaseMeta databaseMeta =
-          
metadataProvider.getSerializer(DatabaseMeta.class).load(variables.resolve(connection));
-
-      if (databaseUsed) {
-        db = new Database(loggingObject, variables, databaseMeta);
-        db.connect();
-        if (db.checkSequenceExists(
-            variables.resolve(schemaName), variables.resolve(sequenceName))) {
-          cr =
-              new CheckResult(
-                  ICheckResult.TYPE_RESULT_OK,
-                  BaseMessages.getString(PKG, 
"AddSequenceMeta.CheckResult.SequenceExists.Title"),
-                  transformMeta);
-        } else {
-          cr =
-              new CheckResult(
-                  ICheckResult.TYPE_RESULT_ERROR,
-                  BaseMessages.getString(
-                      PKG,
-                      
"AddSequenceMeta.CheckResult.SequenceCouldNotBeFound.Title",
-                      sequenceName),
-                  transformMeta);
-        }
-        remarks.add(cr);
-      }
-    } catch (HopException e) {
-      cr =
-          new CheckResult(
-              ICheckResult.TYPE_RESULT_ERROR,
-              BaseMessages.getString(PKG, 
"AddSequenceMeta.CheckResult.UnableToConnectDB.Title")
-                  + Const.CR
-                  + e.getMessage(),
-              transformMeta);
-      remarks.add(cr);
-    } finally {
-      if (db != null) {
-        db.close();
-      }
+    // The counter does not open a connection. Loading an unset name here only 
raises "you need to
+    // specify the name of the metadata object to load", which the verify 
dialog shows as a database
+    // error. Issue #8561.
+    if (databaseUsed) {
+      checkDatabaseSequence(remarks, transformMeta, variables, 
metadataProvider);
     }
 
+    CheckResult cr;
     if (input.length > 0) {
       cr =
           new CheckResult(
@@ -226,6 +202,57 @@ public class AddSequenceMeta extends 
BaseTransformMeta<AddSequence, AddSequenceD
     }
   }
 
+  /**
+   * Verify the database sequence. An unset connection is left to {@code
+   * ReferencedDatabaseConnectionChecker}, which reports it with a code the 
linter can baseline.
+   */
+  private void checkDatabaseSequence(
+      List<ICheckResult> remarks,
+      TransformMeta transformMeta,
+      IVariables variables,
+      IHopMetadataProvider metadataProvider) {
+    String resolvedConnection = variables.resolve(connection);
+    if (Utils.isEmpty(resolvedConnection)) {
+      return;
+    }
+
+    Database db = null;
+    try {
+      DatabaseMeta databaseMeta =
+          
metadataProvider.getSerializer(DatabaseMeta.class).load(resolvedConnection);
+      db = new Database(loggingObject, variables, databaseMeta);
+      db.connect();
+      CheckResult cr;
+      if (db.checkSequenceExists(variables.resolve(schemaName), 
variables.resolve(sequenceName))) {
+        cr =
+            new CheckResult(
+                ICheckResult.TYPE_RESULT_OK,
+                BaseMessages.getString(PKG, 
"AddSequenceMeta.CheckResult.SequenceExists.Title"),
+                transformMeta);
+      } else {
+        cr =
+            new CheckResult(
+                ICheckResult.TYPE_RESULT_ERROR,
+                BaseMessages.getString(
+                    PKG, 
"AddSequenceMeta.CheckResult.SequenceCouldNotBeFound.Title", sequenceName),
+                transformMeta);
+      }
+      remarks.add(cr);
+    } catch (HopException e) {
+      remarks.add(
+          new CheckResult(
+              ICheckResult.TYPE_RESULT_ERROR,
+              BaseMessages.getString(PKG, 
"AddSequenceMeta.CheckResult.UnableToConnectDB.Title")
+                  + Const.CR
+                  + e.getMessage(),
+              transformMeta));
+    } finally {
+      if (db != null) {
+        db.close();
+      }
+    }
+  }
+
   @Override
   public SqlStatement getSqlStatements(
       IVariables variables,
@@ -233,37 +260,38 @@ public class AddSequenceMeta extends 
BaseTransformMeta<AddSequence, AddSequenceD
       TransformMeta transformMeta,
       IRowMeta prev,
       IHopMetadataProvider metadataProvider) {
+    SqlStatement retval = new SqlStatement(transformMeta.getName(), null, 
null);
+    if (!databaseUsed) {
+      return retval;
+    }
+
     Database db = null;
-    SqlStatement retval = null;
     try {
-      DatabaseMeta databaseMeta =
-          
metadataProvider.getSerializer(DatabaseMeta.class).load(variables.resolve(connection));
-      retval = new SqlStatement(transformMeta.getName(), databaseMeta, null);
-      // default: nothing to do!
-      if (databaseUsed) {
-        // Otherwise, don't bother!
-        if (databaseMeta != null) {
-          db = new Database(loggingObject, variables, databaseMeta);
-          db.connect();
-          if (!db.checkSequenceExists(schemaName, sequenceName)) {
-            String crTable =
-                db.getCreateSequenceStatement(sequenceName, startAt, 
incrementBy, maxValue, true);
-            retval.setSql(crTable);
-          } else {
-            retval.setSql(null); // Empty string means: nothing to do: set it 
to null...
-          }
+      String resolvedConnection = variables.resolve(connection);
+      DatabaseMeta databaseMeta = null;
+      if (!Utils.isEmpty(resolvedConnection)) {
+        databaseMeta = 
metadataProvider.getSerializer(DatabaseMeta.class).load(resolvedConnection);
+      }
+      retval.setDatabase(databaseMeta);
+      if (databaseMeta != null) {
+        db = new Database(loggingObject, variables, databaseMeta);
+        db.connect();
+        if (!db.checkSequenceExists(schemaName, sequenceName)) {
+          String crTable =
+              db.getCreateSequenceStatement(sequenceName, startAt, 
incrementBy, maxValue, true);
+          retval.setSql(crTable);
         } else {
-          retval.setError(
-              BaseMessages.getString(PKG, 
"AddSequenceMeta.ErrorMessage.NoConnectionDefined"));
+          retval.setSql(null); // Empty string means: nothing to do: set it to 
null...
         }
-      }
-    } catch (HopException e) {
-      if (retval != null) {
+      } else {
         retval.setError(
-            BaseMessages.getString(PKG, 
"AddSequenceMeta.ErrorMessage.UnableToConnectDB")
-                + Const.CR
-                + e.getMessage());
+            BaseMessages.getString(PKG, 
"AddSequenceMeta.ErrorMessage.NoConnectionDefined"));
       }
+    } catch (HopException e) {
+      retval.setError(
+          BaseMessages.getString(PKG, 
"AddSequenceMeta.ErrorMessage.UnableToConnectDB")
+              + Const.CR
+              + e.getMessage());
     } finally {
       if (db != null) {
         db.close();
diff --git 
a/plugins/transforms/addsequence/src/test/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMetaTest.java
 
b/plugins/transforms/addsequence/src/test/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMetaTest.java
index 4eda296b5d..ff3e87cf19 100644
--- 
a/plugins/transforms/addsequence/src/test/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMetaTest.java
+++ 
b/plugins/transforms/addsequence/src/test/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceMetaTest.java
@@ -22,13 +22,26 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.core.ICheckResult;
+import org.apache.hop.core.SqlStatement;
+import org.apache.hop.core.database.DatabaseMeta;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.metadata.api.IHopMetadataSerializer;
+import org.apache.hop.metadata.validation.ReferencedDatabaseConnectionChecker;
+import org.apache.hop.pipeline.transform.TransformMeta;
 import org.apache.hop.pipeline.transforms.loadsave.LoadSaveTester;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -148,4 +161,80 @@ class AddSequenceMetaTest {
     assertEquals(meta.getConnection(), cloned.getConnection());
     assertEquals(meta.getStartAt(), cloned.getStartAt());
   }
+
+  /**
+   * Issue #8561. The default Add Sequence uses a counter and has no 
connection. That must not be
+   * reported as a missing database connection, and verify must not try to 
load one.
+   */
+  @Test
+  void counterSequenceDoesNotWarnAboutAMissingConnection() throws Exception {
+    AddSequenceMeta meta = new AddSequenceMeta();
+    meta.setDefault();
+    assertFalse(meta.isDatabaseConnectionUsed("connection"));
+
+    IHopMetadataProvider provider = metadataProviderThatCannotLoad();
+    List<ICheckResult> remarks =
+        ReferencedDatabaseConnectionChecker.checkObject(
+            meta, "Transform", "Add sequence", null, new Variables(), 
provider);
+
+    assertTrue(remarks.isEmpty());
+
+    TransformMeta transformMeta = new TransformMeta("Add sequence", meta);
+    List<ICheckResult> checked = new ArrayList<>();
+    meta.check(
+        checked,
+        null,
+        transformMeta,
+        null,
+        new String[] {"Generate rows"},
+        new String[0],
+        null,
+        new Variables(),
+        provider);
+
+    assertEquals(1, checked.size());
+    assertEquals(ICheckResult.TYPE_RESULT_OK, checked.get(0).getType());
+
+    SqlStatement sql = meta.getSqlStatements(new Variables(), null, 
transformMeta, null, provider);
+    assertNotNull(sql);
+    assertNull(sql.getSql());
+    assertFalse(sql.hasError());
+  }
+
+  /** Selecting a database sequence with no connection still has to be 
reported. */
+  @Test
+  void databaseSequenceWithoutAConnectionIsReported() throws Exception {
+    AddSequenceMeta meta = new AddSequenceMeta();
+    meta.setDefault();
+    meta.setDatabaseUsed(true);
+    meta.setCounterUsed(false);
+    assertTrue(meta.isDatabaseConnectionUsed("connection"));
+
+    IHopMetadataProvider provider = metadataProviderThatCannotLoad();
+    List<ICheckResult> remarks =
+        ReferencedDatabaseConnectionChecker.checkObject(
+            meta, "Transform", "Add sequence", null, new Variables(), 
provider);
+
+    assertEquals(1, remarks.size());
+    assertEquals(
+        ReferencedDatabaseConnectionChecker.ERROR_NOT_ASSIGNED, 
remarks.get(0).getErrorCode());
+
+    TransformMeta transformMeta = new TransformMeta("Add sequence", meta);
+    SqlStatement sql = meta.getSqlStatements(new Variables(), null, 
transformMeta, null, provider);
+    assertTrue(sql.hasError());
+    assertEquals(
+        BaseMessages.getString(
+            AddSequenceMeta.class, 
"AddSequenceMeta.ErrorMessage.NoConnectionDefined"),
+        sql.getError());
+  }
+
+  @SuppressWarnings("unchecked")
+  private static IHopMetadataProvider metadataProviderThatCannotLoad() throws 
HopException {
+    IHopMetadataProvider provider = mock(IHopMetadataProvider.class);
+    IHopMetadataSerializer<DatabaseMeta> serializer = 
mock(IHopMetadataSerializer.class);
+    when(provider.getSerializer(DatabaseMeta.class)).thenReturn(serializer);
+    when(serializer.load(nullable(String.class)))
+        .thenThrow(new HopException("you need to specify the name of the 
metadata object to load"));
+    return provider;
+  }
 }

Reply via email to