Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fb3aa6c
Encapsulate usage of alternate header name config
electrum Nov 26, 2023
788f8e0
Encapsulate authenticated identity servlet attribute
electrum Nov 26, 2023
8a8eb7b
Move TransactionBuilder to testing package
electrum Nov 26, 2023
450b553
Move EmbedVersion to util package
electrum Nov 26, 2023
69cf488
Move IndexManager to operator.index package
electrum Nov 26, 2023
2aeadda
Wrap arguments in DistributedQueryRunner
electrum Nov 28, 2023
2648f60
Simplify backup coordinator creation
electrum Nov 28, 2023
180358b
Use testing OpenTelemetryExtension
electrum Dec 3, 2023
a2dca6a
Collect spans for queries in DistributedQueryRunner
electrum Dec 3, 2023
1a2abe1
Use static imports for TestingHiveUtils
electrum Dec 6, 2023
de4c83c
Cleanup warnings in HiveQueryRunner
electrum Dec 6, 2023
a956dd2
Remove unnecessary config constant
electrum Dec 6, 2023
1afaa15
Add tracing wrapper in metastore factories
electrum Dec 3, 2023
21f02e1
Move metastore method enum to top level
electrum Nov 28, 2023
b7ef28b
Fix type safety for counting metastore tests
electrum Nov 28, 2023
0c91934
Create Hive metastore for testing using properties
electrum Dec 3, 2023
fa7692e
Make metastore method names unique
electrum Dec 3, 2023
4ac818a
Use tracing for metastore access tests
electrum Dec 5, 2023
78f8a29
Remove unused test exclusion
electrum Dec 6, 2023
85663cd
Remove legacy Hive file system tests
electrum Dec 6, 2023
19bbf8a
Remove legacy Hive S3 tests
electrum Dec 6, 2023
022fbb4
Remove legacy Hive tests
electrum Dec 6, 2023
c3f4262
Move Rubix initialization tests to HDFS module
electrum Dec 7, 2023
b49d3ef
Move Hive plugin to Hive module
electrum Dec 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/config/labeler-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
- lib/trino-orc/**
- lib/trino-parquet/**
- lib/trino-hive-formats/**
- plugin/trino-hive-hadoop2/**
- plugin/trino-hive/**
- testing/trino-product-tests/**
- lib/trino-filesystem/**
Expand All @@ -20,7 +19,6 @@ delta-lake:

hive:
- plugin/trino-hive/**
- plugin/trino-hive-hadoop2/**

hudi:
- plugin/trino-hudi/**
Expand Down
69 changes: 1 addition & 68 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -301,27 +301,7 @@ jobs:
- name: Install Hive Module
run: |
export MAVEN_OPTS="${MAVEN_INSTALL_OPTS}"
$MAVEN clean install ${MAVEN_FAST_INSTALL} ${MAVEN_GIB} -Dgib.logImpactedTo=gib-impacted.log -am -pl :trino-hive-hadoop2
- name: Run Hive Tests
run: |
source plugin/trino-hive-hadoop2/conf/hive-tests-${{ matrix.config }}.sh &&
plugin/trino-hive-hadoop2/bin/run_hive_tests.sh
- name: Run Hive S3 Tests
env:
AWS_ACCESS_KEY_ID: ${{ secrets.TRINO_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.TRINO_AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ vars.TRINO_AWS_REGION }}
S3_BUCKET: ${{ vars.TRINO_S3_BUCKET }}
S3_BUCKET_ENDPOINT: "https://s3.${{ vars.TRINO_AWS_REGION }}.amazonaws.com"
run: |
if [ "${AWS_ACCESS_KEY_ID}" != "" ]; then
source plugin/trino-hive-hadoop2/conf/hive-tests-${{ matrix.config }}.sh &&
plugin/trino-hive-hadoop2/bin/run_hive_s3_tests.sh
if [ matrix.config == 'config-hdp3' ]; then
# JsonSerde class needed for the S3 Select JSON tests is only available on hdp3.
plugin/trino-hive-hadoop2/bin/run_hive_s3_select_json_tests.sh
fi
fi
$MAVEN clean install ${MAVEN_FAST_INSTALL} ${MAVEN_GIB} -Dgib.logImpactedTo=gib-impacted.log -am -pl :trino-hive
- name: Run Hive AWS Tests
env:
AWS_ACCESS_KEY_ID: ${{ secrets.TRINO_AWS_ACCESS_KEY_ID }}
Expand All @@ -333,53 +313,6 @@ jobs:
if [ "${AWS_ACCESS_KEY_ID}" != "" ]; then
$MAVEN test ${MAVEN_TEST} -pl :trino-hive -P aws-tests
fi
- name: Run Hive Azure ABFS Access Key Tests
if: matrix.config != 'config-empty' # Hive 1.x does not support Azure storage
env:
ABFS_CONTAINER: ${{ secrets.AZURE_ABFS_CONTAINER }}
ABFS_ACCOUNT: ${{ secrets.AZURE_ABFS_ACCOUNT }}
ABFS_ACCESS_KEY: ${{ secrets.AZURE_ABFS_ACCESSKEY }}
run: |
if [ "${ABFS_CONTAINER}" != "" ]; then
source plugin/trino-hive-hadoop2/conf/hive-tests-${{ matrix.config }}.sh &&
plugin/trino-hive-hadoop2/bin/run_hive_abfs_access_key_tests.sh
fi
- name: Run Hive Azure ABFS OAuth Tests
if: matrix.config != 'config-empty' # Hive 1.x does not support Azure storage
env:
ABFS_CONTAINER: ${{ secrets.AZURE_ABFS_CONTAINER }}
ABFS_ACCOUNT: ${{ secrets.AZURE_ABFS_ACCOUNT }}
ABFS_OAUTH_ENDPOINT: ${{ secrets.AZURE_ABFS_OAUTH_ENDPOINT }}
ABFS_OAUTH_CLIENTID: ${{ secrets.AZURE_ABFS_OAUTH_CLIENTID }}
ABFS_OAUTH_SECRET: ${{ secrets.AZURE_ABFS_OAUTH_SECRET }}
run: |
if [ -n "$ABFS_CONTAINER" ]; then
source plugin/trino-hive-hadoop2/conf/hive-tests-${{ matrix.config }}.sh &&
plugin/trino-hive-hadoop2/bin/run_hive_abfs_oauth_tests.sh
fi
- name: Run Hive Azure WASB Tests
if: matrix.config != 'config-empty' # Hive 1.x does not support Azure storage
env:
WASB_CONTAINER: ${{ secrets.AZURE_WASB_CONTAINER }}
WASB_ACCOUNT: ${{ secrets.AZURE_WASB_ACCOUNT }}
WASB_ACCESS_KEY: ${{ secrets.AZURE_WASB_ACCESSKEY }}
run: |
if [ "${WASB_CONTAINER}" != "" ]; then
source plugin/trino-hive-hadoop2/conf/hive-tests-${{ matrix.config }}.sh &&
plugin/trino-hive-hadoop2/bin/run_hive_wasb_tests.sh
fi
- name: Run Hive Azure ADL Tests
if: matrix.config != 'config-empty' # Hive 1.x does not support Azure storage
env:
ADL_NAME: ${{ secrets.AZURE_ADL_NAME }}
ADL_CLIENT_ID: ${{ secrets.AZURE_ADL_CLIENTID }}
ADL_CREDENTIAL: ${{ secrets.AZURE_ADL_CREDENTIAL }}
ADL_REFRESH_URL: ${{ secrets.AZURE_ADL_REFRESHURL }}
run: |
if [ "${ADL_NAME}" != "" ]; then
source plugin/trino-hive-hadoop2/conf/hive-tests-${{ matrix.config }}.sh &&
plugin/trino-hive-hadoop2/bin/run_hive_adl_tests.sh
fi
- name: Upload test results
uses: actions/upload-artifact@v3
# Upload all test reports only on failure, because the artifacts are large
Expand Down
2 changes: 1 addition & 1 deletion client/trino-jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@

<dependency>
<groupId>io.trino</groupId>
<artifactId>trino-hive-hadoop2</artifactId>
<artifactId>trino-hive</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
Expand Down
5 changes: 5 additions & 0 deletions core/trino-main/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@
<artifactId>opentelemetry-context</artifactId>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
</dependency>

<dependency>
<groupId>io.trino</groupId>
<artifactId>re2j</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import io.trino.execution.QueryManagerConfig;
import io.trino.execution.QueryState;
import io.trino.server.HttpRequestSessionContextFactory;
import io.trino.server.ProtocolConfig;
import io.trino.server.ServerConfig;
import io.trino.server.SessionContext;
import io.trino.server.protocol.QueryInfoUrlFactory;
Expand Down Expand Up @@ -85,7 +84,8 @@
import static io.airlift.jaxrs.AsyncResponseHandler.bindAsyncResponse;
import static io.trino.execution.QueryState.FAILED;
import static io.trino.execution.QueryState.QUEUED;
import static io.trino.server.HttpRequestSessionContextFactory.AUTHENTICATED_IDENTITY;
import static io.trino.server.ServletSecurityUtils.authenticatedIdentity;
import static io.trino.server.ServletSecurityUtils.clearAuthenticatedIdentity;
import static io.trino.server.protocol.QueryInfoUrlFactory.getQueryInfoUri;
import static io.trino.server.protocol.Slug.Context.EXECUTING_QUERY;
import static io.trino.server.protocol.Slug.Context.QUEUED_QUERY;
Expand Down Expand Up @@ -120,7 +120,6 @@ public class QueuedStatementResource
private final ScheduledExecutorService timeoutExecutor;

private final boolean compressionEnabled;
private final Optional<String> alternateHeaderName;
private final QueryManager queryManager;

@Inject
Expand All @@ -131,7 +130,6 @@ public QueuedStatementResource(
DispatchExecutor executor,
QueryInfoUrlFactory queryInfoUrlTemplate,
ServerConfig serverConfig,
ProtocolConfig protocolConfig,
QueryManagerConfig queryManagerConfig)
{
this.sessionContextFactory = requireNonNull(sessionContextFactory, "sessionContextFactory is null");
Expand All @@ -141,7 +139,6 @@ public QueuedStatementResource(
this.timeoutExecutor = executor.getScheduledExecutor();
this.queryInfoUrlFactory = requireNonNull(queryInfoUrlTemplate, "queryInfoUrlTemplate is null");
this.compressionEnabled = serverConfig.isQueryResultsCompressionEnabled();
this.alternateHeaderName = protocolConfig.getAlternateHeaderName();
queryManager = new QueryManager(queryManagerConfig.getClientTimeout());
}

Expand Down Expand Up @@ -178,19 +175,19 @@ public Response postStatement(
private Query registerQuery(String statement, HttpServletRequest servletRequest, HttpHeaders httpHeaders)
{
Optional<String> remoteAddress = Optional.ofNullable(servletRequest.getRemoteAddr());
Optional<Identity> identity = Optional.ofNullable((Identity) servletRequest.getAttribute(AUTHENTICATED_IDENTITY));
Optional<Identity> identity = authenticatedIdentity(servletRequest);
if (identity.flatMap(Identity::getPrincipal).map(InternalPrincipal.class::isInstance).orElse(false)) {
throw badRequest(FORBIDDEN, "Internal communication can not be used to start a query");
}

MultivaluedMap<String, String> headers = httpHeaders.getRequestHeaders();

SessionContext sessionContext = sessionContextFactory.createSessionContext(headers, alternateHeaderName, remoteAddress, identity);
SessionContext sessionContext = sessionContextFactory.createSessionContext(headers, remoteAddress, identity);
Query query = new Query(statement, sessionContext, dispatchManager, queryInfoUrlFactory, tracer);
queryManager.registerQuery(query);

// let authentication filter know that identity lifecycle has been handed off
servletRequest.setAttribute(AUTHENTICATED_IDENTITY, null);
clearAuthenticatedIdentity(servletRequest);

return query;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
import static io.airlift.concurrent.Threads.threadsNamed;
import static io.airlift.tracing.Tracing.noopTracer;
import static io.trino.execution.executor.timesharing.MultilevelSplitQueue.computeLevel;
import static io.trino.version.EmbedVersion.testingVersionEmbedder;
import static io.trino.util.EmbedVersion.testingVersionEmbedder;
import static java.lang.Math.min;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.index;
package io.trino.operator.index;

import com.google.inject.Inject;
import io.trino.Session;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.common.net.HttpHeaders.USER_AGENT;
import static io.trino.client.ProtocolHeaders.detectProtocol;
import static io.trino.server.ServletSecurityUtils.authenticatedIdentity;
import static io.trino.spi.security.AccessDeniedException.denySetRole;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
Expand All @@ -69,16 +70,22 @@
public class HttpRequestSessionContextFactory
{
private static final Splitter DOT_SPLITTER = Splitter.on('.');
public static final String AUTHENTICATED_IDENTITY = "trino.authenticated-identity";

private final PreparedStatementEncoder preparedStatementEncoder;
private final Metadata metadata;
private final GroupProvider groupProvider;
private final AccessControl accessControl;
private final Optional<String> alternateHeaderName;

@Inject
public HttpRequestSessionContextFactory(PreparedStatementEncoder preparedStatementEncoder, Metadata metadata, GroupProvider groupProvider, AccessControl accessControl)
public HttpRequestSessionContextFactory(
PreparedStatementEncoder preparedStatementEncoder,
Metadata metadata,
GroupProvider groupProvider,
AccessControl accessControl,
ProtocolConfig protocolConfig)
{
this.alternateHeaderName = protocolConfig.getAlternateHeaderName();
this.preparedStatementEncoder = requireNonNull(preparedStatementEncoder, "preparedStatementEncoder is null");
this.metadata = requireNonNull(metadata, "metadata is null");
this.groupProvider = requireNonNull(groupProvider, "groupProvider is null");
Expand All @@ -87,7 +94,6 @@ public HttpRequestSessionContextFactory(PreparedStatementEncoder preparedStateme

public SessionContext createSessionContext(
MultivaluedMap<String, String> headers,
Optional<String> alternateHeaderName,
Optional<String> remoteAddress,
Optional<Identity> authenticatedIdentity)
throws WebApplicationException
Expand Down Expand Up @@ -184,21 +190,12 @@ else if (nameParts.size() == 2) {
clientInfo);
}

public Identity extractAuthorizedIdentity(
HttpServletRequest servletRequest,
HttpHeaders httpHeaders,
Optional<String> alternateHeaderName)
public Identity extractAuthorizedIdentity(HttpServletRequest servletRequest, HttpHeaders httpHeaders)
{
return extractAuthorizedIdentity(
Optional.ofNullable((Identity) servletRequest.getAttribute(AUTHENTICATED_IDENTITY)),
httpHeaders.getRequestHeaders(),
alternateHeaderName);
return extractAuthorizedIdentity(authenticatedIdentity(servletRequest), httpHeaders.getRequestHeaders());
}

public Identity extractAuthorizedIdentity(
Optional<Identity> optionalAuthenticatedIdentity,
MultivaluedMap<String, String> headers,
Optional<String> alternateHeaderName)
public Identity extractAuthorizedIdentity(Optional<Identity> optionalAuthenticatedIdentity, MultivaluedMap<String, String> headers)
throws AccessDeniedException
{
ProtocolHeaders protocolHeaders;
Expand Down
12 changes: 5 additions & 7 deletions core/trino-main/src/main/java/io/trino/server/QueryResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,13 @@ public class QueryResource
private final DispatchManager dispatchManager;
private final AccessControl accessControl;
private final HttpRequestSessionContextFactory sessionContextFactory;
private final Optional<String> alternateHeaderName;

@Inject
public QueryResource(DispatchManager dispatchManager, AccessControl accessControl, HttpRequestSessionContextFactory sessionContextFactory, ProtocolConfig protocolConfig)
public QueryResource(DispatchManager dispatchManager, AccessControl accessControl, HttpRequestSessionContextFactory sessionContextFactory)
{
this.dispatchManager = requireNonNull(dispatchManager, "dispatchManager is null");
this.accessControl = requireNonNull(accessControl, "accessControl is null");
this.sessionContextFactory = requireNonNull(sessionContextFactory, "sessionContextFactory is null");
this.alternateHeaderName = protocolConfig.getAlternateHeaderName();
}

@ResourceSecurity(AUTHENTICATED_USER)
Expand All @@ -76,7 +74,7 @@ public List<BasicQueryInfo> getAllQueryInfo(@QueryParam("state") String stateFil
QueryState expectedState = stateFilter == null ? null : QueryState.valueOf(stateFilter.toUpperCase(Locale.ENGLISH));

List<BasicQueryInfo> queries = dispatchManager.getQueries();
queries = filterQueries(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders, alternateHeaderName), queries, accessControl);
queries = filterQueries(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders), queries, accessControl);

ImmutableList.Builder<BasicQueryInfo> builder = ImmutableList.builder();
for (BasicQueryInfo queryInfo : queries) {
Expand All @@ -99,7 +97,7 @@ public Response getQueryInfo(@PathParam("queryId") QueryId queryId, @Context Htt
return Response.status(Status.GONE).build();
}
try {
checkCanViewQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders, alternateHeaderName), queryInfo.get().getSession().toIdentity(), accessControl);
checkCanViewQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders), queryInfo.get().getSession().toIdentity(), accessControl);
return Response.ok(queryInfo.get()).build();
}
catch (AccessDeniedException e) {
Expand All @@ -116,7 +114,7 @@ public void cancelQuery(@PathParam("queryId") QueryId queryId, @Context HttpServ

try {
BasicQueryInfo queryInfo = dispatchManager.getQueryInfo(queryId);
checkCanKillQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders, alternateHeaderName), queryInfo.getSession().toIdentity(), accessControl);
checkCanKillQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders), queryInfo.getSession().toIdentity(), accessControl);
dispatchManager.cancelQuery(queryId);
}
catch (AccessDeniedException e) {
Expand Down Expand Up @@ -149,7 +147,7 @@ private Response failQuery(QueryId queryId, TrinoException queryException, HttpS
try {
BasicQueryInfo queryInfo = dispatchManager.getQueryInfo(queryId);

checkCanKillQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders, alternateHeaderName), queryInfo.getSession().toIdentity(), accessControl);
checkCanKillQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders), queryInfo.getSession().toIdentity(), accessControl);

// check before killing to provide the proper error code (this is racy)
if (queryInfo.getState().isDone()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,18 @@ public class QueryStateInfoResource
private final ResourceGroupManager<?> resourceGroupManager;
private final AccessControl accessControl;
private final HttpRequestSessionContextFactory sessionContextFactory;
private final Optional<String> alternateHeaderName;

@Inject
public QueryStateInfoResource(
DispatchManager dispatchManager,
ResourceGroupManager<?> resourceGroupManager,
AccessControl accessControl,
HttpRequestSessionContextFactory sessionContextFactory,
ProtocolConfig protocolConfig)
HttpRequestSessionContextFactory sessionContextFactory)
{
this.dispatchManager = requireNonNull(dispatchManager, "dispatchManager is null");
this.resourceGroupManager = requireNonNull(resourceGroupManager, "resourceGroupManager is null");
this.accessControl = requireNonNull(accessControl, "accessControl is null");
this.sessionContextFactory = requireNonNull(sessionContextFactory, "sessionContextFactory is null");
this.alternateHeaderName = protocolConfig.getAlternateHeaderName();
}

@ResourceSecurity(AUTHENTICATED_USER)
Expand All @@ -79,7 +76,7 @@ public QueryStateInfoResource(
public List<QueryStateInfo> getQueryStateInfos(@QueryParam("user") String user, @Context HttpServletRequest servletRequest, @Context HttpHeaders httpHeaders)
{
List<BasicQueryInfo> queryInfos = dispatchManager.getQueries();
queryInfos = filterQueries(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders, alternateHeaderName), queryInfos, accessControl);
queryInfos = filterQueries(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders), queryInfos, accessControl);

if (!isNullOrEmpty(user)) {
queryInfos = queryInfos.stream()
Expand Down Expand Up @@ -115,7 +112,7 @@ public QueryStateInfo getQueryStateInfo(@PathParam("queryId") String queryId, @C
{
try {
BasicQueryInfo queryInfo = dispatchManager.getQueryInfo(new QueryId(queryId));
checkCanViewQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders, alternateHeaderName), queryInfo.getSession().toIdentity(), accessControl);
checkCanViewQueryOwnedBy(sessionContextFactory.extractAuthorizedIdentity(servletRequest, httpHeaders), queryInfo.getSession().toIdentity(), accessControl);
return getQueryStateInfo(queryInfo);
}
catch (AccessDeniedException e) {
Expand Down
2 changes: 1 addition & 1 deletion core/trino-main/src/main/java/io/trino/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
import io.trino.server.security.oauth2.OAuth2Client;
import io.trino.spi.connector.CatalogHandle;
import io.trino.transaction.TransactionManagerModule;
import io.trino.version.EmbedVersion;
import io.trino.util.EmbedVersion;
import org.weakref.jmx.guice.MBeanModule;

import java.io.IOException;
Expand Down
Loading