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

smolnar82 pushed a commit to branch knox_idf
in repository https://gitbox.apache.org/repos/asf/knox.git

commit 331f3bbd257e5f8b6d2014ba773ac78a21d6c206
Author: Sandor Molnar <[email protected]>
AuthorDate: Wed Aug 12 18:22:31 2026 +0200

    KNOX-3414: fix embedded-Derby table-exists check and add DerbyDB 
TrustedOidcIssuerService default
    
    JDBCUtils.tableExists passed the table name verbatim for uppercase-storing
    engines (Derby), so a lowercase constant like federated_identity never 
matched
    Derby's uppercased FEDERATED_IDENTITY metadata. On restart tableExists 
returned
    false, createTableIfNotExists re-ran the CREATE, and Derby failed with
    "Table/View 'FEDERATED_IDENTITY' already exists". Uppercase-constant callers
    (KNOX_TOKENS, KNOX_PROVIDERS, TRUSTED_OIDC_ISSUERS) accidentally worked. 
Extract
    a normalizeIdentifier() helper that upper-cases for uppercase-storing 
engines and
    lower-cases for lowercase-storing ones.
    
    Also add DerbyDBTrustedOidcIssuerService, a self-provisioning embedded-Derby
    default mirroring DerbyDBFederatedIdentityService, and wire
    TrustedOidcIssuerServiceFactory to auto-select Derby vs JDBC based on 
external
    DB config instead of always using JDBC.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
---
 .../apache/knox/gateway/database/JDBCUtils.java    |  20 +-
 .../factory/TrustedOidcIssuerServiceFactory.java   |  72 ++++--
 .../DerbyDBTrustedOidcIssuerService.java           | 102 ++++++++
 .../TrustedOidcIssuerServiceFactoryTest.java       | 188 +++++++++++++++
 .../DerbyDBFederatedIdentityServiceTest.java       |  42 ++++
 .../DerbyDBTrustedOidcIssuerServiceTest.java       | 131 ++++++++++
 .../TrustedOidcIssuerServiceFactoryTest.java       | 265 ---------------------
 7 files changed, 540 insertions(+), 280 deletions(-)

diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/database/JDBCUtils.java 
b/gateway-server/src/main/java/org/apache/knox/gateway/database/JDBCUtils.java
index 014f8144f..30e2ab59f 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/database/JDBCUtils.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/database/JDBCUtils.java
@@ -36,7 +36,7 @@ public class JDBCUtils {
         boolean exists;
         try (Connection connection = dataSource.getConnection()) {
             final DatabaseMetaData dbMetadata = connection.getMetaData();
-            final String tableNameToCheck = 
dbMetadata.storesUpperCaseIdentifiers() ? tableName : 
tableName.toLowerCase(Locale.ROOT);
+            final String tableNameToCheck = normalizeIdentifier(tableName, 
dbMetadata);
             try (ResultSet tables = 
dbMetadata.getTables(connection.getCatalog(), null, tableNameToCheck, null)) {
                 exists = tables.next();
             }
@@ -44,6 +44,24 @@ public class JDBCUtils {
         return exists;
     }
 
+    /**
+     * Normalises an unquoted identifier to the case the driver actually 
stores it in, so it can be
+     * matched against {@link DatabaseMetaData#getTables}. Derby (and other 
uppercase-storing
+     * engines) store an unquoted {@code federated_identity} as {@code 
FEDERATED_IDENTITY}; passing
+     * the name verbatim would match nothing and cause {@code 
createTableIfNotExists} to re-run the
+     * CREATE and fail with "table already exists". Callers that use 
already-uppercase constants
+     * (KNOX_TOKENS, KNOX_PROVIDERS, TRUSTED_OIDC_ISSUERS) are unaffected 
since upper-casing them is
+     * a no-op.
+     */
+    private static String normalizeIdentifier(String identifier, 
DatabaseMetaData dbMetadata) throws SQLException {
+        if (dbMetadata.storesUpperCaseIdentifiers()) {
+            return identifier.toUpperCase(Locale.ROOT);
+        } else if (dbMetadata.storesLowerCaseIdentifiers()) {
+            return identifier.toLowerCase(Locale.ROOT);
+        }
+        return identifier;
+    }
+
     public static void createTableFromSQL(String createSqlFileName, DataSource 
dataSource, ClassLoader classLoader) throws Exception {
         try (InputStream is = 
classLoader.getResourceAsStream(createSqlFileName);
              Connection connection = dataSource.getConnection();Statement 
createTableStatement = connection.createStatement()) {
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TrustedOidcIssuerServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TrustedOidcIssuerServiceFactory.java
index 3f520f094..e8219c8e3 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TrustedOidcIssuerServiceFactory.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TrustedOidcIssuerServiceFactory.java
@@ -18,11 +18,13 @@ package org.apache.knox.gateway.services.factory;
 
 import org.apache.knox.gateway.GatewayMessages;
 import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.database.DatabaseType;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.knox.gateway.services.GatewayServices;
 import org.apache.knox.gateway.services.Service;
 import org.apache.knox.gateway.services.ServiceLifecycleException;
 import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.knoxidf.trustedoidcissuer.DerbyDBTrustedOidcIssuerService;
 import 
org.apache.knox.gateway.services.knoxidf.trustedoidcissuer.EmptyTrustedOidcIssuerService;
 import 
org.apache.knox.gateway.services.knoxidf.trustedoidcissuer.JdbcTrustedOidcIssuerService;
 import 
org.apache.knox.gateway.services.knoxidf.trustedoidcissuer.TrustedOidcIssuerService;
@@ -42,27 +44,20 @@ public class TrustedOidcIssuerServiceFactory extends 
AbstractServiceFactory {
       throws ServiceLifecycleException {
 
     String implementationToUse = implementation;
+    // No explicit impl configured: auto-select a persistence backend when 
KnoxIDF is deployed.
+    // Otherwise honor the configured impl (very likely a prod JDBC store).
     if (isEmptyDefaultImplementation(implementationToUse) && 
isKnoxIdfEnabledInAnyTopology(gatewayServices, gatewayConfig)) {
-      implementationToUse = JdbcTrustedOidcIssuerService.class.getName();
+      implementationToUse = chooseAutoImplementation(gatewayConfig);
     }
 
     TrustedOidcIssuerService service = null;
     if (shouldCreateService(implementationToUse)) {
       if (matchesImplementation(implementationToUse, 
EmptyTrustedOidcIssuerService.class, true)) {
         service = new EmptyTrustedOidcIssuerService();
+      } else if (matchesImplementation(implementationToUse, 
DerbyDBTrustedOidcIssuerService.class)) {
+        service = createDerbyService(gatewayServices, gatewayConfig, options);
       } else if (matchesImplementation(implementationToUse, 
JdbcTrustedOidcIssuerService.class)) {
-        try {
-          final JdbcTrustedOidcIssuerService jdbcService = new 
JdbcTrustedOidcIssuerService();
-          jdbcService.setAliasService(getAliasService(gatewayServices));
-          jdbcService.init(gatewayConfig, options);
-          service = jdbcService;
-        } catch (ServiceLifecycleException e) {
-          LOG.errorInitializingService(implementationToUse, e.getMessage(), e);
-          service = new EmptyTrustedOidcIssuerService();
-        } catch (Exception e) {
-          throw new ServiceLifecycleException(
-              "Error while creating TrustedOidcIssuerService: " + e, e);
-        }
+        service = createJdbcService(gatewayServices, gatewayConfig, options);
       }
       if (service != null) {
         logServiceUsage(service.getClass().getName(), serviceType);
@@ -71,6 +66,55 @@ public class TrustedOidcIssuerServiceFactory extends 
AbstractServiceFactory {
     return service;
   }
 
+  /**
+   * Chooses the auto-enabled implementation when KnoxIDF is deployed with no 
explicit impl: an
+   * operator-configured external database wins (very likely a prod JDBC 
store), otherwise a
+   * self-provisioning embedded Derby store (the {@code none}/{@code derbydb} 
default) so the
+   * trusted OIDC issuer registry works out of the box without any extra 
infrastructure.
+   */
+  String chooseAutoImplementation(GatewayConfig gatewayConfig) {
+    return isExternalDatabaseConfigured(gatewayConfig)
+        ? JdbcTrustedOidcIssuerService.class.getName()
+        : DerbyDBTrustedOidcIssuerService.class.getName();
+  }
+
+  private boolean isExternalDatabaseConfigured(GatewayConfig gatewayConfig) {
+    final String databaseType = gatewayConfig.getDatabaseType();
+    try {
+      return DatabaseType.fromString(databaseType) != DatabaseType.DERBY;
+    } catch (IllegalArgumentException e) {
+      // "none" (the default) or any unrecognized value: no real external DB 
-> use Derby.
+      return false;
+    }
+  }
+
+  private TrustedOidcIssuerService createDerbyService(GatewayServices 
gatewayServices, GatewayConfig gatewayConfig, Map<String, String> options)
+      throws ServiceLifecycleException {
+    try {
+      final DerbyDBTrustedOidcIssuerService derbyService = new 
DerbyDBTrustedOidcIssuerService();
+      derbyService.setAliasService(getAliasService(gatewayServices));
+      derbyService.setMasterService(getMasterService(gatewayServices));
+      derbyService.init(gatewayConfig, options);
+      return derbyService;
+    } catch (ServiceLifecycleException e) {
+      
LOG.errorInitializingService(DerbyDBTrustedOidcIssuerService.class.getName(), 
e.getMessage(), e);
+      return new EmptyTrustedOidcIssuerService();
+    }
+  }
+
+  private TrustedOidcIssuerService createJdbcService(GatewayServices 
gatewayServices, GatewayConfig gatewayConfig, Map<String, String> options)
+      throws ServiceLifecycleException {
+    try {
+      final JdbcTrustedOidcIssuerService jdbcService = new 
JdbcTrustedOidcIssuerService();
+      jdbcService.setAliasService(getAliasService(gatewayServices));
+      jdbcService.init(gatewayConfig, options);
+      return jdbcService;
+    } catch (ServiceLifecycleException e) {
+      
LOG.errorInitializingService(JdbcTrustedOidcIssuerService.class.getName(), 
e.getMessage(), e);
+      return new EmptyTrustedOidcIssuerService();
+    }
+  }
+
   @Override
   protected ServiceType getServiceType() {
     return ServiceType.TRUSTED_OIDC_ISSUER_SERVICE;
@@ -78,6 +122,6 @@ public class TrustedOidcIssuerServiceFactory extends 
AbstractServiceFactory {
 
   @Override
   protected Collection<String> getKnownImplementations() {
-    return List.of(DEFAULT_IMPLEMENTATION, 
JdbcTrustedOidcIssuerService.class.getName());
+    return List.of(DEFAULT_IMPLEMENTATION, 
JdbcTrustedOidcIssuerService.class.getName(), 
DerbyDBTrustedOidcIssuerService.class.getName());
   }
 }
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/DerbyDBTrustedOidcIssuerService.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/DerbyDBTrustedOidcIssuerService.java
new file mode 100644
index 000000000..f1c73e9b3
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/DerbyDBTrustedOidcIssuerService.java
@@ -0,0 +1,102 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.knox.gateway.services.knoxidf.trustedoidcissuer;
+
+import static 
org.apache.knox.gateway.config.impl.GatewayConfigImpl.GATEWAY_DATABASE_NAME;
+import static 
org.apache.knox.gateway.config.impl.GatewayConfigImpl.GATEWAY_DATABASE_TYPE;
+import static 
org.apache.knox.gateway.database.AbstractDataSourceFactory.DATABASE_PASSWORD_ALIAS_NAME;
+import static 
org.apache.knox.gateway.database.AbstractDataSourceFactory.DATABASE_USER_ALIAS_NAME;
+import static org.apache.knox.gateway.database.DatabaseType.DERBY;
+import static 
org.apache.knox.gateway.services.security.AliasService.NO_CLUSTER_NAME;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.gateway.services.token.impl.DerbyDBTokenStateService;
+import org.apache.knox.gateway.shell.jdbc.derby.DerbyDatabase;
+
+/**
+ * A self-provisioning, embedded-Derby backed {@link 
TrustedOidcIssuerService}. This is the
+ * auto-enabled default when KnoxIDF is deployed without an 
operator-configured external database,
+ * mirroring how {@link DerbyDBTokenStateService} is the default token-state 
service and
+ * {@code DerbyDBFederatedIdentityService} is the default federated-identity 
service.
+ * <p>
+ * It reuses the single embedded Derby database that the token-state service 
already provisions
+ * under {@code ${securityDir}/tokens} (the {@code ;create=true} JDBC URL is 
idempotent, so
+ * connecting to an already-booted database simply connects), sets the shared 
{@link GatewayConfig}
+ * to point at it, ensures the connection user/password aliases exist, and 
then delegates all
+ * persistence to {@link JdbcTrustedOidcIssuerService} (which builds the
+ * {@link TrustedOidcIssuerDatabase} and self-creates its table).
+ */
+public class DerbyDBTrustedOidcIssuerService extends 
JdbcTrustedOidcIssuerService {
+
+  private DerbyDatabase derbyDatabase;
+  private Path derbyDatabaseFolder;
+  private MasterService masterService;
+
+  public void setMasterService(MasterService masterService) {
+    this.masterService = masterService;
+  }
+
+  @Override
+  public void init(GatewayConfig config, Map<String, String> options) throws 
ServiceLifecycleException {
+    try {
+      derbyDatabaseFolder = Paths.get(config.getGatewaySecurityDir(), 
DerbyDBTokenStateService.DB_NAME);
+      startDerby();
+      ((Configuration) config).set(GATEWAY_DATABASE_TYPE, DERBY.type());
+      ((Configuration) config).set(GATEWAY_DATABASE_NAME, 
derbyDatabaseFolder.toString());
+      getAliasService().addAliasForCluster(NO_CLUSTER_NAME, 
DATABASE_USER_ALIAS_NAME, getDatabaseUserName());
+      getAliasService().addAliasForCluster(NO_CLUSTER_NAME, 
DATABASE_PASSWORD_ALIAS_NAME, getDatabasePassword());
+      super.init(config, options);
+    } catch (Exception e) {
+      throw new ServiceLifecycleException("Error while initiating 
DerbyDBTrustedOidcIssuerService: " + e, e);
+    }
+  }
+
+  private void startDerby() throws Exception {
+    derbyDatabase = new DerbyDatabase(derbyDatabaseFolder.toString());
+    derbyDatabase.create();
+    TimeUnit.SECONDS.sleep(1); // give a bit of time for the server to start
+  }
+
+  private String getDatabasePassword() throws Exception {
+    final char[] dbPasswordAliasValue = 
getAliasService().getPasswordFromAliasForGateway(DATABASE_PASSWORD_ALIAS_NAME);
+    return dbPasswordAliasValue != null ? new String(dbPasswordAliasValue) : 
new String(masterService.getMasterSecret());
+  }
+
+  private String getDatabaseUserName() throws Exception {
+    final char[] dbUserAliasValue = 
getAliasService().getPasswordFromAliasForGateway(DATABASE_USER_ALIAS_NAME);
+    return dbUserAliasValue != null ? new String(dbUserAliasValue) : 
DerbyDBTokenStateService.DEFAULT_TOKEN_DB_USER_NAME;
+  }
+
+  @Override
+  public void stop() throws ServiceLifecycleException {
+    try {
+      if (derbyDatabase != null) {
+        derbyDatabase.shutdown();
+      }
+    } catch (Exception e) {
+      throw new ServiceLifecycleException("Error while shutting down Derby 
Database", e);
+    }
+  }
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TrustedOidcIssuerServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TrustedOidcIssuerServiceFactoryTest.java
new file mode 100644
index 000000000..ff06f7825
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TrustedOidcIssuerServiceFactoryTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.knox.gateway.config.impl.GatewayConfigImpl;
+import org.apache.knox.gateway.database.DatabaseType;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.knoxidf.trustedoidcissuer.DerbyDBTrustedOidcIssuerService;
+import 
org.apache.knox.gateway.services.knoxidf.trustedoidcissuer.EmptyTrustedOidcIssuerService;
+import 
org.apache.knox.gateway.services.knoxidf.trustedoidcissuer.JdbcTrustedOidcIssuerService;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.gateway.services.topology.TopologyService;
+import org.apache.knox.gateway.topology.Topology;
+import org.apache.knox.test.TestUtils;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Test;
+
+public class TrustedOidcIssuerServiceFactoryTest {
+
+  private final TrustedOidcIssuerServiceFactory serviceFactory = new 
TrustedOidcIssuerServiceFactory();
+  private final Map<String, String> options = new HashMap<>();
+  private File tempDir;
+  private Service createdService;
+
+  @After
+  public void tearDown() throws Exception {
+    if (createdService != null) {
+      createdService.stop();
+    }
+    if (tempDir != null) {
+      FileUtils.forceDelete(tempDir);
+    }
+  }
+
+  // ------------------------------------------------------------------
+  // Auto-implementation selection
+  // ------------------------------------------------------------------
+
+  @Test
+  public void shouldChooseDerbyWhenNoDatabaseConfigured() {
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    EasyMock.expect(config.getDatabaseType()).andReturn("none").anyTimes();
+    EasyMock.replay(config);
+    assertEquals(DerbyDBTrustedOidcIssuerService.class.getName(), 
serviceFactory.chooseAutoImplementation(config));
+  }
+
+  @Test
+  public void shouldChooseDerbyWhenDatabaseTypeIsDerby() {
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    
EasyMock.expect(config.getDatabaseType()).andReturn(DatabaseType.DERBY.type()).anyTimes();
+    EasyMock.replay(config);
+    assertEquals(DerbyDBTrustedOidcIssuerService.class.getName(), 
serviceFactory.chooseAutoImplementation(config));
+  }
+
+  @Test
+  public void shouldChooseJdbcWhenExternalDatabaseConfigured() {
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    
EasyMock.expect(config.getDatabaseType()).andReturn(DatabaseType.POSTGRESQL.type()).anyTimes();
+    EasyMock.replay(config);
+    assertEquals(JdbcTrustedOidcIssuerService.class.getName(), 
serviceFactory.chooseAutoImplementation(config));
+  }
+
+  // ------------------------------------------------------------------
+  // Empty (no KNOXIDF) cases
+  // ------------------------------------------------------------------
+
+  /** Zero topologies → KnoxIDF not deployed → Empty. */
+  @Test
+  public void shouldSelectEmptyWhenNoTopologies() throws Exception {
+    final GatewayServices gws = servicesWithTopology(/* no topologies */);
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    EasyMock.replay(config);
+    createdService = serviceFactory.create(gws, 
ServiceType.TRUSTED_OIDC_ISSUER_SERVICE, config, options, "");
+    assertTrue(createdService instanceof EmptyTrustedOidcIssuerService);
+  }
+
+  /** Topologies exist but none contain KNOXIDF or KNOXIDF_ADMIN → Empty. */
+  @Test
+  public void shouldSelectEmptyWhenNoKnoxIdfRole() throws Exception {
+    final GatewayServices gws = 
servicesWithTopology(topologyWithRole("KNOXSSO"));
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    EasyMock.replay(config);
+    createdService = serviceFactory.create(gws, 
ServiceType.TRUSTED_OIDC_ISSUER_SERVICE, config, options, "");
+    assertTrue(createdService instanceof EmptyTrustedOidcIssuerService);
+  }
+
+  /** An explicit Empty implementation is honored even when KnoxIDF is 
deployed. */
+  @Test
+  public void shouldHonorExplicitEmptyImplEvenWhenKnoxIdfIsDeployed() throws 
Exception {
+    final GatewayServices gws = 
servicesWithTopology(topologyWithRole("KNOXIDF"));
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    EasyMock.replay(config);
+    createdService = serviceFactory.create(gws, 
ServiceType.TRUSTED_OIDC_ISSUER_SERVICE, config, options,
+        EmptyTrustedOidcIssuerService.class.getName());
+    assertTrue(createdService instanceof EmptyTrustedOidcIssuerService);
+  }
+
+  // ------------------------------------------------------------------
+  // Derby auto-provisioning
+  // ------------------------------------------------------------------
+
+  @Test
+  public void 
shouldAutoSelectDerbyServiceWhenKnoxIdfDeployedWithoutExternalDatabase() throws 
Exception {
+    tempDir = TestUtils.createTempDir(this.getClass().getName());
+    final MasterService masterService = 
EasyMock.createNiceMock(MasterService.class);
+    
EasyMock.expect(masterService.getMasterSecret()).andReturn("M4st3RSecret!".toCharArray()).anyTimes();
+    EasyMock.replay(masterService);
+    final AliasService aliasService = 
EasyMock.createNiceMock(AliasService.class);
+    EasyMock.replay(aliasService);
+
+    final TopologyService topologyService = 
EasyMock.createNiceMock(TopologyService.class);
+    
EasyMock.expect(topologyService.getTopologies()).andReturn(Collections.singletonList(topologyWithRole("KNOXIDF"))).anyTimes();
+    EasyMock.replay(topologyService);
+    final GatewayServices gws = EasyMock.createNiceMock(GatewayServices.class);
+    
EasyMock.expect(gws.getService(ServiceType.TOPOLOGY_SERVICE)).andReturn(topologyService).anyTimes();
+    
EasyMock.expect(gws.getService(ServiceType.ALIAS_SERVICE)).andReturn(aliasService).anyTimes();
+    
EasyMock.expect(gws.getService(ServiceType.MASTER_SERVICE)).andReturn(masterService).anyTimes();
+    EasyMock.replay(gws);
+
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    
EasyMock.expect(config.getDatabaseType()).andReturn(DatabaseType.DERBY.type()).anyTimes();
+    
EasyMock.expect(config.getGatewaySecurityDir()).andReturn(tempDir.getAbsolutePath()).anyTimes();
+    
EasyMock.expect(config.getDatabaseName()).andReturn(Paths.get(tempDir.getAbsolutePath(),
 "tokens").toString()).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerMaxTrustedIssuers()).andReturn(10).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerDiscoveryCacheTtlSecs()).andReturn(300).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerDiscoveryConnectTimeoutMs()).andReturn(2000).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerDiscoveryReadTimeoutMs()).andReturn(2000).anyTimes();
+    EasyMock.replay(config);
+
+    createdService = serviceFactory.create(gws, 
ServiceType.TRUSTED_OIDC_ISSUER_SERVICE, config, options, "");
+    assertNotNull(createdService);
+    assertTrue("Expected a self-provisioning Derby-backed trusted OIDC issuer 
service, got "
+        + createdService.getClass().getName(), createdService instanceof 
DerbyDBTrustedOidcIssuerService);
+  }
+
+  // ------------------------------------------------------------------
+  // Helpers
+  // ------------------------------------------------------------------
+
+  private Topology topologyWithRole(String role) {
+    final Topology topology = new Topology();
+    topology.setName("topology-" + role);
+    final org.apache.knox.gateway.topology.Service service = new 
org.apache.knox.gateway.topology.Service();
+    service.setRole(role);
+    topology.addService(service);
+    return topology;
+  }
+
+  private GatewayServices servicesWithTopology(Topology... topologies) {
+    final TopologyService topologyService = 
EasyMock.createNiceMock(TopologyService.class);
+    
EasyMock.expect(topologyService.getTopologies()).andReturn(Arrays.asList(topologies)).anyTimes();
+    EasyMock.replay(topologyService);
+    final GatewayServices gws = EasyMock.createNiceMock(GatewayServices.class);
+    
EasyMock.expect(gws.getService(ServiceType.TOPOLOGY_SERVICE)).andReturn(topologyService).anyTimes();
+    EasyMock.replay(gws);
+    return gws;
+  }
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/federation/DerbyDBFederatedIdentityServiceTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/federation/DerbyDBFederatedIdentityServiceTest.java
index 267dd28a1..2aed54885 100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/federation/DerbyDBFederatedIdentityServiceTest.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/federation/DerbyDBFederatedIdentityServiceTest.java
@@ -105,4 +105,46 @@ public class DerbyDBFederatedIdentityServiceTest {
         "KEYCLOAK", "https://issuer.example.com/realms/knox";, 
"no-such-subject");
     assertFalse("Did not expect an identity for an unknown subject", 
missing.isPresent());
   }
+
+  /**
+   * Regression guard for the "Table/View 'FEDERATED_IDENTITY' already exists" 
failure on restart:
+   * re-initialising against the same on-disk Derby database (as happens on a 
Knox restart) must not
+   * try to re-create the already-present tables. Before the {@code 
JDBCUtils.tableExists} casing
+   * fix, the lowercase {@code federated_identity} table name never matched 
Derby's uppercased
+   * metadata, so init re-ran the CREATE and blew up on the second boot.
+   */
+  @Test
+  public void shouldReinitializeWithoutErrorWhenTablesAlreadyExist() throws 
Exception {
+    service = newDerbyService();
+    final FederatedIdentity identity = new FederatedIdentity("knox-user-1", 
"KEYCLOAK", "external-subject-1",
+        "https://issuer.example.com/realms/knox";, Instant.now(), new 
HashMap<>());
+    service.addFederatedIdentity(identity);
+    service.stop();
+
+    // Simulate a restart: a brand-new service instance pointing at the same 
Derby folder.
+    service = newDerbyService();
+    final Optional<FederatedIdentity> byId = 
service.findById(identity.getId());
+    assertTrue("Expected the previously-persisted identity to survive a 
restart", byId.isPresent());
+  }
+
+  private DerbyDBFederatedIdentityService newDerbyService() throws Exception {
+    final MasterService masterService = 
EasyMock.createNiceMock(MasterService.class);
+    
EasyMock.expect(masterService.getMasterSecret()).andReturn("M4st3RSecret!".toCharArray()).anyTimes();
+    EasyMock.replay(masterService);
+
+    final AliasService aliasService = 
EasyMock.createNiceMock(AliasService.class);
+    EasyMock.replay(aliasService);
+
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    
EasyMock.expect(config.getGatewaySecurityDir()).andReturn(securityDir.getAbsolutePath()).anyTimes();
+    
EasyMock.expect(config.getDatabaseType()).andReturn(DatabaseType.DERBY.type()).anyTimes();
+    
EasyMock.expect(config.getDatabaseName()).andReturn(Paths.get(securityDir.getAbsolutePath(),
 "tokens").toString()).anyTimes();
+    EasyMock.replay(config);
+
+    final DerbyDBFederatedIdentityService svc = new 
DerbyDBFederatedIdentityService();
+    svc.setAliasService(aliasService);
+    svc.setMasterService(masterService);
+    svc.init(config, Collections.emptyMap());
+    return svc;
+  }
 }
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/DerbyDBTrustedOidcIssuerServiceTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/DerbyDBTrustedOidcIssuerServiceTest.java
new file mode 100644
index 000000000..f2bc4f081
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/DerbyDBTrustedOidcIssuerServiceTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.knox.gateway.services.knoxidf.trustedoidcissuer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.time.Instant;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.knox.gateway.config.impl.GatewayConfigImpl;
+import org.apache.knox.gateway.database.DatabaseType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.test.TestUtils;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Verifies that {@link DerbyDBTrustedOidcIssuerService} self-provisions an 
embedded Derby database
+ * and round-trips a trusted OIDC issuer through it.
+ */
+public class DerbyDBTrustedOidcIssuerServiceTest {
+
+  private File securityDir;
+  private DerbyDBTrustedOidcIssuerService service;
+
+  @Before
+  public void setUp() throws IOException {
+    securityDir = TestUtils.createTempDir(this.getClass().getName());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (service != null) {
+      service.stop();
+    }
+    if (securityDir != null) {
+      FileUtils.forceDelete(securityDir);
+    }
+  }
+
+  @Test
+  public void shouldRoundTripATrustedIssuerOnEmbeddedDerby() throws Exception {
+    service = newService(newConfig());
+
+    final TrustedOidcIssuer issuer = new TrustedOidcIssuer(
+        "https://issuer.example.com/realms/knox";, true, "clusterA", 
Instant.now(), "admin");
+    service.register(issuer);
+
+    assertTrue("Expected the registered issuer to be trusted", 
service.isTrusted(issuer.getIssuerUrl()));
+    assertTrue("Expected the registered issuer to be dynamic-jwks", 
service.isDynamicJwks(issuer.getIssuerUrl()));
+    assertFalse("Did not expect an unknown issuer to be trusted", 
service.isTrusted("https://unknown.example.com";));
+
+    final List<TrustedOidcIssuer> all = service.list();
+    assertEquals(1, all.size());
+    assertEquals(issuer.getIssuerUrl(), all.get(0).getIssuerUrl());
+
+    service.deregister(issuer.getIssuerUrl());
+    assertFalse("Expected the issuer to be gone after deregister", 
service.isTrusted(issuer.getIssuerUrl()));
+  }
+
+  /**
+   * Regression guard for the "Table/View 'TRUSTED_OIDC_ISSUERS' already 
exists" failure on restart:
+   * re-initialising against the same on-disk Derby database (as happens on a 
Knox restart) must not
+   * try to re-create the already-present table.
+   */
+  @Test
+  public void shouldReinitializeWithoutErrorWhenTableAlreadyExists() throws 
Exception {
+    service = newService(newConfig());
+    final TrustedOidcIssuer issuer = new TrustedOidcIssuer(
+        "https://issuer.example.com/realms/knox";, false, null, Instant.now(), 
"admin");
+    service.register(issuer);
+    service.stop();
+
+    // Simulate a restart: a brand-new service instance pointing at the same 
Derby folder.
+    service = newService(newConfig());
+    assertTrue("Expected the previously-registered issuer to survive a 
restart",
+        service.isTrusted(issuer.getIssuerUrl()));
+  }
+
+  private DerbyDBTrustedOidcIssuerService newService(GatewayConfigImpl config) 
throws Exception {
+    final MasterService masterService = 
EasyMock.createNiceMock(MasterService.class);
+    
EasyMock.expect(masterService.getMasterSecret()).andReturn("M4st3RSecret!".toCharArray()).anyTimes();
+    EasyMock.replay(masterService);
+
+    final AliasService aliasService = 
EasyMock.createNiceMock(AliasService.class);
+    EasyMock.replay(aliasService);
+
+    final DerbyDBTrustedOidcIssuerService svc = new 
DerbyDBTrustedOidcIssuerService();
+    svc.setAliasService(aliasService);
+    svc.setMasterService(masterService);
+    svc.init(config, Collections.emptyMap());
+    return svc;
+  }
+
+  private GatewayConfigImpl newConfig() {
+    final GatewayConfigImpl config = 
EasyMock.createNiceMock(GatewayConfigImpl.class);
+    
EasyMock.expect(config.getGatewaySecurityDir()).andReturn(securityDir.getAbsolutePath()).anyTimes();
+    
EasyMock.expect(config.getDatabaseType()).andReturn(DatabaseType.DERBY.type()).anyTimes();
+    
EasyMock.expect(config.getDatabaseName()).andReturn(Paths.get(securityDir.getAbsolutePath(),
 "tokens").toString()).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerMaxTrustedIssuers()).andReturn(10).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerDiscoveryCacheTtlSecs()).andReturn(300).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerDiscoveryConnectTimeoutMs()).andReturn(2000).anyTimes();
+    
EasyMock.expect(config.getTrustedOidcIssuerDiscoveryReadTimeoutMs()).andReturn(2000).anyTimes();
+    EasyMock.replay(config);
+    return config;
+  }
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/TrustedOidcIssuerServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/TrustedOidcIssuerServiceFactoryTest.java
deleted file mode 100644
index be885e1ef..000000000
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/knoxidf/trustedoidcissuer/TrustedOidcIssuerServiceFactoryTest.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.knox.gateway.services.knoxidf.trustedoidcissuer;
-
-import org.apache.knox.gateway.config.GatewayConfig;
-import org.apache.knox.gateway.config.impl.GatewayConfigImpl;
-import org.apache.knox.gateway.database.AbstractDataSourceFactory;
-import org.apache.knox.gateway.database.DatabaseType;
-import org.apache.knox.gateway.services.GatewayServices;
-import org.apache.knox.gateway.services.ServiceType;
-import 
org.apache.knox.gateway.services.factory.TrustedOidcIssuerServiceFactory;
-import org.apache.knox.gateway.services.security.AliasService;
-import org.apache.knox.gateway.services.topology.TopologyService;
-import org.apache.knox.gateway.topology.Topology;
-import org.easymock.EasyMock;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Map;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class TrustedOidcIssuerServiceFactoryTest {
-
-  private static final String DB_NAME = "trustedissuers_factory_test";
-  private static final String DERBY_CREATE_URL = "jdbc:derby:memory:" + 
DB_NAME + ";create=true";
-  private static final String DERBY_SHUTDOWN_URL = "jdbc:derby:memory:" + 
DB_NAME + ";shutdown=true";
-
-  @BeforeClass
-  public static void setUpClass() throws SQLException {
-    // Derby 10.14 does not recognize locales like en_001; force a standard 
locale.
-    java.util.Locale.setDefault(java.util.Locale.US);
-    DriverManager.getConnection(DERBY_CREATE_URL).close();
-  }
-
-  @AfterClass
-  public static void tearDownClass() {
-    try {
-      DriverManager.getConnection(DERBY_SHUTDOWN_URL);
-    } catch (SQLException e) {
-      if (!(e.getErrorCode() == 45000 && "08006".equals(e.getSQLState()))) {
-        throw new RuntimeException("Unexpected Derby shutdown error", e);
-      }
-    }
-  }
-
-  // ------------------------------------------------------------------
-  // Empty (no KNOXIDF) cases
-  // ------------------------------------------------------------------
-
-  /** Zero topologies → no topology service returns anything → Empty. */
-  @Test
-  public void testNoTopologiesReturnsEmpty() throws Exception {
-    assertIsEmpty(createFactory(), buildEmptyGatewayServices(), emptyConfig());
-  }
-
-  /** Topologies exist but none contain KNOXIDF or KNOXIDF_ADMIN → Empty. */
-  @Test
-  public void testTopologiesWithNonKnoxIdfRolesReturnsEmpty() throws Exception 
{
-    final GatewayServices gws = 
buildGatewayServicesWithTopology(withRoles("HDFS", "WEBHDFS"), null);
-    assertIsEmpty(createFactory(), gws, emptyConfig());
-  }
-
-  /** TopologyService is null (not yet registered) → Empty, no NPE. */
-  @Test
-  public void testNullTopologyServiceReturnsEmpty() throws Exception {
-    final GatewayServices gws = EasyMock.createNiceMock(GatewayServices.class);
-    
EasyMock.expect(gws.getService(ServiceType.TOPOLOGY_SERVICE)).andReturn(null).anyTimes();
-    EasyMock.replay(gws);
-    assertIsEmpty(createFactory(), gws, emptyConfig());
-  }
-
-  // ------------------------------------------------------------------
-  // JDBC cases
-  // ------------------------------------------------------------------
-
-  /** A single KNOXIDF topology → JDBC. */
-  @Test
-  public void testKnoxIdfTopologyReturnsJdbc() throws Exception {
-    final GatewayServices gws = 
buildGatewayServicesWithTopology(withRoles("KNOXIDF"), derbyAlias());
-    assertIsJdbc(createFactory(), gws, derbyConfig());
-  }
-
-  /** A single KNOXIDF_ADMIN-only topology (no KNOXIDF) → JDBC. */
-  @Test
-  public void testKnoxIdfAdminOnlyTopologyReturnsJdbc() throws Exception {
-    final GatewayServices gws = 
buildGatewayServicesWithTopology(withRoles("KNOXIDF_ADMIN"), derbyAlias());
-    assertIsJdbc(createFactory(), gws, derbyConfig());
-  }
-
-  /** Both KNOXIDF and KNOXIDF_ADMIN in the same topology → JDBC. */
-  @Test
-  public void testBothRolesInSameTopologyReturnsJdbc() throws Exception {
-    final GatewayServices gws = buildGatewayServicesWithTopology(
-        withRoles("KNOXIDF", "KNOXIDF_ADMIN"), derbyAlias());
-    assertIsJdbc(createFactory(), gws, derbyConfig());
-  }
-
-  /** Multiple topologies; only the second has KNOXIDF → JDBC (verifies the 
loop continues). */
-  @Test
-  public void testMultipleTopologiesOneHasKnoxIdfReturnsJdbc() throws 
Exception {
-    final AliasService alias = derbyAlias();
-    final GatewayServices gws = buildGatewayServicesWithMultipleTopologies(
-        withRoles("HDFS", "WEBHDFS"), withRoles("KNOXIDF"), alias);
-    assertIsJdbc(createFactory(), gws, derbyConfig());
-  }
-
-  // ------------------------------------------------------------------
-  // Error handling
-  // ------------------------------------------------------------------
-
-  /**
-   * When JDBC service initialization fails (e.g. bad DB type), the factory 
must fall back
-   * to EmptyTrustedOidcIssuerService rather than propagating the exception.
-   */
-  @Test
-  public void testJdbcInitFailureFallsBackToEmpty() throws Exception {
-    final GatewayServices gws = 
buildGatewayServicesWithTopology(withRoles("KNOXIDF"), derbyAlias());
-
-    final GatewayConfig brokenConfig = 
EasyMock.createNiceMock(GatewayConfig.class);
-    
EasyMock.expect(brokenConfig.getDatabaseType()).andReturn("invalid_db_type").anyTimes();
-    EasyMock.expect(brokenConfig.getServiceParameter(EasyMock.anyString(), 
EasyMock.anyString()))
-        .andReturn("").anyTimes();
-    EasyMock.replay(brokenConfig);
-
-    assertIsEmpty(createFactory(), gws, brokenConfig);
-  }
-
-  // ------------------------------------------------------------------
-  // Helpers
-  // ------------------------------------------------------------------
-
-  private static TrustedOidcIssuerServiceFactory createFactory() {
-    return new TrustedOidcIssuerServiceFactory();
-  }
-
-  private static void assertIsEmpty(TrustedOidcIssuerServiceFactory factory,
-      GatewayServices gws, GatewayConfig config) throws Exception {
-    final org.apache.knox.gateway.services.Service result =
-        factory.create(gws, ServiceType.TRUSTED_OIDC_ISSUER_SERVICE, config, 
Map.of());
-    assertNotNull(result);
-    assertTrue("Expected EmptyTrustedOidcIssuerService but got " + 
result.getClass().getSimpleName(),
-        result instanceof EmptyTrustedOidcIssuerService);
-  }
-
-  private static void assertIsJdbc(TrustedOidcIssuerServiceFactory factory,
-      GatewayServices gws, GatewayConfig config) throws Exception {
-    final org.apache.knox.gateway.services.Service result =
-        factory.create(gws, ServiceType.TRUSTED_OIDC_ISSUER_SERVICE, config, 
Map.of());
-    assertNotNull(result);
-    assertTrue("Expected JdbcTrustedOidcIssuerService but got " + 
result.getClass().getSimpleName(),
-        result instanceof JdbcTrustedOidcIssuerService);
-  }
-
-  /** GatewayServices with a TopologyService returning no topologies; no 
AliasService needed. */
-  private static GatewayServices buildEmptyGatewayServices() {
-    final TopologyService topologyService = 
EasyMock.createNiceMock(TopologyService.class);
-    
EasyMock.expect(topologyService.getTopologies()).andReturn(Collections.emptyList()).anyTimes();
-    EasyMock.replay(topologyService);
-
-    final GatewayServices gws = EasyMock.createNiceMock(GatewayServices.class);
-    EasyMock.expect(gws.getService(ServiceType.TOPOLOGY_SERVICE))
-        .andReturn(topologyService).anyTimes();
-    EasyMock.replay(gws);
-    return gws;
-  }
-
-  /**
-   * Builds a {@link GatewayServices} mock with one topology that has the 
given service roles.
-   * {@code alias} may be null when no JDBC init will be attempted.
-   */
-  private static GatewayServices buildGatewayServicesWithTopology(
-      String[] roles, AliasService alias) throws Exception {
-    final Topology topology = topologyWithRoles(roles);
-    return buildGatewayServices(Collections.singletonList(topology), alias);
-  }
-
-  private static GatewayServices buildGatewayServicesWithMultipleTopologies(
-      String[] roles1, String[] roles2, AliasService alias) throws Exception {
-    return buildGatewayServices(
-        Arrays.asList(topologyWithRoles(roles1), topologyWithRoles(roles2)), 
alias);
-  }
-
-  private static GatewayServices buildGatewayServices(
-      java.util.List<Topology> topologies, AliasService alias) throws 
Exception {
-    final TopologyService topologyService = 
EasyMock.createNiceMock(TopologyService.class);
-    
EasyMock.expect(topologyService.getTopologies()).andReturn(topologies).anyTimes();
-    EasyMock.replay(topologyService);
-
-    final GatewayServices gws = EasyMock.createNiceMock(GatewayServices.class);
-    EasyMock.expect(gws.getService(ServiceType.TOPOLOGY_SERVICE))
-        .andReturn(topologyService).anyTimes();
-    if (alias != null) {
-      EasyMock.expect(gws.getService(ServiceType.ALIAS_SERVICE))
-          .andReturn(alias).anyTimes();
-    }
-    EasyMock.replay(gws);
-    return gws;
-  }
-
-  private static Topology topologyWithRoles(String... roles) {
-    final Topology topology = EasyMock.createNiceMock(Topology.class);
-    final java.util.List<org.apache.knox.gateway.topology.Service> services = 
new java.util.ArrayList<>();
-    for (String role : roles) {
-      final org.apache.knox.gateway.topology.Service svc =
-          
EasyMock.createNiceMock(org.apache.knox.gateway.topology.Service.class);
-      EasyMock.expect(svc.getRole()).andReturn(role).anyTimes();
-      EasyMock.replay(svc);
-      services.add(svc);
-    }
-    EasyMock.expect(topology.getServices()).andReturn(services).anyTimes();
-    EasyMock.replay(topology);
-    return topology;
-  }
-
-  private static String[] withRoles(String... roles) {
-    return roles;
-  }
-
-  private static AliasService derbyAlias() throws Exception {
-    final AliasService alias = EasyMock.createNiceMock(AliasService.class);
-    EasyMock.expect(alias.getPasswordFromAliasForGateway(
-        
AbstractDataSourceFactory.DATABASE_USER_ALIAS_NAME)).andReturn(null).anyTimes();
-    EasyMock.expect(alias.getPasswordFromAliasForGateway(
-        
AbstractDataSourceFactory.DATABASE_PASSWORD_ALIAS_NAME)).andReturn(null).anyTimes();
-    EasyMock.replay(alias);
-    return alias;
-  }
-
-  private static GatewayConfig derbyConfig() {
-    final GatewayConfigImpl config = new GatewayConfigImpl();
-    config.set(GatewayConfigImpl.GATEWAY_DATABASE_TYPE, 
DatabaseType.DERBY.type());
-    config.set(GatewayConfigImpl.GATEWAY_DATABASE_NAME, "memory:" + DB_NAME);
-    return config;
-  }
-
-  /** Config mock that returns empty string for getServiceParameter (required 
for impl detection). */
-  private static GatewayConfig emptyConfig() {
-    final GatewayConfig config = EasyMock.createNiceMock(GatewayConfig.class);
-    EasyMock.expect(config.getServiceParameter(EasyMock.anyString(), 
EasyMock.anyString()))
-        .andReturn("").anyTimes();
-    EasyMock.replay(config);
-    return config;
-  }
-}

Reply via email to