SENTRY-904: Set max message size for thrift messages ( Li Li, Reviewed by: Sravya Tirukkovalur)
Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/adc22808 Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/adc22808 Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/adc22808 Branch: refs/heads/hive_plugin_v2 Commit: adc228081c1f93fdfb9804214100c83fa25f5f56 Parents: 60e9b54 Author: Sravya Tirukkovalur <sra...@cloudera.com> Authored: Wed Oct 21 13:53:02 2015 -0700 Committer: Sun Dapeng <s...@apache.org> Committed: Mon Nov 2 16:37:17 2015 +0800 ---------------------------------------------------------------------- .../SentryHDFSServiceClientDefaultImpl.java | 6 +- .../apache/sentry/hdfs/ServiceConstants.java | 4 + .../apache/sentry/hdfs/ThriftSerializer.java | 16 ++- .../sentry/hdfs/TestHMSPathsFullDump.java | 76 +++++++++--- .../SentryGenericServiceClientDefaultImpl.java | 7 +- .../SentryPolicyServiceClientDefaultImpl.java | 7 +- .../sentry/service/thrift/SentryService.java | 5 +- .../sentry/service/thrift/ServiceConstants.java | 7 ++ .../TestSentryServiceWithInvalidMsgSize.java | 119 +++++++++++++++++++ 9 files changed, 218 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java ---------------------------------------------------------------------- diff --git a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java index c727403..03bf39e 100644 --- a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java +++ b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java @@ -154,11 +154,13 @@ public class SentryHDFSServiceClientDefaultImpl implements SentryHDFSServiceClie } LOGGER.info("Successfully opened transport: " + transport + " to " + serverAddress); TProtocol tProtocol = null; + long maxMessageSize = conf.getLong(ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE, + ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT); if (conf.getBoolean(ClientConfig.USE_COMPACT_TRANSPORT, ClientConfig.USE_COMPACT_TRANSPORT_DEFAULT)) { - tProtocol = new TCompactProtocol(transport); + tProtocol = new TCompactProtocol(transport, maxMessageSize, maxMessageSize); } else { - tProtocol = new TBinaryProtocol(transport); + tProtocol = new TBinaryProtocol(transport, maxMessageSize, maxMessageSize, true, true); } TMultiplexedProtocol protocol = new TMultiplexedProtocol( tProtocol, SentryHDFSServiceClient.SENTRY_HDFS_SERVICE_NAME); http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java ---------------------------------------------------------------------- diff --git a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java index 19b0b49..8f62496 100644 --- a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java +++ b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java @@ -80,6 +80,10 @@ public class ServiceConstants { public static final int SERVER_RPC_CONN_TIMEOUT_DEFAULT = 200000; public static final String USE_COMPACT_TRANSPORT = "sentry.hdfs.service.client.compact.transport"; public static final boolean USE_COMPACT_TRANSPORT_DEFAULT = false; + + // max message size for thrift messages + public static String SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE = "sentry.hdfs.thrift.max.message.size"; + public static long SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT = 100 * 1024 * 1024; } } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ThriftSerializer.java ---------------------------------------------------------------------- diff --git a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ThriftSerializer.java b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ThriftSerializer.java index b585773..782367a 100644 --- a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ThriftSerializer.java +++ b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ThriftSerializer.java @@ -19,18 +19,24 @@ package org.apache.sentry.hdfs; import java.io.IOException; +import com.google.common.annotations.VisibleForTesting; import org.apache.thrift.TBase; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; -import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; public class ThriftSerializer { + // Use default max thrift message size here. + // TODO: Figure out a way to make maxMessageSize configurable, eg. create a serializer singleton at startup by + // passing a max_size parameter + @VisibleForTesting + static long maxMessageSize = ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT; + @SuppressWarnings("rawtypes") public static byte[] serialize(TBase baseObject) throws IOException { - TSerializer serializer = new TSerializer(new TCompactProtocol.Factory()); + TSerializer serializer = new TSerializer(new TCompactProtocol.Factory(maxMessageSize, maxMessageSize)); try { return serializer.serialize(baseObject); } catch (TException e) { @@ -40,10 +46,8 @@ public class ThriftSerializer { } @SuppressWarnings("rawtypes") - public static TBase deserialize(TBase baseObject, byte[] serialized) - throws IOException { - TDeserializer deserializer = new TDeserializer( - new TCompactProtocol.Factory()); + public static TBase deserialize(TBase baseObject, byte[] serialized) throws IOException { + TDeserializer deserializer = new TDeserializer(new TCompactProtocol.Factory(maxMessageSize, maxMessageSize)); try { deserializer.deserialize(baseObject, serialized); } catch (TException e) { http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-hdfs/sentry-hdfs-common/src/test/java/org/apache/sentry/hdfs/TestHMSPathsFullDump.java ---------------------------------------------------------------------- diff --git a/sentry-hdfs/sentry-hdfs-common/src/test/java/org/apache/sentry/hdfs/TestHMSPathsFullDump.java b/sentry-hdfs/sentry-hdfs-common/src/test/java/org/apache/sentry/hdfs/TestHMSPathsFullDump.java index f74a75d..d01f7dd 100644 --- a/sentry-hdfs/sentry-hdfs-common/src/test/java/org/apache/sentry/hdfs/TestHMSPathsFullDump.java +++ b/sentry-hdfs/sentry-hdfs-common/src/test/java/org/apache/sentry/hdfs/TestHMSPathsFullDump.java @@ -30,6 +30,12 @@ import org.junit.Test; import com.google.common.collect.Lists; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + public class TestHMSPathsFullDump { private static boolean useCompact = true; @@ -76,6 +82,59 @@ public class TestHMSPathsFullDump { @Test public void testThrftSerialization() throws TException { + HMSPathsDumper serDe = genHMSPathsDumper(); + long t1 = System.currentTimeMillis(); + TPathsDump pathsDump = serDe.createPathsDump(); + + TProtocolFactory protoFactory = useCompact ? new TCompactProtocol.Factory( + ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT, + ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT) + : new TBinaryProtocol.Factory(true, true, + ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT, + ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT); + byte[] ser = new TSerializer(protoFactory).serialize(pathsDump); + long serTime = System.currentTimeMillis() - t1; + System.out.println("Serialization Time: " + serTime + ", " + ser.length); + + t1 = System.currentTimeMillis(); + TPathsDump tPathsDump = new TPathsDump(); + new TDeserializer(protoFactory).deserialize(tPathsDump, ser); + HMSPaths fromDump = serDe.initializeFromDump(tPathsDump); + System.out.println("Deserialization Time: " + (System.currentTimeMillis() - t1)); + Assert.assertEquals("db9.tbl999", fromDump.findAuthzObject(new String[]{"user", "hive", "warehouse", "db9", "tbl999"}, false)); + Assert.assertEquals("db9.tbl999", fromDump.findAuthzObject(new String[]{"user", "hive", "warehouse", "db9", "tbl999", "part99"}, false)); + } + + /** + * Test ThriftSerializer with a larger message than thrift max message size. + */ + @Test + public void testThriftSerializerWithInvalidMsgSize() throws TException, IOException { + HMSPathsDumper serDe = genHMSPathsDumper(); + TPathsDump pathsDump = serDe.createPathsDump(); + byte[] ser =ThriftSerializer.serialize(pathsDump); + + boolean exceptionThrown = false; + try { + // deserialize a msg with a larger size should throw IO exception + ThriftSerializer.maxMessageSize = 1024; + ThriftSerializer.deserialize(new TPathsDump(), ser); + } catch (IOException e) { + exceptionThrown = true; + Assert.assertTrue(e.getCause().getMessage().contains("Length exceeded max allowed:")); + Assert.assertTrue(e.getMessage().contains("Error deserializing thrift object TPathsDump")); + } finally { + Assert.assertEquals(true, exceptionThrown); + } + // deserialize a normal msg should succeed + ThriftSerializer.maxMessageSize = ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT; + ThriftSerializer.deserialize(new TPathsDump(), ser); + } + + /** + * Generate HMSPathsDumper for ThrftSerialization tests + */ + private HMSPathsDumper genHMSPathsDumper() { HMSPaths hmsPaths = new HMSPaths(new String[] {"/"}); String prefix = "/user/hive/warehouse/"; for (int dbNum = 0; dbNum < 10; dbNum++) { @@ -94,22 +153,7 @@ public class TestHMSPathsFullDump { } } } - HMSPathsDumper serDe = hmsPaths.getPathsDump(); - long t1 = System.currentTimeMillis(); - TPathsDump pathsDump = serDe.createPathsDump(); - - TProtocolFactory protoFactory = useCompact ? new TCompactProtocol.Factory() : new TBinaryProtocol.Factory(); - byte[] ser = new TSerializer(protoFactory).serialize(pathsDump); - long serTime = System.currentTimeMillis() - t1; - System.out.println("Serialization Time: " + serTime + ", " + ser.length); - - t1 = System.currentTimeMillis(); - TPathsDump tPathsDump = new TPathsDump(); - new TDeserializer(protoFactory).deserialize(tPathsDump, ser); - HMSPaths fromDump = serDe.initializeFromDump(tPathsDump); - System.out.println("Deserialization Time: " + (System.currentTimeMillis() - t1)); - Assert.assertEquals("db9.tbl999", fromDump.findAuthzObject(new String[]{"user", "hive", "warehouse", "db9", "tbl999"}, false)); - Assert.assertEquals("db9.tbl999", fromDump.findAuthzObject(new String[]{"user", "hive", "warehouse", "db9", "tbl999", "part99"}, false)); + return hmsPaths.getPathsDump(); } } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java index 67a3574..c1eafe4 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java @@ -37,6 +37,7 @@ import org.apache.sentry.SentryUserException; import org.apache.sentry.core.common.ActiveRoleSet; import org.apache.sentry.core.common.Authorizable; import org.apache.sentry.core.model.db.AccessConstants; +import org.apache.sentry.service.thrift.ServiceConstants; import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig; import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig; import org.apache.sentry.service.thrift.Status; @@ -151,9 +152,11 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi throw new IOException("Transport exception while opening transport: " + e.getMessage(), e); } LOGGER.debug("Successfully opened transport: " + transport + " to " + serverAddress); + long maxMessageSize = conf.getLong(ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE, + ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT); TMultiplexedProtocol protocol = new TMultiplexedProtocol( - new TBinaryProtocol(transport), - SentryGenericPolicyProcessor.SENTRY_GENERIC_SERVICE_NAME); + new TBinaryProtocol(transport, maxMessageSize, maxMessageSize, true, true), + SentryGenericPolicyProcessor.SENTRY_GENERIC_SERVICE_NAME); client = new SentryGenericPolicyService.Client(protocol); LOGGER.debug("Successfully created client"); } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java index ae0eec2..74f379a 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java @@ -41,6 +41,7 @@ import org.apache.sentry.core.model.db.AccessConstants; import org.apache.sentry.core.model.db.DBModelAuthorizable; import org.apache.sentry.provider.common.PolicyFileConstants; import org.apache.sentry.service.thrift.SentryServiceUtil; +import org.apache.sentry.service.thrift.ServiceConstants; import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig; import org.apache.sentry.service.thrift.ServiceConstants.PrivilegeScope; import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig; @@ -167,9 +168,11 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService throw new IOException("Transport exception while opening transport: " + e.getMessage(), e); } LOGGER.debug("Successfully opened transport: " + transport + " to " + serverAddress); + long maxMessageSize = conf.getLong(ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE, + ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT); TMultiplexedProtocol protocol = new TMultiplexedProtocol( - new TBinaryProtocol(transport), - SentryPolicyStoreProcessor.SENTRY_POLICY_SERVICE_NAME); + new TBinaryProtocol(transport, maxMessageSize, maxMessageSize, true, true), + SentryPolicyStoreProcessor.SENTRY_POLICY_SERVICE_NAME); client = new SentryPolicyService.Client(protocol); LOGGER.debug("Successfully created client"); } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java index 1af7a8b..26a32e4 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java @@ -91,6 +91,7 @@ public class SentryService implements Callable { private Status status; private int webServerPort; private SentryWebServer sentryWebServer; + private long maxMessageSize; public SentryService(Configuration conf) { this.conf = conf; @@ -110,6 +111,8 @@ public class SentryService implements Callable { ServerConfig.RPC_MAX_THREADS_DEFAULT); minThreads = conf.getInt(ServerConfig.RPC_MIN_THREADS, ServerConfig.RPC_MIN_THREADS_DEFAULT); + maxMessageSize = conf.getLong(ServerConfig.SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE, + ServerConfig.SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE_DEFAULT); if (kerberos) { // Use Hadoop libraries to translate the _HOST placeholder with actual hostname try { @@ -222,7 +225,7 @@ public class SentryService implements Callable { TThreadPoolServer.Args args = new TThreadPoolServer.Args( serverTransport).processor(processor) .transportFactory(transportFactory) - .protocolFactory(new TBinaryProtocol.Factory()) + .protocolFactory(new TBinaryProtocol.Factory(true, true, maxMessageSize, maxMessageSize)) .minWorkerThreads(minThreads).maxWorkerThreads(maxThreads); thriftServer = new TThreadPoolServer(args); LOGGER.info("Serving on " + address); http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java index bc35742..e23e9d7 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java @@ -167,6 +167,10 @@ public class ServiceConstants { public static final String SENTRY_WEB_SECURITY_PRINCIPAL = SENTRY_WEB_SECURITY_PREFIX + ".kerberos.principal"; public static final String SENTRY_WEB_SECURITY_KEYTAB = SENTRY_WEB_SECURITY_PREFIX + ".kerberos.keytab"; public static final String SENTRY_WEB_SECURITY_ALLOW_CONNECT_USERS = SENTRY_WEB_SECURITY_PREFIX + ".allow.connect.users"; + + // max message size for thrift messages + public static String SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE = "sentry.policy.server.thrift.max.message.size"; + public static long SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE_DEFAULT = 100 * 1024 * 1024; } public static class ClientConfig { public static final ImmutableMap<String, String> SASL_PROPERTIES = ServiceConstants.SASL_PROPERTIES; @@ -200,6 +204,9 @@ public class ServiceConstants { public static final String SENTRY_POOL_RETRY_TOTAL = "sentry.service.client.connection.pool.retry-total"; public static final int SENTRY_POOL_RETRY_TOTAL_DEFAULT = 3; + // max message size for thrift messages + public static String SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE = "sentry.policy.client.thrift.max.message.size"; + public static long SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT = 100 * 1024 * 1024; } /** http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/adc22808/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceWithInvalidMsgSize.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceWithInvalidMsgSize.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceWithInvalidMsgSize.java new file mode 100644 index 0000000..09f3d8e --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceWithInvalidMsgSize.java @@ -0,0 +1,119 @@ +/** + * 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.sentry.provider.db.service.thrift; + +import com.google.common.collect.Sets; +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.SentryUserException; +import org.apache.sentry.service.thrift.SentryServiceClientFactory; +import org.apache.sentry.service.thrift.SentryServiceFactory; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.apache.sentry.service.thrift.ServiceConstants; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Set; + +/** + * Test sentry service with a larger message size than the server's or client's thrift max message size. + */ +public class TestSentryServiceWithInvalidMsgSize extends SentryServiceIntegrationBase { + private final Set<String> REQUESTER_USER_GROUP_NAMES = Sets.newHashSet(ADMIN_GROUP); + private final String ROLE_NAME = "admin_r"; + + /** + * Test the case when the message size is larger than the client's thrift max message size. + */ + @Test + public void testClientWithSmallMaxMsgSize() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + Configuration confWithSmallMaxMsgSize = new Configuration(conf); + confWithSmallMaxMsgSize.setLong(ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE, 20); + // create a client with a small thrift max message size + SentryPolicyServiceClient clientWithSmallMaxMsgSize = SentryServiceClientFactory.create(confWithSmallMaxMsgSize); + + setLocalGroupMapping(ADMIN_USER, REQUESTER_USER_GROUP_NAMES); + writePolicyFile(); + + boolean exceptionThrown = false; + try { + // client throws exception when message size is larger than the client's thrift max message size. + clientWithSmallMaxMsgSize.listRoles(ADMIN_USER); + } catch (SentryUserException e) { + exceptionThrown = true; + Assert.assertTrue(e.getMessage().contains("Thrift exception occurred")); + Assert.assertTrue(e.getCause().getMessage().contains("Length exceeded max allowed")); + } finally { + Assert.assertEquals(true, exceptionThrown); + clientWithSmallMaxMsgSize.close(); + } + + // client can still talk with sentry server when message size is smaller. + client.dropRoleIfExists(ADMIN_USER, ROLE_NAME); + client.listRoles(ADMIN_USER); + client.createRole(ADMIN_USER, ROLE_NAME); + client.listRoles(ADMIN_USER); + } + }); + } + + /** + * Test the case when the message size is larger than the server's thrift max message size. + */ + @Test + public void testServerWithSmallMaxMsgSize() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + Configuration confWithSmallMaxMsgSize = new Configuration(conf); + confWithSmallMaxMsgSize.setLong(ServiceConstants.ServerConfig.SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE, + 50); + stopSentryService(); + + // create a server with a small max thrift message size + server = new SentryServiceFactory().create(confWithSmallMaxMsgSize); + startSentryService(); + + setLocalGroupMapping(ADMIN_USER, REQUESTER_USER_GROUP_NAMES); + writePolicyFile(); + + // client can talk with server when message size is smaller. + client.listRoles(ADMIN_USER); + client.createRole(ADMIN_USER, ROLE_NAME); + + boolean exceptionThrown = false; + try { + // client throws exception when message size is larger than the server's thrift max message size. + client.grantServerPrivilege(ADMIN_USER, ROLE_NAME, "server", false); + } catch (SentryUserException e) { + exceptionThrown = true; + Assert.assertTrue(e.getMessage().contains("org.apache.thrift.transport.TTransportException")); + } finally { + Assert.assertEquals(true, exceptionThrown); + } + + // client can still talk with sentry server when message size is smaller. + Set<TSentryRole> roles = client.listRoles(ADMIN_USER); + Assert.assertTrue(roles.size() == 1); + Assert.assertEquals(ROLE_NAME, roles.iterator().next().getRoleName()); + } + }); + } +}