You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by pr...@apache.org on 2014/10/29 19:42:37 UTC
git commit: SENTRY-477: Sentry service should expose metrics (Sravya
Tirukkovalur via Prasad Mujumdar)
Repository: incubator-sentry
Updated Branches:
refs/heads/master e4dc61d52 -> de0cc9e7f
SENTRY-477: Sentry service should expose metrics (Sravya Tirukkovalur via Prasad Mujumdar)
Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/de0cc9e7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/de0cc9e7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/de0cc9e7
Branch: refs/heads/master
Commit: de0cc9e7f62c1a44474b196d521b87d1ff902f0e
Parents: e4dc61d
Author: Prasad Mujumdar <pr...@cloudera.com>
Authored: Wed Oct 29 11:42:28 2014 -0700
Committer: Prasad Mujumdar <pr...@cloudera.com>
Committed: Wed Oct 29 11:42:28 2014 -0700
----------------------------------------------------------------------
pom.xml | 6 +-
sentry-provider/sentry-provider-db/pom.xml | 25 ++++
.../db/service/persistent/SentryStore.java | 42 ++++++
...SentryHealthCheckServletContextListener.java | 35 +++++
.../db/service/thrift/SentryMetrics.java | 135 +++++++++++++++++++
.../SentryMetricsServletContextListener.java | 32 +++++
.../thrift/SentryPolicyStoreProcessor.java | 56 ++++++++
.../db/service/thrift/SentryWebServer.java | 55 ++++++++
.../sentry/service/thrift/SentryService.java | 30 ++++-
.../sentry/service/thrift/ServiceConstants.java | 8 ++
.../db/service/persistent/TestSentryStore.java | 65 +++++++++
.../AbstractTestWithStaticConfiguration.java | 2 +
12 files changed, 486 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e172e92..405367f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,8 +50,8 @@ limitations under the License.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <maven.compile.source>1.6</maven.compile.source>
- <maven.compile.target>1.6</maven.compile.target>
+ <maven.compile.source>1.7</maven.compile.source>
+ <maven.compile.target>1.7</maven.compile.target>
<!-- versions are in alphabetical order -->
<ant.contrib.version>1.0b3</ant.contrib.version>
<maven.antrun.plugin.version>1.7</maven.antrun.plugin.version>
@@ -83,6 +83,8 @@ limitations under the License.
<zookeeper.version>3.4.5-cdh5.1.0-SNAPSHOT</zookeeper.version>
<pig.version>0.12.0-cdh5.1.0-SNAPSHOT</pig.version>
<jackson.version>1.8.8</jackson.version>
+ <metrics.version>3.1.0</metrics.version>
+ <jettyVersion>7.6.16.v20140903</jettyVersion>
</properties>
<dependencyManagement>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/pom.xml b/sentry-provider/sentry-provider-db/pom.xml
index b4167e4..fbf831a 100644
--- a/sentry-provider/sentry-provider-db/pom.xml
+++ b/sentry-provider/sentry-provider-db/pom.xml
@@ -134,6 +134,31 @@ limitations under the License.
<artifactId>datanucleus-rdbms</artifactId>
</dependency>
<dependency>
+ <groupId>io.dropwizard.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ <version>${metrics.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.dropwizard.metrics</groupId>
+ <artifactId>metrics-servlets</artifactId>
+ <version>${metrics.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.dropwizard.metrics</groupId>
+ <artifactId>metrics-jvm</artifactId>
+ <version>${metrics.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>${jettyVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <version>${jettyVersion}</version>
+ </dependency>
+ <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index 017cf08..f6699d2 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -18,6 +18,7 @@
package org.apache.sentry.provider.db.service.persistent;
+import com.codahale.metrics.Gauge;
import static org.apache.sentry.provider.common.ProviderConstants.AUTHORIZABLE_JOINER;
import static org.apache.sentry.provider.common.ProviderConstants.KV_JOINER;
@@ -271,6 +272,47 @@ public class SentryStore {
}
}
+ private <T> Long getCount(Class<T> tClass) {
+ PersistenceManager pm = null;
+ Long size = new Long(-1);
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery();
+ query.setClass(tClass);
+ query.setResult("count(this)");
+ size = (Long)query.execute();
+
+ } finally {
+ commitTransaction(pm);
+ }
+ return size;
+ }
+ public Gauge<Long> getRoleCountGauge() {
+ return new Gauge< Long >() {
+ @Override
+ public Long getValue() {
+ return getCount(MSentryRole.class);
+ }
+ };
+ }
+
+ public Gauge<Long> getPrivilegeCountGauge() {
+ return new Gauge< Long >() {
+ @Override
+ public Long getValue() {
+ return getCount(MSentryPrivilege.class);
+ }
+ };
+ }
+ public Gauge<Long> getGroupCountGauge() {
+ return new Gauge< Long >() {
+ @Override
+ public Long getValue() {
+ return getCount(MSentryGroup.class);
+ }
+ };
+ }
+
public CommitContext alterSentryRoleGrantPrivilege(String grantorPrincipal,
String roleName, TSentryPrivilege privilege)
throws SentryUserException {
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryHealthCheckServletContextListener.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryHealthCheckServletContextListener.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryHealthCheckServletContextListener.java
new file mode 100644
index 0000000..8822c2e
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryHealthCheckServletContextListener.java
@@ -0,0 +1,35 @@
+/**
+ * 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.codahale.metrics.health.HealthCheckRegistry;
+import com.codahale.metrics.servlets.HealthCheckServlet;
+
+/**
+ * Use this class's registry to register health checks: Can be some tests which make sure Sentry service is healthy
+ */
+public class SentryHealthCheckServletContextListener extends HealthCheckServlet.ContextListener {
+
+ //This is just a place holder for health check registry, with out this AdminServlet throws out an error
+ public static final HealthCheckRegistry HEALTH_CHECK_REGISTRY = new HealthCheckRegistry();
+
+ @Override
+ protected HealthCheckRegistry getHealthCheckRegistry() {
+ return HEALTH_CHECK_REGISTRY;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java
new file mode 100644
index 0000000..6bd7e2b
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java
@@ -0,0 +1,135 @@
+/**
+ * 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.codahale.metrics.ConsoleReporter;
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.MetricSet;
+import com.codahale.metrics.Timer;
+import com.codahale.metrics.jvm.BufferPoolMetricSet;
+import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
+import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
+import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
+import org.apache.sentry.provider.db.service.persistent.SentryStore;
+
+import java.lang.management.ManagementFactory;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A singleton class which holds metrics related utility functions as well as the list of metrics
+ */
+public class SentryMetrics {
+ private static SentryMetrics sentryMetrics = null;
+ private boolean reportingInitialized = false;
+
+ public final Timer createRoleTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "create-role"));
+ public final Timer dropRoleTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "drop-role"));
+ public final Timer grantRoleTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "grant-role"));
+ public final Timer revokeRoleTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "revoke-role"));
+ public final Timer grantTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "grant-privilege"));
+ public final Timer revokeTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "revoke-privilege"));
+
+ public final Timer dropPrivilegeTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "drop-privilege"));
+ public final Timer renamePrivilegeTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "rename-privilege"));
+
+ public final Timer listRolesByGroupTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "list-roles-by-group"));
+ public final Timer listPrivilegesByRoleTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "list-privileges-by-role"));
+ public final Timer listPrivilegesForProviderTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "list-privileges-for-provider"));
+ public final Timer listPrivilegesByAuthorizableTimer = SentryMetricsServletContextListener.METRIC_REGISTRY.timer(
+ MetricRegistry.name(SentryPolicyStoreProcessor.class, "list-privileges-by-authorizable"));
+
+ private SentryMetrics() {
+ registerMetricSet("gc", new GarbageCollectorMetricSet(), SentryMetricsServletContextListener.METRIC_REGISTRY);
+ registerMetricSet("buffers", new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()),
+ SentryMetricsServletContextListener.METRIC_REGISTRY);
+ registerMetricSet("memory", new MemoryUsageGaugeSet(), SentryMetricsServletContextListener.METRIC_REGISTRY);
+ registerMetricSet("threads", new ThreadStatesGaugeSet(), SentryMetricsServletContextListener.METRIC_REGISTRY);
+ }
+
+ public static synchronized SentryMetrics getInstance() {
+ if (sentryMetrics == null) {
+ sentryMetrics = new SentryMetrics();
+ }
+ return sentryMetrics;
+ }
+
+ public void addSentryStoreGauges(SentryStore sentryStore) {
+ addGauge(SentryStore.class, "role_count", sentryStore.getRoleCountGauge());
+ addGauge(SentryStore.class, "privilege_count", sentryStore.getPrivilegeCountGauge());
+ addGauge(SentryStore.class, "group_count", sentryStore.getGroupCountGauge());
+ }
+
+
+ /* Should be only called once to initialize the reporters
+ */
+ public synchronized void initReporting(Reporting reporting) {
+ if(!reportingInitialized) {
+ switch(reporting) {
+ case CONSOLE:
+ final ConsoleReporter consoleReporter = ConsoleReporter.forRegistry(SentryMetricsServletContextListener.METRIC_REGISTRY)
+ .convertRatesTo(TimeUnit.SECONDS)
+ .convertDurationsTo(TimeUnit.MILLISECONDS)
+ .build();
+ consoleReporter.start(1, TimeUnit.SECONDS);
+ break;
+ case JMX:
+ final JmxReporter jmxReporter = JmxReporter.forRegistry(SentryMetricsServletContextListener.METRIC_REGISTRY)
+ .convertRatesTo(TimeUnit.SECONDS)
+ .convertDurationsTo(TimeUnit.MILLISECONDS)
+ .build();
+ jmxReporter.start();
+ break;
+ }
+ }
+ }
+
+ private <T, V> void addGauge(Class<T> tClass, String gaugeName, Gauge<V> gauge) {
+ SentryMetricsServletContextListener.METRIC_REGISTRY.register(
+ MetricRegistry.name(tClass, gaugeName), gauge);
+ }
+
+ private void registerMetricSet(String prefix, MetricSet metricSet, MetricRegistry registry) {
+ for (Map.Entry<String, Metric> entry : metricSet.getMetrics().entrySet()) {
+ if (entry.getValue() instanceof MetricSet) {
+ registerMetricSet(prefix + "." + entry.getKey(), (MetricSet) entry.getValue(), registry);
+ } else {
+ registry.register(prefix + "." + entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ public enum Reporting {
+ JMX,
+ CONSOLE;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetricsServletContextListener.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetricsServletContextListener.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetricsServletContextListener.java
new file mode 100644
index 0000000..6692197
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetricsServletContextListener.java
@@ -0,0 +1,32 @@
+/**
+ * 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.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlets.MetricsServlet;
+
+public class SentryMetricsServletContextListener extends MetricsServlet.ContextListener {
+
+ public static final MetricRegistry METRIC_REGISTRY = new MetricRegistry();
+
+ @Override
+ protected MetricRegistry getMetricRegistry() {
+ return METRIC_REGISTRY;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
index d64d019..01077da 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
+import com.codahale.metrics.Timer;
import org.apache.hadoop.conf.Configuration;
import org.apache.sentry.SentryUserException;
import org.apache.sentry.core.model.db.AccessConstants;
@@ -67,6 +68,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
private final NotificationHandlerInvoker notificationHandlerInvoker;
private final ImmutableSet<String> adminGroups;
private boolean isReady;
+ SentryMetrics sentryMetrics;
public SentryPolicyStoreProcessor(String name, Configuration conf) throws Exception {
super();
@@ -79,6 +81,24 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
isReady = true;
adminGroups = ImmutableSet.copyOf(toTrimedLower(Sets.newHashSet(conf.getStrings(
ServerConfig.ADMIN_GROUPS, new String[]{}))));
+ initReporting();
+ }
+
+ private void initReporting() {
+ String sentryReporting = conf.get(ServerConfig.SENTRY_REPORTING);
+ if( sentryReporting != null) {
+ SentryMetrics.Reporting reporting;
+ try {
+ reporting = SentryMetrics.Reporting.valueOf(sentryReporting.toUpperCase());
+ sentryMetrics = SentryMetrics.getInstance();
+ sentryMetrics.addSentryStoreGauges(sentryStore);
+ sentryMetrics.initReporting(reporting);
+
+ } catch (IllegalArgumentException e) {
+ LOGGER.warn("Metrics reporting not configured correctly, please set " + ServerConfig.SENTRY_REPORTING +
+ " to: " + ServerConfig.SENTRY_REPORTING_CONSOLE + "/" + ServerConfig.SENTRY_REPORTING_JMX);
+ }
+ }
}
public void stop() {
@@ -148,6 +168,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TCreateSentryRoleResponse create_sentry_role(
TCreateSentryRoleRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.createRoleTimer.time();
TCreateSentryRoleResponse response = new TCreateSentryRoleResponse();
try {
authorize(request.getRequestorUserName(),
@@ -167,6 +188,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance().createJsonLogEntity(
@@ -177,6 +200,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TAlterSentryRoleGrantPrivilegeResponse alter_sentry_role_grant_privilege
(TAlterSentryRoleGrantPrivilegeRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.grantTimer.time();
TAlterSentryRoleGrantPrivilegeResponse response = new TAlterSentryRoleGrantPrivilegeResponse();
try {
@@ -201,6 +225,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance().createJsonLogEntity(
@@ -211,6 +237,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TAlterSentryRoleRevokePrivilegeResponse alter_sentry_role_revoke_privilege
(TAlterSentryRoleRevokePrivilegeRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.revokeTimer.time();
TAlterSentryRoleRevokePrivilegeResponse response = new TAlterSentryRoleRevokePrivilegeResponse();
try {
CommitContext commitContext = sentryStore.alterSentryRoleRevokePrivilege(request.getRequestorUserName(),
@@ -237,6 +264,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance().createJsonLogEntity(
@@ -247,6 +276,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TDropSentryRoleResponse drop_sentry_role(
TDropSentryRoleRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.dropRoleTimer.time();
TDropSentryRoleResponse response = new TDropSentryRoleResponse();
TSentryResponseStatus status;
try {
@@ -267,6 +297,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance().createJsonLogEntity(
@@ -277,6 +309,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TAlterSentryRoleAddGroupsResponse alter_sentry_role_add_groups(
TAlterSentryRoleAddGroupsRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.grantRoleTimer.time();
TAlterSentryRoleAddGroupsResponse response = new TAlterSentryRoleAddGroupsResponse();
try {
authorize(request.getRequestorUserName(),
@@ -297,6 +330,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance().createJsonLogEntity(
@@ -307,6 +342,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TAlterSentryRoleDeleteGroupsResponse alter_sentry_role_delete_groups(
TAlterSentryRoleDeleteGroupsRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.revokeRoleTimer.time();
TAlterSentryRoleDeleteGroupsResponse response = new TAlterSentryRoleDeleteGroupsResponse();
try {
authorize(request.getRequestorUserName(),
@@ -327,6 +363,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error adding groups to role: " + request;
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance().createJsonLogEntity(
@@ -337,6 +375,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TListSentryRolesResponse list_sentry_roles_by_group(
TListSentryRolesRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.listRolesByGroupTimer.time();
TListSentryRolesResponse response = new TListSentryRolesResponse();
TSentryResponseStatus status;
Set<TSentryRole> roleSet = new HashSet<TSentryRole>();
@@ -373,6 +412,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
return response;
}
@@ -380,6 +421,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TListSentryPrivilegesResponse list_sentry_privileges_by_role(
TListSentryPrivilegesRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.listPrivilegesByRoleTimer.time();
TListSentryPrivilegesResponse response = new TListSentryPrivilegesResponse();
TSentryResponseStatus status;
Set<TSentryPrivilege> privilegeSet = new HashSet<TSentryPrivilege>();
@@ -413,6 +455,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
return response;
}
@@ -424,6 +468,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TListSentryPrivilegesForProviderResponse list_sentry_privileges_for_provider(
TListSentryPrivilegesForProviderRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.listPrivilegesForProviderTimer.time();
TListSentryPrivilegesForProviderResponse response = new TListSentryPrivilegesForProviderResponse();
response.setPrivileges(new HashSet<String>());
try {
@@ -449,6 +494,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
String msg = "Unknown error for request: " + request + ", message: " + e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
return response;
}
@@ -495,6 +542,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TDropPrivilegesResponse drop_sentry_privilege(
TDropPrivilegesRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.dropPrivilegeTimer.time();
TDropPrivilegesResponse response = new TDropPrivilegesResponse();
try {
authorize(request.getRequestorUserName(), adminGroups);
@@ -508,6 +556,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
+ e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
return response;
}
@@ -515,6 +565,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TRenamePrivilegesResponse rename_sentry_privilege(
TRenamePrivilegesRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.renamePrivilegeTimer.time();
TRenamePrivilegesResponse response = new TRenamePrivilegesResponse();
try {
authorize(request.getRequestorUserName(), adminGroups);
@@ -529,6 +580,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
+ e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.close();
}
return response;
}
@@ -536,6 +589,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
@Override
public TListSentryPrivilegesByAuthResponse list_sentry_privileges_by_authorizable(
TListSentryPrivilegesByAuthRequest request) throws TException {
+ final Timer.Context timerContext = sentryMetrics.listPrivilegesByAuthorizableTimer.time();
TListSentryPrivilegesByAuthResponse response = new TListSentryPrivilegesByAuthResponse();
Map<TSentryAuthorizable, TSentryPrivilegeMap> authRoleMap = Maps.newHashMap();
String subject = request.getRequestorUserName();
@@ -586,6 +640,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface {
+ e.getMessage();
LOGGER.error(msg, e);
response.setStatus(Status.RuntimeError(msg, e));
+ } finally {
+ timerContext.stop();
}
return response;
}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java
new file mode 100644
index 0000000..0243c48
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryWebServer.java
@@ -0,0 +1,55 @@
+package org.apache.sentry.provider.db.service.thrift;
+
+/**
+ * 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.
+ */
+
+import com.codahale.metrics.servlets.AdminServlet;
+
+import java.util.EventListener;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+import java.util.List;
+
+public class SentryWebServer {
+ Server server;
+ int port;
+
+ public SentryWebServer(List<EventListener> listeners, int port) {
+ this.port = port;
+ server = new Server(port);
+ ServletContextHandler servletContextHandler = new ServletContextHandler();
+ ServletHolder servletHolder = new ServletHolder(AdminServlet.class);
+ servletContextHandler.addServlet(servletHolder, "/*");
+
+ for(EventListener listener:listeners) {
+ servletContextHandler.addEventListener(listener);
+ }
+
+ server.setHandler(servletContextHandler);
+ }
+
+ public void start() throws Exception{
+ server.start();
+ }
+ public void stop() throws Exception{
+ server.stop();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/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 40e8a0e..8915b4d 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
@@ -25,7 +25,10 @@ import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.EventListener;
import java.util.HashSet;
+import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -45,6 +48,9 @@ import org.apache.hadoop.security.SaslRpcServer;
import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.sentry.Command;
+import org.apache.sentry.provider.db.service.thrift.SentryHealthCheckServletContextListener;
+import org.apache.sentry.provider.db.service.thrift.SentryMetricsServletContextListener;
+import org.apache.sentry.provider.db.service.thrift.SentryWebServer;
import org.apache.sentry.service.thrift.ServiceConstants.ConfUtilties;
import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
import org.apache.thrift.TMultiplexedProcessor;
@@ -55,12 +61,10 @@ import org.apache.thrift.transport.TSaslServerTransport;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportFactory;
-import org.mortbay.log.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
public class SentryService implements Callable {
@@ -83,6 +87,8 @@ public class SentryService implements Callable {
private Future future;
private TServer thriftServer;
private Status status;
+ private int webServerPort;
+ private SentryWebServer sentryWebServer;
public SentryService(Configuration conf) {
this.conf = conf;
@@ -133,6 +139,7 @@ public class SentryService implements Callable {
+ (count++));
}
});
+ webServerPort = conf.getInt(ServerConfig.SENTRY_WEB_PORT, ServerConfig.SENTRY_WEB_PORT_DEFAULT);
status = Status.NOT_STARTED;
}
@@ -210,9 +217,25 @@ public class SentryService implements Callable {
.minWorkerThreads(minThreads).maxWorkerThreads(maxThreads);
thriftServer = new TThreadPoolServer(args);
LOGGER.info("Serving on " + address);
+ startSentryWebServer();
thriftServer.serve();
}
+ private void startSentryWebServer() throws Exception{
+ List<EventListener> listenerList = new ArrayList<EventListener>();
+ listenerList.add(new SentryHealthCheckServletContextListener());
+ listenerList.add(new SentryMetricsServletContextListener());
+ sentryWebServer = new SentryWebServer(listenerList, webServerPort);
+ sentryWebServer.start();
+
+ }
+
+ private void stopSentryWebServer() throws Exception{
+ if( sentryWebServer != null) {
+ sentryWebServer.stop();
+ }
+ }
+
public InetSocketAddress getAddress() {
return address;
}
@@ -231,7 +254,7 @@ public class SentryService implements Callable {
future = serviceExecutor.submit(this);
}
- public synchronized void stop() {
+ public synchronized void stop() throws Exception{
if (status == Status.NOT_STARTED) {
return;
}
@@ -241,6 +264,7 @@ public class SentryService implements Callable {
thriftServer.stop();
}
thriftServer = null;
+ stopSentryWebServer();
status = Status.NOT_STARTED;
LOGGER.info("Stopped...");
}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/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 52eaeed..29a7a1c 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
@@ -24,6 +24,7 @@ import javax.security.sasl.Sasl;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
+import org.apache.sentry.provider.db.service.thrift.SentryMetrics;
public class ServiceConstants {
@@ -122,6 +123,13 @@ public class ServiceConstants {
.put("javax.jdo.option.Multithreaded", "true")
.build();
+ public static final String SENTRY_WEB_PORT = "sentry.service.web.port";
+ public static final int SENTRY_WEB_PORT_DEFAULT = 51000;
+ public static final String SENTRY_REPORTING = "sentry.service.reporting";
+ public static final String SENTRY_REPORTING_JMX = SentryMetrics.Reporting.JMX.name(); //case insensitive
+ public static final String SENTRY_REPORTING_CONSOLE = SentryMetrics.Reporting.CONSOLE.name();//case insensitive
+
+
}
public static class ClientConfig {
public static final ImmutableMap<String, String> SASL_PROPERTIES = ServiceConstants.SASL_PROPERTIES;
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
index befecf4..2e829d6 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
@@ -157,6 +157,7 @@ public class TestSentryStore {
// expected
}
}
+
@Test
public void testCaseSensitiveScope() throws Exception {
String roleName = "role1";
@@ -840,6 +841,69 @@ public class TestSentryStore {
}
}
+ @Test
+ public void testSentryRoleSize() throws Exception {
+ for( long i = 0; i< 5; i++ ) {
+ assertEquals((Long)i, sentryStore.getRoleCountGauge().getValue());
+ sentryStore.createSentryRole("role" + i);
+ }
+ }
+ @Test
+ public void testSentryPrivilegeSize() throws Exception {
+ String role1 = "role1";
+ String role2 = "role2";
+
+ sentryStore.createSentryRole(role1);
+ sentryStore.createSentryRole(role2);
+
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName("server1");
+ privilege.setDbName("db1");
+ privilege.setTableName("tb1");
+ privilege.setCreateTime(System.currentTimeMillis());
+
+ String grantor = "g1";
+
+ assertEquals(new Long(0), sentryStore.getPrivilegeCountGauge().getValue());
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, role1, privilege);
+ assertEquals(new Long(1), sentryStore.getPrivilegeCountGauge().getValue());
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
+ assertEquals(new Long(1), sentryStore.getPrivilegeCountGauge().getValue());
+
+ privilege.setTableName("tb2");
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
+ assertEquals(new Long(2), sentryStore.getPrivilegeCountGauge().getValue());
+ }
+
+ @Test
+ public void testSentryGroupsSize() throws Exception {
+ String role1 = "role1";
+ String role2 = "role2";
+
+ sentryStore.createSentryRole(role1);
+ sentryStore.createSentryRole(role2);
+
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName("group1");
+ groups.add(group);
+
+ String grantor = "g1";
+
+ sentryStore.alterSentryRoleAddGroups(grantor, role1, groups);
+ assertEquals(new Long(1), sentryStore.getGroupCountGauge().getValue());
+
+ sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
+ assertEquals(new Long(1), sentryStore.getGroupCountGauge().getValue());
+
+ groups.add(new TSentryGroup("group2"));
+ sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
+ assertEquals(new Long(2), sentryStore.getGroupCountGauge().getValue());
+
+ }
protected void addGroupsToUser(String user, String... groupNames) {
policyFile.addGroupsToUser(user, groupNames);
}
@@ -847,4 +911,5 @@ public class TestSentryStore {
protected void writePolicyFile() throws Exception {
policyFile.write(policyFilePath);
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/de0cc9e7/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
index f251ebc..f6b6ad4 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
@@ -360,6 +360,7 @@ public abstract class AbstractTestWithStaticConfiguration {
for (Map.Entry<String, String> entry : properties.entrySet()) {
sentryConf.set(entry.getKey(), entry.getValue());
}
+ sentryConf.set(ServerConfig.SENTRY_REPORTING, ServerConfig.SENTRY_REPORTING_CONSOLE);
sentryServer = new SentryServiceFactory().create(sentryConf);
properties.put(ClientConfig.SERVER_RPC_ADDRESS, sentryServer.getAddress()
.getHostName());
@@ -374,6 +375,7 @@ public abstract class AbstractTestWithStaticConfiguration {
properties.put(HiveConf.ConfVars.METASTORE_EVENT_LISTENERS.varname,
SentryMetastorePostEventListener.class.getName());
}
+
}
private static void startSentryService() throws Exception {