This is an automated email from the ASF dual-hosted git repository.
capistrant pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 3de483f19ce Convert auth ITs to embedded tests (#18706)
3de483f19ce is described below
commit 3de483f19ce0528c27cb787aacb173d08f2f7853
Author: Kashif Faraz <[email protected]>
AuthorDate: Wed Nov 5 00:55:37 2025 +0530
Convert auth ITs to embedded tests (#18706)
* Move and fix up basic auth test
* Fix up LDAP auth test
* Clean up the methods
* Remove MSQ extensions as they are always loaded
* Fix dependencies
* Remove unused files
* Remove mentions of test group of ldap-security
* Try to bump docker-java-bom version to 3.6.0
* Fix licenses
---
.github/workflows/cron-job-its.yml | 2 +-
.github/workflows/standard-its.yml | 2 +-
embedded-tests/pom.xml | 21 +
.../auth}/AbstractAuthConfigurationTest.java | 462 ++++++++++-----------
.../embedded/auth/BasicAuthConfigurationTest.java | 70 +---
.../auth/BasicAuthLdapConfigurationTest.java | 95 ++---
.../druid/testing/embedded/auth}/HttpUtil.java | 54 +--
.../testing/embedded/auth/LdapAuthResource.java | 110 +++++
.../src/test/resources/ldap-configs/bootstrap.ldif | 174 ++++++++
integration-tests/docker/druid.sh | 2 +-
.../docker/test-data/ldap-security-sample-data.sql | 17 -
.../docker/test-data/security-sample-data.sql | 17 -
integration-tests/pom.xml | 5 -
integration-tests/script/docker_compose_args.sh | 6 +-
.../java/org/apache/druid/tests/TestNGGroup.java | 5 -
licenses.yaml | 2 +-
pom.xml | 2 +-
.../testing/embedded/EmbeddedDruidServer.java | 10 +-
.../druid/testing/embedded/EmbeddedHistorical.java | 10 +-
19 files changed, 619 insertions(+), 447 deletions(-)
diff --git a/.github/workflows/cron-job-its.yml
b/.github/workflows/cron-job-its.yml
index 2a6917c28e0..d13ae4c6ad6 100644
--- a/.github/workflows/cron-job-its.yml
+++ b/.github/workflows/cron-job-its.yml
@@ -60,7 +60,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- testing_group: [kafka-index, kafka-index-slow,
kafka-transactional-index, kafka-transactional-index-slow, kafka-data-format,
ldap-security, realtime-index, append-ingestion]
+ testing_group: [kafka-index, kafka-index-slow,
kafka-transactional-index, kafka-transactional-index-slow, kafka-data-format,
realtime-index, append-ingestion]
uses: ./.github/workflows/reusable-standard-its.yml
needs: build
with:
diff --git a/.github/workflows/standard-its.yml
b/.github/workflows/standard-its.yml
index e31c8f2b494..16e57e60aa6 100644
--- a/.github/workflows/standard-its.yml
+++ b/.github/workflows/standard-its.yml
@@ -47,7 +47,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- testing_group: [kafka-index, kafka-index-slow,
kafka-transactional-index, kafka-transactional-index-slow, ldap-security,
realtime-index, append-ingestion, cds-task-schema-publish-disabled,
cds-coordinator-metadata-query-disabled]
+ testing_group: [kafka-index, kafka-index-slow,
kafka-transactional-index, kafka-transactional-index-slow, realtime-index,
append-ingestion, cds-task-schema-publish-disabled,
cds-coordinator-metadata-query-disabled]
uses: ./.github/workflows/reusable-standard-its.yml
if: ${{ needs.changes.outputs.core == 'true' ||
needs.changes.outputs.common-extensions == 'true' }}
with:
diff --git a/embedded-tests/pom.xml b/embedded-tests/pom.xml
index 9da02c364d6..9a3fbd90765 100644
--- a/embedded-tests/pom.xml
+++ b/embedded-tests/pom.xml
@@ -322,6 +322,11 @@
<version>${scala.library.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
@@ -526,6 +531,22 @@
<version>19.0.0</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents.client5</groupId>
+ <artifactId>httpclient5</artifactId>
+ <version>5.5</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
diff --git
a/integration-tests/src/test/java/org/apache/druid/tests/security/AbstractAuthConfigurationTest.java
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/AbstractAuthConfigurationTest.java
similarity index 67%
rename from
integration-tests/src/test/java/org/apache/druid/tests/security/AbstractAuthConfigurationTest.java
rename to
embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/AbstractAuthConfigurationTest.java
index 53803b09813..429c4e31559 100644
---
a/integration-tests/src/test/java/org/apache/druid/tests/security/AbstractAuthConfigurationTest.java
+++
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/AbstractAuthConfigurationTest.java
@@ -17,21 +17,19 @@
* under the License.
*/
-package org.apache.druid.tests.security;
+package org.apache.druid.testing.embedded.auth;
-import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
-import com.google.inject.Inject;
import org.apache.calcite.avatica.AvaticaSqlException;
-import org.apache.druid.guice.annotations.Client;
-import org.apache.druid.guice.annotations.ExtensionPoint;
+import org.apache.druid.common.utils.IdUtils;
+import org.apache.druid.indexing.common.task.Task;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.jackson.JacksonUtils;
-import org.apache.druid.java.util.common.logger.Logger;
import org.apache.druid.java.util.http.client.CredentialedHttpClient;
import org.apache.druid.java.util.http.client.HttpClient;
import org.apache.druid.java.util.http.client.auth.BasicCredentials;
@@ -39,25 +37,32 @@ import
org.apache.druid.java.util.http.client.response.StatusResponseHolder;
import org.apache.druid.msq.dart.controller.sql.DartSqlEngine;
import org.apache.druid.query.QueryContexts;
import org.apache.druid.query.http.SqlTaskStatus;
+import org.apache.druid.segment.TestHelper;
+import org.apache.druid.server.DruidNode;
import org.apache.druid.server.security.Access;
import org.apache.druid.server.security.Action;
import org.apache.druid.server.security.Resource;
import org.apache.druid.server.security.ResourceAction;
import org.apache.druid.server.security.ResourceType;
import org.apache.druid.sql.avatica.DruidAvaticaJsonHandler;
-import org.apache.druid.testing.clients.CoordinatorResourceTestClient;
-import org.apache.druid.testing.tools.IntegrationTestingConfig;
-import org.apache.druid.testing.utils.HttpUtil;
-import org.apache.druid.testing.utils.MsqTestQueryHelper;
-import org.apache.druid.testing.utils.TestQueryHelper;
-import org.apache.druid.tests.indexer.AbstractIndexerTest;
+import org.apache.druid.testing.embedded.EmbeddedBroker;
+import org.apache.druid.testing.embedded.EmbeddedCoordinator;
+import org.apache.druid.testing.embedded.EmbeddedDruidCluster;
+import org.apache.druid.testing.embedded.EmbeddedDruidServer;
+import org.apache.druid.testing.embedded.EmbeddedHistorical;
+import org.apache.druid.testing.embedded.EmbeddedIndexer;
+import org.apache.druid.testing.embedded.EmbeddedOverlord;
+import org.apache.druid.testing.embedded.EmbeddedResource;
+import org.apache.druid.testing.embedded.EmbeddedRouter;
+import org.apache.druid.testing.embedded.indexing.MoreResources;
+import org.apache.druid.testing.embedded.junit5.EmbeddedClusterTestBase;
+import org.apache.druid.timeline.DataSegment;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
-import org.testng.Assert;
-import org.testng.annotations.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
@@ -67,37 +72,25 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.stream.Collectors;
+import java.util.Set;
-@ExtensionPoint
-public abstract class AbstractAuthConfigurationTest
+public abstract class AbstractAuthConfigurationTest extends
EmbeddedClusterTestBase
{
- private static final Logger LOG = new
Logger(AbstractAuthConfigurationTest.class);
protected static final String INVALID_NAME = "invalid%2Fname";
- protected static final String SYSTEM_SCHEMA_SEGMENTS_RESULTS_RESOURCE =
- "/results/auth_test_sys_schema_segments.json";
- protected static final String SYSTEM_SCHEMA_SERVER_SEGMENTS_RESULTS_RESOURCE
=
- "/results/auth_test_sys_schema_server_segments.json";
- protected static final String SYSTEM_SCHEMA_SERVERS_RESULTS_RESOURCE =
- "/results/auth_test_sys_schema_servers.json";
- protected static final String SYSTEM_SCHEMA_TASKS_RESULTS_RESOURCE =
- "/results/auth_test_sys_schema_tasks.json";
-
protected static final String SYS_SCHEMA_SEGMENTS_QUERY =
- "SELECT * FROM sys.segments WHERE datasource IN ('auth_test')";
+ "SELECT segment_id, num_rows, size FROM sys.segments WHERE datasource =
'auth_test'";
protected static final String SYS_SCHEMA_SERVERS_QUERY =
- "SELECT * FROM sys.servers WHERE tier IS NOT NULL";
+ "SELECT server, host, plaintext_port, tls_port, server_type, tier,
curr_size, max_size, is_leader"
+ + " FROM sys.servers WHERE tier IS NOT NULL";
protected static final String SYS_SCHEMA_SERVER_SEGMENTS_QUERY =
"SELECT * FROM sys.server_segments WHERE segment_id LIKE 'auth_test%'";
protected static final String SYS_SCHEMA_TASKS_QUERY =
- "SELECT * FROM sys.tasks WHERE datasource IN ('auth_test')";
-
- protected static final TypeReference<List<Map<String, Object>>>
SYS_SCHEMA_RESULTS_TYPE_REFERENCE =
- new TypeReference<>() {};
+ "SELECT task_id, group_id, type, datasource, status, location"
+ + " FROM sys.tasks WHERE datasource IN ('auth_test')";
/**
* create a ResourceAction set of permissions that can only read a
'auth_test' datasource, for Authorizer
@@ -218,39 +211,27 @@ public abstract class AbstractAuthConfigurationTest
}
}
- protected List<Map<String, Object>> adminSegments;
- protected List<Map<String, Object>> adminTasks;
- protected List<Map<String, Object>> adminServers;
- protected List<Map<String, Object>> adminServerSegments;
-
- @Inject
- protected IntegrationTestingConfig config;
+ protected String adminSegments;
+ protected String adminTasks;
+ protected String adminServers;
+ protected String adminServerSegments;
- @Inject
- protected ObjectMapper jsonMapper;
+ protected final ObjectMapper jsonMapper = TestHelper.JSON_MAPPER;
- @Inject
- protected MsqTestQueryHelper msqHelper;
-
- @Inject
- @Client
protected HttpClient httpClient;
-
- @Inject
- protected CoordinatorResourceTestClient coordinatorClient;
-
protected Map<User, HttpClient> httpClients;
- protected abstract void setupDatasourceOnlyUser() throws Exception;
- protected abstract void setupDatasourceAndContextParamsUser() throws
Exception;
- protected abstract void setupDatasourceAndSysTableUser() throws Exception;
- protected abstract void setupDatasourceAndSysAndStateUser() throws Exception;
- protected abstract void setupSysTableAndStateOnlyUser() throws Exception;
- protected abstract void setupTestSpecificHttpClients() throws Exception;
+ protected abstract void setupDatasourceOnlyUser();
+ protected abstract void setupDatasourceAndContextParamsUser();
+ protected abstract void setupDatasourceAndSysTableUser();
+ protected abstract void setupDatasourceAndSysAndStateUser();
+ protected abstract void setupSysTableAndStateOnlyUser();
+ protected abstract void setupTestSpecificHttpClients();
protected abstract String getAuthenticatorName();
protected abstract String getAuthorizerName();
protected abstract String getExpectedAvaticaAuthError();
protected abstract String getExpectedAvaticaAuthzError();
+ protected abstract EmbeddedResource getAuthResource();
/**
* Returns properties for the admin with an invalid password.
@@ -264,37 +245,83 @@ public abstract class AbstractAuthConfigurationTest
* @see User
*/
protected abstract Properties getAvaticaConnectionPropertiesForUser(User
user);
+
+ private final EmbeddedOverlord overlord = new EmbeddedOverlord();
+ private final EmbeddedCoordinator coordinator = new EmbeddedCoordinator();
+ private final EmbeddedRouter router = new EmbeddedRouter();
+ private final EmbeddedBroker broker = new
EmbeddedBroker().setServerMemory(500_000_000);
+ private final EmbeddedHistorical historical = new
EmbeddedHistorical().setServerMemory(500_000_000);
+ private final EmbeddedIndexer indexer = new EmbeddedIndexer()
+ .setServerMemory(300_000_000)
+ .addProperty("druid.worker.capacity", "2");
+
+ @Override
+ protected EmbeddedDruidCluster createCluster()
+ {
+ return EmbeddedDruidCluster
+ .withEmbeddedDerbyAndZookeeper()
+ .useLatchableEmitter()
+ .addResource(getAuthResource())
+ .addCommonProperty("druid.auth.unsecuredPaths",
"[\"/druid/coordinator/v1/loadqueue\"]")
+ .addCommonProperty("druid.auth.authorizeQueryContextParams", "true")
+ .addCommonProperty("druid.msq.dart.enabled", "true")
+ .addCommonProperty("druid.sql.planner.authorizeSystemTablesDirectly",
"true")
+ .addCommonProperty("druid.server.http.allowedHttpMethods",
"[\"OPTIONS\"]")
+ .addServer(coordinator)
+ .addServer(overlord)
+ .addServer(indexer)
+ .addServer(broker)
+ .addServer(historical)
+ .addServer(router);
+ }
+
+ @BeforeAll
+ public void setupDataAndRoles()
+ {
+ httpClient = router.bindings().globalHttpClient();
+
+ // Ingest some data
+ final String dataSource = "auth_test";
+ final String taskId = IdUtils.getRandomId();
+ final Task task = MoreResources.Task.BASIC_INDEX
+ .get()
+ .segmentGranularity("YEAR")
+ .dataSource(dataSource)
+ .withId(taskId);
+
+ cluster.callApi().runTask(task, overlord);
+ cluster.callApi().waitForAllSegmentsToBeAvailable(dataSource, coordinator,
broker);
+
+ setupHttpClientsAndUsers();
+ setExpectedSystemSchemaObjects(dataSource, taskId);
+ }
@Test
- public void test_systemSchemaAccess_admin() throws Exception
+ public void test_systemSchemaAccess_admin()
{
final HttpClient adminClient = getHttpClient(User.ADMIN);
// check that admin access works on all nodes
checkNodeAccess(adminClient);
// as admin
- LOG.info("Checking sys.segments query as admin...");
verifySystemSchemaQuery(
adminClient,
SYS_SCHEMA_SEGMENTS_QUERY,
adminSegments
);
- LOG.info("Checking sys.servers query as admin...");
verifySystemSchemaServerQuery(
adminClient,
SYS_SCHEMA_SERVERS_QUERY,
- getServersWithoutNonConfigurableFields(adminServers)
+ adminServers
);
- LOG.info("Checking sys.server_segments query as admin...");
verifySystemSchemaQuery(
adminClient,
SYS_SCHEMA_SERVER_SEGMENTS_QUERY,
adminServerSegments
);
- LOG.info("Checking sys.tasks query as admin...");
verifySystemSchemaQuery(
adminClient,
SYS_SCHEMA_TASKS_QUERY,
@@ -303,182 +330,146 @@ public abstract class AbstractAuthConfigurationTest
}
@Test
- public void test_systemSchemaAccess_datasourceOnlyUser() throws Exception
+ public void test_systemSchemaAccess_datasourceOnlyUser()
{
final HttpClient datasourceOnlyUserClient =
getHttpClient(User.DATASOURCE_ONLY_USER);
// check that we can access a datasource-permission restricted resource on
the broker
HttpUtil.makeRequest(
datasourceOnlyUserClient,
HttpMethod.GET,
- config.getBrokerUrl() + "/druid/v2/datasources/auth_test",
- null
+ getServerUrl(broker) + "/druid/v2/datasources/auth_test"
);
// as user that can only read auth_test
- LOG.info("Checking sys.segments query as datasourceOnlyUser...");
final String expectedMsg = "{\"Access-Check-Result\":\"" +
Access.DEFAULT_ERROR_MESSAGE + "\"}";
- verifySystemSchemaQueryFailure(
+ verifySystemSchemaQueryIsForbidden(
datasourceOnlyUserClient,
SYS_SCHEMA_SEGMENTS_QUERY,
- HttpResponseStatus.FORBIDDEN,
expectedMsg
);
- LOG.info("Checking sys.servers query as datasourceOnlyUser...");
- verifySystemSchemaQueryFailure(
+ verifySystemSchemaQueryIsForbidden(
datasourceOnlyUserClient,
SYS_SCHEMA_SERVERS_QUERY,
- HttpResponseStatus.FORBIDDEN,
expectedMsg
);
- LOG.info("Checking sys.server_segments query as datasourceOnlyUser...");
- verifySystemSchemaQueryFailure(
+ verifySystemSchemaQueryIsForbidden(
datasourceOnlyUserClient,
SYS_SCHEMA_SERVER_SEGMENTS_QUERY,
- HttpResponseStatus.FORBIDDEN,
expectedMsg
);
- LOG.info("Checking sys.tasks query as datasourceOnlyUser...");
- verifySystemSchemaQueryFailure(
+ verifySystemSchemaQueryIsForbidden(
datasourceOnlyUserClient,
SYS_SCHEMA_TASKS_QUERY,
- HttpResponseStatus.FORBIDDEN,
expectedMsg
);
}
@Test
- public void test_systemSchemaAccess_datasourceAndSysUser() throws Exception
+ public void test_systemSchemaAccess_datasourceAndSysUser()
{
final HttpClient datasourceAndSysUserClient =
getHttpClient(User.DATASOURCE_AND_SYS_USER);
// check that we can access a datasource-permission restricted resource on
the broker
HttpUtil.makeRequest(
datasourceAndSysUserClient,
HttpMethod.GET,
- config.getBrokerUrl() + "/druid/v2/datasources/auth_test",
- null
+ getServerUrl(broker) + "/druid/v2/datasources/auth_test"
);
// as user that can only read auth_test
- LOG.info("Checking sys.segments query as datasourceAndSysUser...");
verifySystemSchemaQuery(
datasourceAndSysUserClient,
SYS_SCHEMA_SEGMENTS_QUERY,
- adminSegments.stream()
- .filter((segmentEntry) ->
"auth_test".equals(segmentEntry.get("datasource")))
- .collect(Collectors.toList())
+ adminSegments
);
- LOG.info("Checking sys.servers query as datasourceAndSysUser...");
- verifySystemSchemaQueryFailure(
+ verifySystemSchemaQueryIsForbidden(
datasourceAndSysUserClient,
SYS_SCHEMA_SERVERS_QUERY,
- HttpResponseStatus.FORBIDDEN,
"{\"Access-Check-Result\":\"Insufficient permission to view servers:
Unauthorized\"}"
);
- LOG.info("Checking sys.server_segments query as datasourceAndSysUser...");
- verifySystemSchemaQueryFailure(
+ verifySystemSchemaQueryIsForbidden(
datasourceAndSysUserClient,
SYS_SCHEMA_SERVER_SEGMENTS_QUERY,
- HttpResponseStatus.FORBIDDEN,
"{\"Access-Check-Result\":\"Insufficient permission to view servers:
Unauthorized\"}"
);
- LOG.info("Checking sys.tasks query as datasourceAndSysUser...");
verifySystemSchemaQuery(
datasourceAndSysUserClient,
SYS_SCHEMA_TASKS_QUERY,
- adminTasks.stream()
- .filter((taskEntry) ->
"auth_test".equals(taskEntry.get("datasource")))
- .collect(Collectors.toList())
+ adminTasks
);
}
@Test
- public void test_systemSchemaAccess_datasourceAndSysWithStateUser() throws
Exception
+ public void test_systemSchemaAccess_datasourceAndSysWithStateUser()
{
final HttpClient datasourceWithStateUserClient =
getHttpClient(User.DATASOURCE_WITH_STATE_USER);
// check that we can access a state-permission restricted resource on the
broker
HttpUtil.makeRequest(
datasourceWithStateUserClient,
HttpMethod.GET,
- config.getBrokerUrl() + "/status",
- null
+ getServerUrl(broker) + "/status"
);
// as user that can read auth_test and STATE
- LOG.info("Checking sys.segments query as datasourceWithStateUser...");
verifySystemSchemaQuery(
datasourceWithStateUserClient,
SYS_SCHEMA_SEGMENTS_QUERY,
- adminSegments.stream()
- .filter((segmentEntry) ->
"auth_test".equals(segmentEntry.get("datasource")))
- .collect(Collectors.toList())
+ adminSegments
);
- LOG.info("Checking sys.servers query as datasourceWithStateUser...");
verifySystemSchemaServerQuery(
datasourceWithStateUserClient,
SYS_SCHEMA_SERVERS_QUERY,
adminServers
);
- LOG.info("Checking sys.server_segments query as
datasourceWithStateUser...");
verifySystemSchemaQuery(
datasourceWithStateUserClient,
SYS_SCHEMA_SERVER_SEGMENTS_QUERY,
- adminServerSegments.stream()
- .filter((serverSegmentEntry) -> ((String)
serverSegmentEntry.get("segment_id")).contains(
- "auth_test"))
- .collect(Collectors.toList())
+ adminServerSegments
);
- LOG.info("Checking sys.tasks query as datasourceWithStateUser...");
verifySystemSchemaQuery(
datasourceWithStateUserClient,
SYS_SCHEMA_TASKS_QUERY,
- adminTasks.stream()
- .filter((taskEntry) ->
"auth_test".equals(taskEntry.get("datasource")))
- .collect(Collectors.toList())
+ adminTasks
);
}
@Test
- public void test_systemSchemaAccess_stateOnlyUser() throws Exception
+ public void test_systemSchemaAccess_stateOnlyUser()
{
final HttpClient stateOnlyUserClient = getHttpClient(User.STATE_ONLY_USER);
- HttpUtil.makeRequest(stateOnlyUserClient, HttpMethod.GET,
config.getBrokerUrl() + "/status", null);
+ HttpUtil.makeRequest(stateOnlyUserClient, HttpMethod.GET,
getServerUrl(broker) + "/status");
// as user that can only read STATE
- LOG.info("Checking sys.segments query as stateOnlyUser...");
verifySystemSchemaQuery(
stateOnlyUserClient,
SYS_SCHEMA_SEGMENTS_QUERY,
- Collections.emptyList()
+ "segment_id,num_rows,size"
);
- LOG.info("Checking sys.servers query as stateOnlyUser...");
verifySystemSchemaServerQuery(
stateOnlyUserClient,
SYS_SCHEMA_SERVERS_QUERY,
adminServers
);
- LOG.info("Checking sys.server_segments query as stateOnlyUser...");
verifySystemSchemaQuery(
stateOnlyUserClient,
SYS_SCHEMA_SERVER_SEGMENTS_QUERY,
- Collections.emptyList()
+ "server,segment_id"
);
- LOG.info("Checking sys.tasks query as stateOnlyUser...");
verifySystemSchemaQuery(
stateOnlyUserClient,
SYS_SCHEMA_TASKS_QUERY,
- Collections.emptyList()
+ "task_id,group_id,type,datasource,status,location"
);
}
@@ -554,7 +545,7 @@ public abstract class AbstractAuthConfigurationTest
}
@Test
- public void test_msqQueryWithContext_datasourceOnlyUser_fail() throws
Exception
+ public void test_msqQueryWithContext_datasourceOnlyUser_fail()
{
final String query = "select count(*) from auth_test";
makeMSQQueryRequest(
@@ -576,11 +567,11 @@ public abstract class AbstractAuthConfigurationTest
HttpResponseStatus.ACCEPTED
);
String taskId = jsonMapper.readValue(responseHolder.getContent(),
SqlTaskStatus.class).getTaskId();
- msqHelper.pollTaskIdForSuccess(taskId);
+ cluster.callApi().waitForTaskToSucceed(taskId, overlord);
}
@Test
- public void test_dartQueryWithContext_datasourceOnlyUser_fail() throws
Exception
+ public void test_dartQueryWithContext_datasourceOnlyUser_fail()
{
final String query = "select count(*) from auth_test";
makeDartQueryRequest(
@@ -592,7 +583,7 @@ public abstract class AbstractAuthConfigurationTest
}
@Test
- public void
test_dartQueryWithContext_datasourceAndContextParamsUser_succeed() throws
Exception
+ public void
test_dartQueryWithContext_datasourceAndContextParamsUser_succeed()
{
final String query = "select count(*) from auth_test";
makeDartQueryRequest(
@@ -604,7 +595,7 @@ public abstract class AbstractAuthConfigurationTest
}
@Test
- public void test_sqlQueryWithContext_datasourceOnlyUser_fail() throws
Exception
+ public void test_sqlQueryWithContext_datasourceOnlyUser_fail()
{
final String query = "select count(*) from auth_test";
makeSQLQueryRequest(
@@ -616,7 +607,7 @@ public abstract class AbstractAuthConfigurationTest
}
@Test
- public void
test_sqlQueryWithContext_datasourceAndContextParamsUser_succeed() throws
Exception
+ public void test_sqlQueryWithContext_datasourceAndContextParamsUser_succeed()
{
final String query = "select count(*) from auth_test";
makeSQLQueryRequest(
@@ -662,7 +653,7 @@ public abstract class AbstractAuthConfigurationTest
return Preconditions.checkNotNull(httpClients.get(user), "http client for
user[%s]", user.getName());
}
- protected void setupHttpClientsAndUsers() throws Exception
+ protected void setupHttpClientsAndUsers()
{
setupHttpClients();
setupDatasourceOnlyUser();
@@ -674,34 +665,34 @@ public abstract class AbstractAuthConfigurationTest
protected void checkNodeAccess(HttpClient httpClient)
{
- HttpUtil.makeRequest(httpClient, HttpMethod.GET,
config.getCoordinatorUrl() + "/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.GET, config.getOverlordUrl() +
"/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.GET, config.getBrokerUrl() +
"/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.GET, config.getHistoricalUrl()
+ "/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.GET, config.getRouterUrl() +
"/status", null);
+ HttpUtil.makeRequest(httpClient, HttpMethod.GET, getServerUrl(coordinator)
+ "/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.GET, getServerUrl(overlord) +
"/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.GET, getServerUrl(broker) +
"/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.GET, getServerUrl(historical)
+ "/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.GET, getServerUrl(router) +
"/status");
}
protected void checkLoadStatus(HttpClient httpClient) throws Exception
{
- checkLoadStatusSingle(httpClient, config.getCoordinatorUrl());
- checkLoadStatusSingle(httpClient, config.getOverlordUrl());
- checkLoadStatusSingle(httpClient, config.getBrokerUrl());
- checkLoadStatusSingle(httpClient, config.getHistoricalUrl());
- checkLoadStatusSingle(httpClient, config.getRouterUrl());
+ checkLoadStatusSingle(httpClient, getServerUrl(coordinator));
+ checkLoadStatusSingle(httpClient, getServerUrl(overlord));
+ checkLoadStatusSingle(httpClient, getServerUrl(broker));
+ checkLoadStatusSingle(httpClient, getServerUrl(historical));
+ checkLoadStatusSingle(httpClient, getServerUrl(router));
}
protected void testOptionsRequests(HttpClient httpClient)
{
- HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS,
config.getCoordinatorUrl() + "/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS,
config.getOverlordUrl() + "/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, config.getBrokerUrl()
+ "/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS,
config.getHistoricalUrl() + "/status", null);
- HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, config.getRouterUrl()
+ "/status", null);
+ HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS,
getServerUrl(coordinator) + "/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS,
getServerUrl(overlord) + "/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, getServerUrl(broker)
+ "/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS,
getServerUrl(historical) + "/status");
+ HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, getServerUrl(router)
+ "/status");
}
protected void checkUnsecuredCoordinatorLoadQueuePath(HttpClient client)
{
- HttpUtil.makeRequest(client, HttpMethod.GET, config.getCoordinatorUrl() +
"/druid/coordinator/v1/loadqueue", null);
+ HttpUtil.makeRequest(client, HttpMethod.GET, getServerUrl(coordinator) +
"/druid/coordinator/v1/loadqueue");
}
private Properties getAvaticaConnectionPropertiesForAdmin()
@@ -711,14 +702,13 @@ public abstract class AbstractAuthConfigurationTest
protected void testAvaticaQuery(Properties connectionProperties, String url)
{
- LOG.info("URL: " + url);
try (
Connection connection = DriverManager.getConnection(url,
connectionProperties);
Statement statement = connection.createStatement()) {
statement.setMaxRows(450);
String query = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS";
ResultSet resultSet = statement.executeQuery(query);
- Assert.assertTrue(resultSet.next());
+ Assertions.assertTrue(resultSet.next());
}
catch (Exception e) {
throw new RuntimeException(e);
@@ -738,7 +728,6 @@ public abstract class AbstractAuthConfigurationTest
protected void testAvaticaAuthFailure(Properties connectionProperties,
String url, String expectedError)
throws Exception
{
- LOG.info("URL: " + url);
try (
Connection connection = DriverManager.getConnection(url,
connectionProperties);
Statement statement = connection.createStatement()) {
@@ -747,13 +736,13 @@ public abstract class AbstractAuthConfigurationTest
statement.executeQuery(query);
}
catch (AvaticaSqlException ase) {
- Assert.assertEquals(
+ Assertions.assertEquals(
ase.getErrorMessage(),
expectedError
);
return;
}
- Assert.fail("Test failed, did not get AvaticaSqlException.");
+ Assertions.fail("Test failed, did not get AvaticaSqlException.");
}
protected void checkLoadStatusSingle(HttpClient httpClient, String baseUrl)
throws Exception
@@ -761,35 +750,33 @@ public abstract class AbstractAuthConfigurationTest
StatusResponseHolder holder = HttpUtil.makeRequest(
httpClient,
HttpMethod.GET,
- baseUrl + "/druid-ext/basic-security/authentication/loadStatus",
- null
+ baseUrl + "/druid-ext/basic-security/authentication/loadStatus"
);
String content = holder.getContent();
Map<String, Boolean> loadStatus = jsonMapper.readValue(content,
JacksonUtils.TYPE_REFERENCE_MAP_STRING_BOOLEAN);
String authenticatorName = getAuthenticatorName();
- Assert.assertNotNull(loadStatus.get(authenticatorName));
- Assert.assertTrue(loadStatus.get(authenticatorName));
+ Assertions.assertNotNull(loadStatus.get(authenticatorName));
+ Assertions.assertTrue(loadStatus.get(authenticatorName));
holder = HttpUtil.makeRequest(
httpClient,
HttpMethod.GET,
- baseUrl + "/druid-ext/basic-security/authorization/loadStatus",
- null
+ baseUrl + "/druid-ext/basic-security/authorization/loadStatus"
);
content = holder.getContent();
loadStatus = jsonMapper.readValue(content,
JacksonUtils.TYPE_REFERENCE_MAP_STRING_BOOLEAN);
String authorizerName = getAuthorizerName();
- Assert.assertNotNull(loadStatus.get(authorizerName));
- Assert.assertTrue(loadStatus.get(authorizerName));
+ Assertions.assertNotNull(loadStatus.get(authorizerName));
+ Assertions.assertTrue(loadStatus.get(authorizerName));
}
protected StatusResponseHolder makeSQLQueryRequest(
HttpClient httpClient,
String query,
HttpResponseStatus expectedStatus
- ) throws Exception
+ )
{
return makeSQLQueryRequest(httpClient, query, "/druid/v2/sql",
ImmutableMap.of(), expectedStatus);
}
@@ -799,7 +786,7 @@ public abstract class AbstractAuthConfigurationTest
String query,
Map<String, Object> context,
HttpResponseStatus expectedStatus
- ) throws Exception
+ )
{
return makeSQLQueryRequest(httpClient, query, "/druid/v2/sql", context,
expectedStatus);
}
@@ -809,7 +796,7 @@ public abstract class AbstractAuthConfigurationTest
String query,
Map<String, Object> context,
HttpResponseStatus expectedStatus
- ) throws Exception
+ )
{
return makeSQLQueryRequest(httpClient, query, "/druid/v2/sql/task",
context, expectedStatus);
}
@@ -819,7 +806,7 @@ public abstract class AbstractAuthConfigurationTest
String query,
Map<String, Object> context,
HttpResponseStatus expectedStatus
- ) throws Exception
+ )
{
final Map<String, Object> dartContext = new HashMap<>(context);
dartContext.put(QueryContexts.ENGINE, DartSqlEngine.NAME);
@@ -832,17 +819,19 @@ public abstract class AbstractAuthConfigurationTest
String path,
Map<String, Object> context,
HttpResponseStatus expectedStatus
- ) throws Exception
+ )
{
Map<String, Object> queryMap = ImmutableMap.of(
"query", query,
- "context", context
+ "context", context,
+ "resultFormat", "csv",
+ "header", true
);
- return HttpUtil.makeRequestWithExpectedStatus(
+ return HttpUtil.makeRequest(
httpClient,
HttpMethod.POST,
- config.getBrokerUrl() + path,
- jsonMapper.writeValueAsBytes(queryMap),
+ getServerUrl(broker) + path,
+ queryMap,
expectedStatus
);
}
@@ -850,57 +839,51 @@ public abstract class AbstractAuthConfigurationTest
protected void verifySystemSchemaQueryBase(
HttpClient client,
String query,
- List<Map<String, Object>> expectedResults,
- boolean isServerQuery
- ) throws Exception
+ String expectedResults
+ )
{
StatusResponseHolder responseHolder = makeSQLQueryRequest(client, query,
HttpResponseStatus.OK);
- String content = responseHolder.getContent();
- List<Map<String, Object>> responseMap = jsonMapper.readValue(content,
SYS_SCHEMA_RESULTS_TYPE_REFERENCE);
- if (isServerQuery) {
- responseMap = getServersWithoutNonConfigurableFields(responseMap);
- }
- Assert.assertEquals(responseMap, expectedResults);
+ String content = responseHolder.getContent().trim();
+ Assertions.assertEquals(expectedResults, content);
}
protected void verifySystemSchemaQuery(
HttpClient client,
String query,
- List<Map<String, Object>> expectedResults
- ) throws Exception
+ String expectedResults
+ )
{
- verifySystemSchemaQueryBase(client, query, expectedResults, false);
+ verifySystemSchemaQueryBase(client, query, expectedResults);
}
protected void verifySystemSchemaServerQuery(
HttpClient client,
String query,
- List<Map<String, Object>> expectedResults
- ) throws Exception
+ String expectedResults
+ )
{
- verifySystemSchemaQueryBase(client, query, expectedResults, true);
+ verifySystemSchemaQueryBase(client, query, expectedResults);
}
- protected void verifySystemSchemaQueryFailure(
+ private void verifySystemSchemaQueryIsForbidden(
HttpClient client,
String query,
- HttpResponseStatus expectedErrorStatus,
String expectedErrorMessage
- ) throws Exception
+ )
{
- StatusResponseHolder responseHolder = makeSQLQueryRequest(client, query,
expectedErrorStatus);
- Assert.assertEquals(responseHolder.getStatus(), expectedErrorStatus);
- Assert.assertEquals(responseHolder.getContent(), expectedErrorMessage);
+ StatusResponseHolder responseHolder = makeSQLQueryRequest(client, query,
HttpResponseStatus.FORBIDDEN);
+ Assertions.assertEquals(responseHolder.getStatus(),
HttpResponseStatus.FORBIDDEN);
+ Assertions.assertEquals(responseHolder.getContent(), expectedErrorMessage);
}
protected String getBrokerAvacticaUrl()
{
- return "jdbc:avatica:remote:url=" + config.getBrokerUrl() +
DruidAvaticaJsonHandler.AVATICA_PATH;
+ return "jdbc:avatica:remote:url=" + getServerUrl(broker) +
DruidAvaticaJsonHandler.AVATICA_PATH;
}
protected String getRouterAvacticaUrl()
{
- return "jdbc:avatica:remote:url=" + config.getRouterUrl() +
DruidAvaticaJsonHandler.AVATICA_PATH;
+ return "jdbc:avatica:remote:url=" + getServerUrl(router) +
DruidAvaticaJsonHandler.AVATICA_PATH;
}
protected void verifyAdminOptionsRequest()
@@ -912,7 +895,7 @@ public abstract class AbstractAuthConfigurationTest
{
verifyInvalidAuthNameFails(StringUtils.format(
"%s/druid-ext/basic-security/authentication/listen/%s",
- config.getCoordinatorUrl(),
+ getServerUrl(coordinator),
INVALID_NAME
));
}
@@ -921,7 +904,7 @@ public abstract class AbstractAuthConfigurationTest
{
verifyInvalidAuthNameFails(StringUtils.format(
"%s/druid-ext/basic-security/authorization/listen/users/%s",
- config.getCoordinatorUrl(),
+ getServerUrl(coordinator),
INVALID_NAME
));
}
@@ -930,18 +913,18 @@ public abstract class AbstractAuthConfigurationTest
{
verifyInvalidAuthNameFails(StringUtils.format(
"%s/druid-ext/basic-security/authorization/listen/groupMappings/%s",
- config.getCoordinatorUrl(),
+ getServerUrl(coordinator),
INVALID_NAME
));
}
protected void verifyInvalidAuthNameFails(String endpoint)
{
- HttpUtil.makeRequestWithExpectedStatus(
+ HttpUtil.makeRequest(
getHttpClient(User.ADMIN),
HttpMethod.POST,
endpoint,
- "SERIALIZED_DATA".getBytes(StandardCharsets.UTF_8),
+ "SERIALIZED_DATA",
HttpResponseStatus.INTERNAL_SERVER_ERROR
);
}
@@ -953,19 +936,19 @@ public abstract class AbstractAuthConfigurationTest
new BasicCredentials(maliciousUsername, "noPass"),
httpClient
);
- StatusResponseHolder responseHolder =
HttpUtil.makeRequestWithExpectedStatus(
+ StatusResponseHolder responseHolder = HttpUtil.makeRequest(
maliciousClient,
HttpMethod.GET,
- config.getBrokerUrl() + "/status",
+ getServerUrl(broker) + "/status",
null,
HttpResponseStatus.UNAUTHORIZED
);
String responseContent = responseHolder.getContent();
-
Assert.assertTrue(responseContent.contains("<tr><th>MESSAGE:</th><td>Unauthorized</td></tr>"));
- Assert.assertFalse(responseContent.contains(maliciousUsername));
+
Assertions.assertTrue(responseContent.contains("<tr><th>MESSAGE:</th><td>Unauthorized</td></tr>"));
+ Assertions.assertFalse(responseContent.contains(maliciousUsername));
}
- protected void setupHttpClients() throws Exception
+ protected void setupHttpClients()
{
setupCommonHttpClients();
setupTestSpecificHttpClients();
@@ -992,35 +975,56 @@ public abstract class AbstractAuthConfigurationTest
);
}
- protected void setExpectedSystemSchemaObjects() throws IOException
+ protected void setExpectedSystemSchemaObjects(String dataSource, String
taskId)
{
// initial setup is done now, run the system schema response content tests
- adminSegments = jsonMapper.readValue(
-
TestQueryHelper.class.getResourceAsStream(SYSTEM_SCHEMA_SEGMENTS_RESULTS_RESOURCE),
- SYS_SCHEMA_RESULTS_TYPE_REFERENCE
+ final Set<DataSegment> segments =
cluster.callApi().getVisibleUsedSegments(dataSource, overlord);
+ Assertions.assertEquals(1, segments.size());
+
+ final DataSegment segment = Iterables.getOnlyElement(segments);
+ final String segmentId = segment.getId().toString();
+
+ adminSegments = StringUtils.format(
+ "segment_id,num_rows,size\n"
+ + "%s,10,%s",
+ segmentId, segment.getSize()
);
- adminTasks = jsonMapper.readValue(
-
TestQueryHelper.class.getResourceAsStream(SYSTEM_SCHEMA_TASKS_RESULTS_RESOURCE),
- SYS_SCHEMA_RESULTS_TYPE_REFERENCE
+ adminTasks = StringUtils.format(
+ "task_id,group_id,type,datasource,status,location\n"
+ + "%s,%s,index,%s,SUCCESS,localhost:8091",
+ taskId, taskId, dataSource
);
- adminServers = getServersWithoutNonConfigurableFields(
- jsonMapper.readValue(
- fillServersTemplate(
- config,
-
AbstractIndexerTest.getResourceAsString(SYSTEM_SCHEMA_SERVERS_RESULTS_RESOURCE)
- ),
- SYS_SCHEMA_RESULTS_TYPE_REFERENCE
- )
+ adminServers =
+
"server,host,plaintext_port,tls_port,server_type,tier,curr_size,max_size,is_leader\n"
+ +
"localhost:8083,localhost,8083,-1,historical,_default_tier,1939,100000000,\n"
+ + "localhost:8091,localhost,8091,-1,indexer,_default_tier,0,0,";
+
+ adminServerSegments = StringUtils.format(
+ "server,segment_id\n"
+ + "localhost:8083,%s",
+ segmentId
);
+ }
- adminServerSegments = jsonMapper.readValue(
- fillSegementServersTemplate(
- config,
-
AbstractIndexerTest.getResourceAsString(SYSTEM_SCHEMA_SERVER_SEGMENTS_RESULTS_RESOURCE)
- ),
- SYS_SCHEMA_RESULTS_TYPE_REFERENCE
+ protected String getCoordinatorUrl()
+ {
+ return getServerUrl(coordinator);
+ }
+
+ protected String getBrokerUrl()
+ {
+ return getServerUrl(broker);
+ }
+
+ private static String getServerUrl(EmbeddedDruidServer<?> server)
+ {
+ final DruidNode node = server.bindings().selfNode();
+ return StringUtils.format(
+ "http://%s:%s",
+ node.getHost(),
+ node.getPlaintextPort()
);
}
@@ -1042,17 +1046,5 @@ public abstract class AbstractAuthConfigurationTest
return newServer;
}
);
- }
-
- protected static String fillSegementServersTemplate(IntegrationTestingConfig
config, String template)
- {
- return StringUtils.replace(template, "%%HISTORICAL%%",
config.getHistoricalInternalHost());
- }
-
- protected static String fillServersTemplate(IntegrationTestingConfig config,
String template)
- {
- String json = StringUtils.replace(template, "%%HISTORICAL%%",
config.getHistoricalInternalHost());
- json = StringUtils.replace(json, "%%BROKER%%",
config.getBrokerInternalHost());
- return json;
- }
+ }
}
diff --git
a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthConfigurationTest.java
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/BasicAuthConfigurationTest.java
similarity index 74%
rename from
integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthConfigurationTest.java
rename to
embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/BasicAuthConfigurationTest.java
index df147685232..ce356d185f8 100644
---
a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthConfigurationTest.java
+++
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/BasicAuthConfigurationTest.java
@@ -17,35 +17,25 @@
* under the License.
*/
-package org.apache.druid.tests.security;
+package org.apache.druid.testing.embedded.auth;
import org.apache.druid.java.util.common.StringUtils;
-import org.apache.druid.java.util.common.logger.Logger;
import org.apache.druid.java.util.http.client.CredentialedHttpClient;
import org.apache.druid.java.util.http.client.HttpClient;
import org.apache.druid.java.util.http.client.auth.BasicCredentials;
import
org.apache.druid.security.basic.authentication.entity.BasicAuthenticatorCredentialUpdate;
import org.apache.druid.server.security.Access;
import org.apache.druid.server.security.ResourceAction;
-import org.apache.druid.testing.guice.DruidTestModuleFactory;
-import org.apache.druid.testing.tools.ITRetryUtil;
-import org.apache.druid.testing.utils.HttpUtil;
-import org.apache.druid.tests.TestNGGroup;
+import org.apache.druid.testing.embedded.EmbeddedResource;
import org.jboss.netty.handler.codec.http.HttpMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Guice;
-import org.testng.annotations.Test;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.junit.jupiter.api.Test;
-import java.io.IOException;
import java.util.List;
import java.util.Properties;
-@Test(groups = TestNGGroup.SECURITY)
-@Guice(moduleFactory = DruidTestModuleFactory.class)
-public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest
+public class BasicAuthConfigurationTest extends AbstractAuthConfigurationTest
{
- private static final Logger LOG = new
Logger(ITBasicAuthConfigurationTest.class);
-
private static final String BASIC_AUTHENTICATOR = "basic";
private static final String BASIC_AUTHORIZER = "basic";
@@ -59,16 +49,10 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
private HttpClient druid99;
- @BeforeClass
- public void before() throws Exception
+ @Override
+ protected EmbeddedResource getAuthResource()
{
- // ensure that auth_test segments are loaded completely, we use them for
testing system schema tables
- ITRetryUtil.retryUntilTrue(
- () -> coordinatorClient.areSegmentsLoaded("auth_test"), "auth_test
segment load"
- );
-
- setupHttpClientsAndUsers();
- setExpectedSystemSchemaObjects();
+ return new EmbeddedBasicAuthResource();
}
@Test
@@ -78,22 +62,7 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
}
@Override
- protected void setupHttpClientsAndUsers() throws Exception
- {
- super.setupHttpClientsAndUsers();
-
- // Add a large enough delay to allow propagation of credentials to all
services. It'd be ideal
- // to have a "readiness" endpoint exposed by different services that'd
return the version of auth creds cached.
- try {
- Thread.sleep(20000);
- }
- catch (InterruptedException e) {
- // Ignore exception
- }
- }
-
- @Override
- protected void setupDatasourceOnlyUser() throws Exception
+ protected void setupDatasourceOnlyUser()
{
createUserAndRoleWithPermissions(
"datasourceOnlyUser",
@@ -104,7 +73,7 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
}
@Override
- protected void setupDatasourceAndContextParamsUser() throws Exception
+ protected void setupDatasourceAndContextParamsUser()
{
createUserAndRoleWithPermissions(
"datasourceAndContextParamsUser",
@@ -115,7 +84,7 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
}
@Override
- protected void setupDatasourceAndSysTableUser() throws Exception
+ protected void setupDatasourceAndSysTableUser()
{
createUserAndRoleWithPermissions(
"datasourceAndSysUser",
@@ -126,7 +95,7 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
}
@Override
- protected void setupDatasourceAndSysAndStateUser() throws Exception
+ protected void setupDatasourceAndSysAndStateUser()
{
createUserAndRoleWithPermissions(
"datasourceWithStateUser",
@@ -137,7 +106,7 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
}
@Override
- protected void setupSysTableAndStateOnlyUser() throws Exception
+ protected void setupSysTableAndStateOnlyUser()
{
createUserAndRoleWithPermissions(
"stateOnlyUser",
@@ -148,7 +117,7 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
}
@Override
- protected void setupTestSpecificHttpClients() throws Exception
+ protected void setupTestSpecificHttpClients()
{
// create a new user+role that can read /status
createUserAndRoleWithPermissions(
@@ -163,7 +132,6 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
final String username = "druid" + i;
postAsAdmin(null, "/authentication/db/basic/users/%s", username);
postAsAdmin(null, "/authorization/db/basic/users/%s", username);
- LOG.info("Created user[%s]", username);
}
// setup the last of 100 users and check that it works
@@ -226,7 +194,7 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
String password,
String role,
List<ResourceAction> permissions
- ) throws Exception
+ )
{
// Setup authentication by creating user and password
postAsAdmin(null, "/authentication/db/basic/users/%s", user);
@@ -246,17 +214,15 @@ public class ITBasicAuthConfigurationTest extends
AbstractAuthConfigurationTest
Object payload,
String pathFormat,
Object... pathParams
- ) throws IOException
+ )
{
HttpClient adminClient = getHttpClient(User.ADMIN);
-
- byte[] payloadBytes = payload == null ? null :
jsonMapper.writeValueAsBytes(payload);
String url = getBaseUrl() + StringUtils.format(pathFormat, pathParams);
- HttpUtil.makeRequest(adminClient, HttpMethod.POST, url, payloadBytes);
+ HttpUtil.makeRequest(adminClient, HttpMethod.POST, url, payload,
HttpResponseStatus.OK);
}
private String getBaseUrl()
{
- return config.getCoordinatorUrl() + "/druid-ext/basic-security";
+ return getCoordinatorUrl() + "/druid-ext/basic-security";
}
}
diff --git
a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthLdapConfigurationTest.java
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/BasicAuthLdapConfigurationTest.java
similarity index 73%
rename from
integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthLdapConfigurationTest.java
rename to
embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/BasicAuthLdapConfigurationTest.java
index 23cbc090275..cb62adcb91d 100644
---
a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthLdapConfigurationTest.java
+++
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/BasicAuthLdapConfigurationTest.java
@@ -17,100 +17,70 @@
* under the License.
*/
-package org.apache.druid.tests.security;
+package org.apache.druid.testing.embedded.auth;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
-import com.google.inject.Inject;
import org.apache.druid.java.util.common.StringUtils;
-import org.apache.druid.java.util.common.logger.Logger;
import org.apache.druid.java.util.http.client.CredentialedHttpClient;
import org.apache.druid.java.util.http.client.HttpClient;
import org.apache.druid.java.util.http.client.auth.BasicCredentials;
import
org.apache.druid.security.basic.authorization.entity.BasicAuthorizerGroupMapping;
import org.apache.druid.server.security.Access;
import org.apache.druid.server.security.ResourceAction;
-import org.apache.druid.testing.guice.DruidTestModuleFactory;
-import org.apache.druid.testing.tools.ITRetryUtil;
-import org.apache.druid.testing.tools.IntegrationTestingConfig;
-import org.apache.druid.testing.utils.HttpUtil;
-import org.apache.druid.tests.TestNGGroup;
+import org.apache.druid.testing.embedded.EmbeddedResource;
import org.jboss.netty.handler.codec.http.HttpMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Guice;
-import org.testng.annotations.Test;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.junit.jupiter.api.Test;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-@Test(groups = TestNGGroup.LDAP_SECURITY)
-@Guice(moduleFactory = DruidTestModuleFactory.class)
-public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationTest
+public class BasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationTest
{
- private static final Logger LOG = new
Logger(ITBasicAuthLdapConfigurationTest.class);
-
private static final String LDAP_AUTHENTICATOR = "ldap";
private static final String LDAP_AUTHORIZER = "ldapauth";
private static final String EXPECTED_AVATICA_AUTH_ERROR = "Error while
executing SQL \"SELECT * FROM INFORMATION_SCHEMA.COLUMNS\": Remote driver
error: " + Access.DEFAULT_ERROR_MESSAGE;
private static final String EXPECTED_AVATICA_AUTHZ_ERROR = "Error while
executing SQL \"SELECT * FROM INFORMATION_SCHEMA.COLUMNS\": Remote driver
error: " + Access.DEFAULT_ERROR_MESSAGE;
- @Inject
- IntegrationTestingConfig config;
-
- @Inject
- ObjectMapper jsonMapper;
-
-
private HttpClient druidUserClient;
private HttpClient stateOnlyNoLdapGroupUserClient;
- @BeforeClass
- public void before() throws Exception
+ @Override
+ protected EmbeddedResource getAuthResource()
{
- // ensure that auth_test segments are loaded completely, we use them for
testing system schema tables
- ITRetryUtil.retryUntilTrue(
- () -> coordinatorClient.areSegmentsLoaded("auth_test"), "auth_test
segment load"
- );
-
- setupHttpClientsAndUsers();
- setExpectedSystemSchemaObjects();
+ return new LdapAuthResource();
}
@Test
- public void test_systemSchemaAccess_stateOnlyNoLdapGroupUser() throws
Exception
+ public void test_systemSchemaAccess_stateOnlyNoLdapGroupUser()
{
- HttpUtil.makeRequest(getHttpClient(User.STATE_ONLY_USER), HttpMethod.GET,
config.getBrokerUrl() + "/status", null);
+ HttpUtil.makeRequest(getHttpClient(User.STATE_ONLY_USER), HttpMethod.GET,
getBrokerUrl() + "/status");
// as user that can only read STATE
- LOG.info("Checking sys.segments query as stateOnlyNoLdapGroupUser...");
verifySystemSchemaQuery(
stateOnlyNoLdapGroupUserClient,
SYS_SCHEMA_SEGMENTS_QUERY,
- Collections.emptyList()
+ "segment_id,num_rows,size"
);
- LOG.info("Checking sys.servers query as stateOnlyNoLdapGroupUser...");
verifySystemSchemaServerQuery(
stateOnlyNoLdapGroupUserClient,
SYS_SCHEMA_SERVERS_QUERY,
adminServers
);
- LOG.info("Checking sys.server_segments query as
stateOnlyNoLdapGroupUser...");
verifySystemSchemaQuery(
stateOnlyNoLdapGroupUserClient,
SYS_SCHEMA_SERVER_SEGMENTS_QUERY,
- Collections.emptyList()
+ "server,segment_id"
);
- LOG.info("Checking sys.tasks query as stateOnlyNoLdapGroupUser...");
verifySystemSchemaQuery(
stateOnlyNoLdapGroupUserClient,
SYS_SCHEMA_TASKS_QUERY,
- Collections.emptyList()
+ "task_id,group_id,type,datasource,status,location"
);
}
@@ -122,7 +92,7 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
@Override
- protected void setupDatasourceOnlyUser() throws Exception
+ protected void setupDatasourceOnlyUser()
{
createRoleWithPermissionsAndGroupMapping(
"datasourceOnlyGroup",
@@ -131,7 +101,7 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
}
@Override
- protected void setupDatasourceAndContextParamsUser() throws Exception
+ protected void setupDatasourceAndContextParamsUser()
{
createRoleWithPermissionsAndGroupMapping(
"datasourceAndContextParamsGroup",
@@ -140,7 +110,7 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
}
@Override
- protected void setupDatasourceAndSysTableUser() throws Exception
+ protected void setupDatasourceAndSysTableUser()
{
createRoleWithPermissionsAndGroupMapping(
"datasourceWithSysGroup",
@@ -149,7 +119,7 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
}
@Override
- protected void setupDatasourceAndSysAndStateUser() throws Exception
+ protected void setupDatasourceAndSysAndStateUser()
{
createRoleWithPermissionsAndGroupMapping(
"datasourceWithStateGroup",
@@ -158,7 +128,7 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
}
@Override
- protected void setupSysTableAndStateOnlyUser() throws Exception
+ protected void setupSysTableAndStateOnlyUser()
{
createRoleWithPermissionsAndGroupMapping(
"stateOnlyGroup",
@@ -233,7 +203,7 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
private void createRoleWithPermissionsAndGroupMapping(
String group,
Map<String, List<ResourceAction>> roleTopermissions
- ) throws Exception
+ )
{
final HttpClient adminClient = getHttpClient(User.ADMIN);
roleTopermissions.keySet().forEach(role -> HttpUtil.makeRequest(
@@ -241,25 +211,24 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
HttpMethod.POST,
StringUtils.format(
"%s/druid-ext/basic-security/authorization/db/ldapauth/roles/%s",
- config.getCoordinatorUrl(),
+ getCoordinatorUrl(),
role
- ),
- null
+ )
));
for (Map.Entry<String, List<ResourceAction>> entry :
roleTopermissions.entrySet()) {
String role = entry.getKey();
List<ResourceAction> permissions = entry.getValue();
- byte[] permissionsBytes = jsonMapper.writeValueAsBytes(permissions);
HttpUtil.makeRequest(
adminClient,
HttpMethod.POST,
StringUtils.format(
"%s/druid-ext/basic-security/authorization/db/ldapauth/roles/%s/permissions",
- config.getCoordinatorUrl(),
+ getCoordinatorUrl(),
role
),
- permissionsBytes
+ permissions,
+ HttpResponseStatus.OK
);
}
@@ -269,16 +238,16 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
StringUtils.format("cn=%s,ou=Groups,dc=example,dc=org", group),
roleTopermissions.keySet()
);
- byte[] groupMappingBytes = jsonMapper.writeValueAsBytes(groupMapping);
HttpUtil.makeRequest(
adminClient,
HttpMethod.POST,
StringUtils.format(
"%s/druid-ext/basic-security/authorization/db/ldapauth/groupMappings/%s",
- config.getCoordinatorUrl(),
+ getCoordinatorUrl(),
groupMappingName
),
- groupMappingBytes
+ groupMapping,
+ HttpResponseStatus.OK
);
}
@@ -293,10 +262,9 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
HttpMethod.POST,
StringUtils.format(
"%s/druid-ext/basic-security/authorization/db/ldapauth/users/%s",
- config.getCoordinatorUrl(),
+ getCoordinatorUrl(),
user
- ),
- null
+ )
);
HttpUtil.makeRequest(
@@ -304,11 +272,10 @@ public class ITBasicAuthLdapConfigurationTest extends
AbstractAuthConfigurationT
HttpMethod.POST,
StringUtils.format(
"%s/druid-ext/basic-security/authorization/db/ldapauth/users/%s/roles/%s",
- config.getCoordinatorUrl(),
+ getCoordinatorUrl(),
user,
role
- ),
- null
+ )
);
}
}
diff --git
a/integration-tests/src/main/java/org/apache/druid/testing/utils/HttpUtil.java
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/HttpUtil.java
similarity index 59%
rename from
integration-tests/src/main/java/org/apache/druid/testing/utils/HttpUtil.java
rename to
embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/HttpUtil.java
index 08a27adb0eb..9dfe821a030 100644
---
a/integration-tests/src/main/java/org/apache/druid/testing/utils/HttpUtil.java
+++
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/HttpUtil.java
@@ -17,15 +17,16 @@
* under the License.
*/
-package org.apache.druid.testing.utils;
+package org.apache.druid.testing.embedded.auth;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.java.util.common.StringUtils;
-import org.apache.druid.java.util.common.logger.Logger;
import org.apache.druid.java.util.http.client.HttpClient;
import org.apache.druid.java.util.http.client.Request;
import org.apache.druid.java.util.http.client.response.StatusResponseHandler;
import org.apache.druid.java.util.http.client.response.StatusResponseHolder;
+import org.apache.druid.segment.TestHelper;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
@@ -35,62 +36,41 @@ import java.net.URL;
public class HttpUtil
{
- private static final Logger LOG = new Logger(HttpUtil.class);
private static final StatusResponseHandler RESPONSE_HANDLER =
StatusResponseHandler.getInstance();
+ private static final ObjectMapper MAPPER = TestHelper.JSON_MAPPER;
- static final int NUM_RETRIES = 0;
- static final long DELAY_FOR_RETRIES_MS = 10000;
-
- public static StatusResponseHolder makeRequest(HttpClient httpClient,
HttpMethod method, String url, byte[] content)
+ public static StatusResponseHolder makeRequest(HttpClient httpClient,
HttpMethod method, String url)
{
- return makeRequestWithExpectedStatus(
+ return makeRequest(
httpClient,
method,
url,
- content,
+ null,
HttpResponseStatus.OK
);
}
- public static StatusResponseHolder makeRequestWithExpectedStatus(
+ public static StatusResponseHolder makeRequest(
HttpClient httpClient,
HttpMethod method,
String url,
- @Nullable byte[] content,
+ @Nullable Object content,
HttpResponseStatus expectedStatus
)
{
try {
Request request = new Request(method, new URL(url));
if (content != null) {
- request.setContent(MediaType.APPLICATION_JSON, content);
+ request.setContent(MediaType.APPLICATION_JSON,
MAPPER.writeValueAsBytes(content));
}
- int retryCount = 0;
-
- StatusResponseHolder response;
-
- while (true) {
- response = httpClient.go(request, RESPONSE_HANDLER).get();
+ StatusResponseHolder response = httpClient.go(request,
RESPONSE_HANDLER).get();
- if (!response.getStatus().equals(expectedStatus)) {
- String errMsg = StringUtils.format(
- "Error while making request to url[%s] status[%s] content[%s]",
- url,
- response.getStatus(),
- response.getContent()
- );
- // it can take time for the auth config to propagate, so we retry
- if (retryCount > NUM_RETRIES) {
- throw new ISE(errMsg);
- } else {
- LOG.error(errMsg);
- LOG.error("retrying in 3000ms, retryCount: " + retryCount);
- retryCount++;
- Thread.sleep(DELAY_FOR_RETRIES_MS);
- }
- } else {
- break;
- }
+ if (!response.getStatus().equals(expectedStatus)) {
+ String errMsg = StringUtils.format(
+ "Unexpected status[%s] content[%s] while making request[%s] to
URL[%s]",
+ response.getStatus(), response.getContent(), method, url
+ );
+ throw new ISE(errMsg);
}
return response;
}
diff --git
a/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/LdapAuthResource.java
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/LdapAuthResource.java
new file mode 100644
index 00000000000..ada03a80272
--- /dev/null
+++
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/auth/LdapAuthResource.java
@@ -0,0 +1,110 @@
+/*
+ * 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.druid.testing.embedded.auth;
+
+import org.apache.druid.java.util.common.StringUtils;
+import org.apache.druid.security.basic.BasicSecurityDruidModule;
+import org.apache.druid.testing.embedded.EmbeddedDruidCluster;
+import org.apache.druid.testing.embedded.TestcontainerResource;
+import org.apache.druid.testing.embedded.indexing.Resources;
+import org.testcontainers.containers.BindMode;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.utility.DockerImageName;
+
+import java.util.List;
+
+/**
+ * Resource to run an LDAP test container and add required properties to the
+ * cluster for LDAP authentication.
+ */
+public class LdapAuthResource extends
TestcontainerResource<GenericContainer<?>>
+{
+ private static final String IMAGE_NAME = "osixia/openldap:1.4.0";
+
+ public static final String ADMIN_PASSWORD = "priest";
+ public static final String SYSTEM_PASSWORD = "warlock";
+ public static final String SYSTEM_USER = "druid_system";
+
+ private static final String AUTHORIZER_NAME = "ldapauth";
+ private static final String AUTHENTICATOR_NAME = "ldap";
+
+ @Override
+ protected GenericContainer<?> createContainer()
+ {
+ GenericContainer<?> container = new
GenericContainer<>(DockerImageName.parse(IMAGE_NAME))
+ .withFileSystemBind(
+ Resources.getFileForResource("ldap-configs").getAbsolutePath(),
+ "/container/service/slapd/assets/config/bootstrap/ldif/custom",
+ BindMode.READ_WRITE
+ )
+ .withExposedPorts(389, 636)
+ .withCommand("--copy-service");
+
+ container.setPortBindings(List.of("8389:389", "8636:636"));
+
+ return container;
+ }
+
+ @Override
+ public void onStarted(EmbeddedDruidCluster cluster)
+ {
+ cluster
+ .addExtensions(BasicSecurityDruidModule.class)
+ .addCommonProperty(authenticatorProp("authorizerName"),
AUTHORIZER_NAME)
+ .addCommonProperty(authenticatorProp("initialAdminPassword"),
ADMIN_PASSWORD)
+ .addCommonProperty(authenticatorProp("initialInternalClientPassword"),
SYSTEM_PASSWORD)
+ .addCommonProperty(authenticatorProp("type"), "basic")
+ .addCommonProperty(authenticatorProp("credentialsValidator.type"),
"ldap")
+ .addCommonProperty(authenticatorProp("credentialsValidator.url"),
"ldap://localhost:8389")
+ .addCommonProperty(authenticatorProp("credentialsValidator.bindUser"),
"cn=admin,dc=example,dc=org")
+
.addCommonProperty(authenticatorProp("credentialsValidator.bindPassword"),
"admin")
+ .addCommonProperty(authenticatorProp("credentialsValidator.baseDn"),
"ou=Users,dc=example,dc=org")
+ .addCommonProperty(
+ authenticatorProp("credentialsValidator.userSearch"),
+ "(&(uid=%s)(objectClass=inetOrgPerson))"
+ )
+
.addCommonProperty(authenticatorProp("credentialsValidator.userAttribute"),
"uid")
+ .addCommonProperty("druid.auth.authenticatorChain", "[\"ldap\"]")
+ .addCommonProperty(authorizerProp("type"), "basic")
+ .addCommonProperty(authorizerProp("initialAdminUser"), "admin")
+ .addCommonProperty(authorizerProp("initialAdminRole"), "admin")
+ .addCommonProperty(authorizerProp("roleProvider.type"), "ldap")
+ .addCommonProperty("druid.auth.authorizers",
StringUtils.format("[\"%s\"]", AUTHORIZER_NAME))
+ .addCommonProperty(escalatorProp("type"), "basic")
+ .addCommonProperty(escalatorProp("internalClientPassword"),
SYSTEM_PASSWORD)
+ .addCommonProperty(escalatorProp("internalClientUsername"),
SYSTEM_USER)
+ .addCommonProperty(escalatorProp("authorizerName"), AUTHORIZER_NAME);
+ }
+
+ private String escalatorProp(String name)
+ {
+ return StringUtils.format("druid.escalator.%s", name);
+ }
+
+ private String authorizerProp(String name)
+ {
+ return StringUtils.format("druid.auth.authorizer.%s.%s", AUTHORIZER_NAME,
name);
+ }
+
+ private String authenticatorProp(String name)
+ {
+ return StringUtils.format("druid.auth.authenticator.%s.%s",
AUTHENTICATOR_NAME, name);
+ }
+}
diff --git a/embedded-tests/src/test/resources/ldap-configs/bootstrap.ldif
b/embedded-tests/src/test/resources/ldap-configs/bootstrap.ldif
new file mode 100644
index 00000000000..aec519658ac
--- /dev/null
+++ b/embedded-tests/src/test/resources/ldap-configs/bootstrap.ldif
@@ -0,0 +1,174 @@
+# 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.
+dn: ou=Users,dc=example,dc=org
+objectClass: top
+objectClass: organizationalUnit
+ou: Users
+
+dn: ou=Groups,dc=example,dc=org
+objectClass: top
+objectClass: organizationalUnit
+ou: Groups
+
+dn: uid=admin,ou=Users,dc=example,dc=org
+uid: admin
+cn: admin
+sn: admin
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/admin
+uidNumber: 1
+gidNumber: 1
+userPassword: priest
+
+dn: uid=druid_system,ou=Users,dc=example,dc=org
+uid: druid_system
+cn: druid_system
+sn: druid_system
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/druid_system
+uidNumber: 2
+gidNumber: 2
+userPassword: warlock
+
+dn: cn=admin,ou=Groups,dc=example,dc=org
+objectClass: groupOfUniqueNames
+cn: admin
+description: Admin users
+uniqueMember: uid=admin,ou=Users,dc=example,dc=org
+uniqueMember: uid=druid_system,ou=Users,dc=example,dc=org
+
+dn: uid=datasourceOnlyUser,ou=Users,dc=example,dc=org
+uid: datasourceOnlyUser
+cn: datasourceOnlyUser
+sn: datasourceOnlyUser
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/datasourceOnlyUser
+uidNumber: 3
+gidNumber: 3
+userPassword: helloworld
+
+dn: cn=datasourceOnlyGroup,ou=Groups,dc=example,dc=org
+objectClass: groupOfUniqueNames
+cn: datasourceOnlyGroup
+description: datasourceOnlyGroup users
+uniqueMember: uid=datasourceOnlyUser,ou=Users,dc=example,dc=org
+
+dn: uid=datasourceWithStateUser,ou=Users,dc=example,dc=org
+uid: datasourceWithStateUser
+cn: datasourceWithStateUser
+sn: datasourceWithStateUser
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/datasourceWithStateUser
+uidNumber: 4
+gidNumber: 4
+userPassword: helloworld
+
+dn: cn=datasourceWithStateGroup,ou=Groups,dc=example,dc=org
+objectClass: groupOfUniqueNames
+cn: datasourceWithStateGroup
+description: datasourceWithStateGroup users
+uniqueMember: uid=datasourceWithStateUser,ou=Users,dc=example,dc=org
+
+dn: uid=stateOnlyUser,ou=Users,dc=example,dc=org
+uid: stateOnlyUser
+cn: stateOnlyUser
+sn: stateOnlyUser
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/stateOnlyUser
+uidNumber: 5
+gidNumber: 5
+userPassword: helloworld
+
+dn: cn=stateOnlyGroup,ou=Groups,dc=example,dc=org
+objectClass: groupOfUniqueNames
+cn: stateOnlyGroup
+description: stateOnlyGroup users
+uniqueMember: uid=stateOnlyUser,ou=Users,dc=example,dc=org
+
+dn: uid=druid,ou=Users,dc=example,dc=org
+uid: druid
+cn: druid
+sn: druid
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/druid
+uidNumber: 6
+gidNumber: 6
+userPassword: helloworld
+
+dn: cn=druidGroup,ou=Groups,dc=example,dc=org
+objectClass: groupOfUniqueNames
+cn: druidGroup
+description: druidGroup users
+uniqueMember: uid=druid,ou=Users,dc=example,dc=org
+
+dn: uid=stateOnlyNoLdapGroup,ou=Users,dc=example,dc=org
+uid: druid
+cn: druid
+sn: druid
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/druid
+uidNumber: 7
+gidNumber: 7
+userPassword: helloworld
+
+dn: uid=datasourceAndSysUser,ou=Users,dc=example,dc=org
+uid: datasourceAndSysUser
+cn: datasourceAndSysUser
+sn: datasourceAndSysUser
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/datasourceAndSysUser
+uidNumber: 8
+gidNumber: 8
+userPassword: helloworld
+
+dn: cn=datasourceWithSysGroup,ou=Groups,dc=example,dc=org
+objectClass: groupOfUniqueNames
+cn: datasourceWithSysGroup
+description: datasourceWithSysGroup users
+uniqueMember: uid=datasourceAndSysUser,ou=Users,dc=example,dc=org
+
+dn: uid=datasourceAndContextParamsUser,ou=Users,dc=example,dc=org
+uid: datasourceAndContextParamsUser
+cn: datasourceAndContextParamsUser
+sn: datasourceAndContextParamsUser
+objectClass: top
+objectClass: posixAccount
+objectClass: inetOrgPerson
+homeDirectory: /home/datasourceAndContextParamsUser
+uidNumber: 9
+gidNumber: 9
+userPassword: helloworld
+
+dn: cn=datasourceAndContextParamsGroup,ou=Groups,dc=example,dc=org
+objectClass: groupOfUniqueNames
+cn: datasourceAndContextParamsGroup
+description: datasourceAndContextParamsGroup users
+uniqueMember: uid=datasourceAndContextParamsUser,ou=Users,dc=example,dc=org
diff --git a/integration-tests/docker/druid.sh
b/integration-tests/docker/druid.sh
index 65210c86caa..129e3722ee6 100755
--- a/integration-tests/docker/druid.sh
+++ b/integration-tests/docker/druid.sh
@@ -103,7 +103,7 @@ setupData()
# The "query" and "security" test groups require data to be setup before
running the tests.
# In particular, they requires segments to be download from a pre-existing
s3 bucket.
# This is done by using the loadSpec put into metadatastore and s3
credientials set below.
- if [ "$DRUID_INTEGRATION_TEST_GROUP" = "query" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-retry" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-error" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "security" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "ldap-security" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "upgrade" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "centralized-datasource-schema" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "cds-task-schema-publish-disabled" ] || [
"$DRUID_INTEGRATI [...]
+ if [ "$DRUID_INTEGRATION_TEST_GROUP" = "query" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-retry" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-error" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "security" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "upgrade" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "centralized-datasource-schema" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "cds-task-schema-publish-disabled" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "cds-coordinator-metadata-query-disabled [...]
cat /test-data/${DRUID_INTEGRATION_TEST_GROUP}-sample-data.sql | mysql -u
root druid
fi
diff --git a/integration-tests/docker/test-data/ldap-security-sample-data.sql
b/integration-tests/docker/test-data/ldap-security-sample-data.sql
deleted file mode 100644
index 5e4774663c0..00000000000
--- a/integration-tests/docker/test-data/ldap-security-sample-data.sql
+++ /dev/null
@@ -1,17 +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
---
--- 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.
-
-INSERT INTO druid_tasks (id, created_date, datasource, payload,
status_payload, active) VALUES ('index_auth_test_2030-04-30T01:13:31.893Z',
'2030-04-30T01:13:31.893Z', 'auth_test',
'{\"id\":\"index_auth_test_2030-04-30T01:13:31.893Z\",\"created_date\":\"2030-04-30T01:13:31.893Z\",\"datasource\":\"auth_test\",\"active\":0}',
'{\"id\":\"index_auth_test_2030-04-30T01:13:31.893Z\",\"status\":\"SUCCESS\",\"duration\":1}',
0);
-INSERT INTO druid_segments
(id,dataSource,created_date,start,end,partitioned,version,used,payload,used_status_last_updated)
VALUES
('auth_test_2012-12-29T00:00:00.000Z_2013-01-10T08:00:00.000Z_2013-01-10T08:13:47.830Z_v9','auth_test','2013-03-15T20:49:52.348Z','2012-12-29T00:00:00.000Z','2013-01-10T08:00:00.000Z',0,'2013-01-10T08:13:47.830Z_v9',1,'{\"dataSource\":\"auth_test\",\"interval\":\"2012-12-29T00:00:00.000Z/2013-01-10T08:00:00.000Z\",\"version\":\"2013-01-10T08:13:47.830Z_v9\",\
[...]
diff --git a/integration-tests/docker/test-data/security-sample-data.sql
b/integration-tests/docker/test-data/security-sample-data.sql
deleted file mode 100644
index 5e4774663c0..00000000000
--- a/integration-tests/docker/test-data/security-sample-data.sql
+++ /dev/null
@@ -1,17 +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
---
--- 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.
-
-INSERT INTO druid_tasks (id, created_date, datasource, payload,
status_payload, active) VALUES ('index_auth_test_2030-04-30T01:13:31.893Z',
'2030-04-30T01:13:31.893Z', 'auth_test',
'{\"id\":\"index_auth_test_2030-04-30T01:13:31.893Z\",\"created_date\":\"2030-04-30T01:13:31.893Z\",\"datasource\":\"auth_test\",\"active\":0}',
'{\"id\":\"index_auth_test_2030-04-30T01:13:31.893Z\",\"status\":\"SUCCESS\",\"duration\":1}',
0);
-INSERT INTO druid_segments
(id,dataSource,created_date,start,end,partitioned,version,used,payload,used_status_last_updated)
VALUES
('auth_test_2012-12-29T00:00:00.000Z_2013-01-10T08:00:00.000Z_2013-01-10T08:13:47.830Z_v9','auth_test','2013-03-15T20:49:52.348Z','2012-12-29T00:00:00.000Z','2013-01-10T08:00:00.000Z',0,'2013-01-10T08:13:47.830Z_v9',1,'{\"dataSource\":\"auth_test\",\"interval\":\"2012-12-29T00:00:00.000Z/2013-01-10T08:00:00.000Z\",\"version\":\"2013-01-10T08:13:47.830Z_v9\",\
[...]
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index b6d2b4feef6..92a7d3a6053 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -192,11 +192,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.druid.extensions</groupId>
- <artifactId>druid-basic-security</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
<dependency>
<groupId>org.apache.druid.extensions</groupId>
<artifactId>druid-lookups-cached-global</artifactId>
diff --git a/integration-tests/script/docker_compose_args.sh
b/integration-tests/script/docker_compose_args.sh
index 3a3a754a70c..fff93605e97 100644
--- a/integration-tests/script/docker_compose_args.sh
+++ b/integration-tests/script/docker_compose_args.sh
@@ -29,7 +29,7 @@ getComposeArgs()
if [ "$DRUID_INTEGRATION_TEST_INDEXER" = "indexer" ]
then
# Sanity check: cannot combine CliIndexer tests with security, query-retry
tests
- if [ "$DRUID_INTEGRATION_TEST_GROUP" = "security" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "ldap-security" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-retry" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-error" ]
+ if [ "$DRUID_INTEGRATION_TEST_GROUP" = "security" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-retry" ] || [
"$DRUID_INTEGRATION_TEST_GROUP" = "query-error" ]
then
echo "Cannot run test group '$DRUID_INTEGRATION_TEST_GROUP' with
CliIndexer"
exit 1
@@ -41,10 +41,6 @@ getComposeArgs()
then
# default + additional druid router (custom-check-tls, permissive-tls,
no-client-auth-tls)
echo "-f ${DOCKERDIR}/docker-compose.yml -f
${DOCKERDIR}/docker-compose.security.yml"
- elif [ "$DRUID_INTEGRATION_TEST_GROUP" = "ldap-security" ]
- then
- # default + additional druid router (custom-check-tls, permissive-tls,
no-client-auth-tls)
- echo "-f ${DOCKERDIR}/docker-compose.yml -f
${DOCKERDIR}/docker-compose.ldap-security.yml"
elif [ "$DRUID_INTEGRATION_TEST_GROUP" = "query-retry" ]
then
# default + additional historical modified for query retry test
diff --git
a/integration-tests/src/test/java/org/apache/druid/tests/TestNGGroup.java
b/integration-tests/src/test/java/org/apache/druid/tests/TestNGGroup.java
index 249672b099c..21c3fc7a76b 100644
--- a/integration-tests/src/test/java/org/apache/druid/tests/TestNGGroup.java
+++ b/integration-tests/src/test/java/org/apache/druid/tests/TestNGGroup.java
@@ -49,11 +49,6 @@ public class TestNGGroup
*/
public static final String SECURITY = "security";
- /**
- * This group can only be run individually using -Dgroups=ldap-security
since it requires specific test data setup.
- */
- public static final String LDAP_SECURITY = "ldap-security";
-
/**
* This group is not part of CI. To run this group, s3 configs/credentials
for your s3 must be provided in a file.
* The path of the file must then be pass to mvn with
-Doverride.config.path=<PATH_TO_FILE>
diff --git a/licenses.yaml b/licenses.yaml
index b873d729b23..f1faf44d24e 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -5122,7 +5122,7 @@ name: Docker Java
license_category: binary
module: extensions-core/druid-testcontainers
license_name: Apache License version 2.0
-version: 3.3.4
+version: 3.6.0
libraries:
- com.github.docker-java: docker-java-api
- com.github.docker-java: docker-java-transport
diff --git a/pom.xml b/pom.xml
index 0b4046e2cfd..6b52e3ff447 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1160,7 +1160,7 @@
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java-bom</artifactId>
- <version>3.3.4</version>
+ <version>3.6.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>
diff --git
a/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedDruidServer.java
b/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedDruidServer.java
index 947e7e6e34a..5f2ff75fe82 100644
---
a/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedDruidServer.java
+++
b/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedDruidServer.java
@@ -162,19 +162,21 @@ public abstract class EmbeddedDruidServer<T extends
EmbeddedDruidServer<T>> impl
/**
* Sets the amount of heap memory visible to the server through {@link
RuntimeInfo}.
*/
- public final EmbeddedDruidServer<T> setServerMemory(long serverMemory)
+ @SuppressWarnings("unchecked")
+ public final T setServerMemory(long serverMemory)
{
this.serverMemory = serverMemory;
- return this;
+ return (T) this;
}
/**
* Sets the amount of direct (off-heap) memory visible to the server through
{@link RuntimeInfo}.
*/
- public final EmbeddedDruidServer<T> setServerDirectMemory(long
serverDirectMemory)
+ @SuppressWarnings("unchecked")
+ public final T setServerDirectMemory(long serverDirectMemory)
{
this.serverDirectMemory = serverDirectMemory;
- return this;
+ return (T) this;
}
/**
diff --git
a/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedHistorical.java
b/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedHistorical.java
index b9df19acca1..3dbb9c6cbc1 100644
---
a/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedHistorical.java
+++
b/services/src/test/java/org/apache/druid/testing/embedded/EmbeddedHistorical.java
@@ -36,6 +36,8 @@ import java.util.List;
*/
public class EmbeddedHistorical extends EmbeddedDruidServer<EmbeddedHistorical>
{
+ private long maxDiskSize = MEM_100_MB;
+
public EmbeddedHistorical()
{
addBeforeStartHook((cluster, self) -> {
@@ -44,12 +46,18 @@ public class EmbeddedHistorical extends
EmbeddedDruidServer<EmbeddedHistorical>
StringUtils.format(
"[{\"path\":\"%s\",\"maxSize\":\"%s\"}]",
cluster.getTestFolder().newFolder().getAbsolutePath(),
- MEM_100_MB
+ maxDiskSize
)
);
});
}
+ public EmbeddedHistorical setDiskSize(long maxDiskSize)
+ {
+ this.maxDiskSize = maxDiskSize;
+ return this;
+ }
+
@Override
protected ServerRunnable createRunnable(LifecycleInitHandler handler)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]