You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by co...@apache.org on 2016/06/24 06:00:45 UTC
[16/44] sentry git commit: SENTRY-1287: Create sentry-service-server
module(Colin Ma, reviewed by Dapeng Sun)
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/tools/SentrySchemaTool.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/tools/SentrySchemaTool.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/tools/SentrySchemaTool.java
new file mode 100644
index 0000000..d75e24b
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/tools/SentrySchemaTool.java
@@ -0,0 +1,595 @@
+/**
+ * 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.tools;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.IllegalFormatException;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hive.beeline.BeeLine;
+import org.apache.sentry.Command;
+import org.apache.sentry.core.common.exception.SentryUserException;
+import org.apache.sentry.core.common.exception.SentrySiteConfigurationException;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreSchemaInfo;
+import org.apache.sentry.provider.db.tools.SentrySchemaHelper.NestedScriptParser;
+import org.apache.sentry.service.thrift.SentryService;
+import org.apache.sentry.service.thrift.ServiceConstants;
+
+public class SentrySchemaTool {
+ private static final String SENTRY_SCRIP_DIR = File.separatorChar + "scripts"
+ + File.separatorChar + "sentrystore" + File.separatorChar + "upgrade";
+ private String userName = null;
+ private String passWord = null;
+ private String connectionURL = null;
+ private String driver = null;
+ private boolean dryRun = false;
+ private String dbOpts = null;
+ private boolean verbose = false;
+ private final Configuration sentryConf;
+ private final String dbType;
+ private final SentryStoreSchemaInfo sentryStoreSchemaInfo;
+
+ public SentrySchemaTool(Configuration sentryConf, String dbType)
+ throws SentryUserException, IOException {
+ this(System.getenv("SENTRY_HOME") + SENTRY_SCRIP_DIR, sentryConf, dbType);
+ }
+
+ public SentrySchemaTool(String sentryScripPath, Configuration sentryConf,
+ String dbType) throws SentryUserException, IOException {
+ if (sentryScripPath == null || sentryScripPath.isEmpty()) {
+ throw new SentryUserException("No Sentry script dir provided");
+ }
+ this.sentryConf = sentryConf;
+ this.dbType = dbType;
+ this.sentryStoreSchemaInfo = new SentryStoreSchemaInfo(sentryScripPath,
+ dbType);
+ userName = sentryConf.get(ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_USER,
+ ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_USER_DEFAULT);
+ //Password will be read from Credential provider specified using property
+ // CREDENTIAL_PROVIDER_PATH("hadoop.security.credential.provider.path" in sentry-site.xml
+ // it falls back to reading directly from sentry-site.xml
+ char[] passTmp = sentryConf.getPassword(ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_PASS);
+ if(passTmp != null) {
+ passWord = new String(passTmp);
+ } else {
+ throw new SentrySiteConfigurationException("Error reading " + ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_PASS);
+ }
+
+ try {
+ connectionURL = getValidConfVar(ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_URL);
+ if(dbType.equalsIgnoreCase(SentrySchemaHelper.DB_DERBY)) {
+ driver = sentryConf.get(ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_DRIVER,
+ ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_DRIVER_DEFAULT);
+ } else {
+ driver = getValidConfVar(ServiceConstants.ServerConfig.SENTRY_STORE_JDBC_DRIVER);
+ }
+ // load required JDBC driver
+ Class.forName(driver);
+ } catch (IOException e) {
+ throw new SentryUserException("Missing property: " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ throw new SentryUserException("Failed to load driver", e);
+ }
+ }
+
+ public Configuration getConfiguration() {
+ return sentryConf;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public void setDryRun(boolean dryRun) {
+ this.dryRun = dryRun;
+ }
+
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ public String getDbOpts() {
+ return dbOpts;
+ }
+
+ public void setDbOpts(String dbOpts) {
+ this.dbOpts = dbOpts;
+ }
+
+ private static void printAndExit(Options cmdLineOptions) {
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("schemaTool", cmdLineOptions);
+ System.exit(1);
+ }
+
+ /***
+ * Print Hive version and schema version
+ * @throws SentryUserException
+ */
+ public void showInfo() throws SentryUserException {
+ Connection sentryStoreConn = getConnectionToMetastore(true);
+ System.out.println("Sentry distribution version:\t "
+ + SentryStoreSchemaInfo.getSentryVersion());
+ System.out.println("SentryStore schema version:\t "
+ + getMetaStoreSchemaVersion(sentryStoreConn));
+ }
+
+ // read schema version from sentry store
+ private String getMetaStoreSchemaVersion(Connection sentryStoreConn)
+ throws SentryUserException {
+ String versionQuery;
+ if (SentrySchemaHelper.getDbCommandParser(dbType).needsQuotedIdentifier()) {
+ versionQuery = "select t.\"SCHEMA_VERSION\" from \"SENTRY_VERSION\" t";
+ } else {
+ versionQuery = "select t.SCHEMA_VERSION from SENTRY_VERSION t";
+ }
+ try (Statement stmt = sentryStoreConn.createStatement();
+ ResultSet res = stmt.executeQuery(versionQuery)) {
+ if (!res.next()) {
+ throw new SentryUserException("Didn't find version data in sentry store");
+ }
+ String currentSchemaVersion = res.getString(1);
+ sentryStoreConn.close();
+ return currentSchemaVersion;
+ } catch (SQLException e) {
+ throw new SentryUserException("Failed to get schema version.", e);
+ }
+ }
+
+ // test the connection sentry store using the config property
+ private void testConnectionToMetastore() throws SentryUserException {
+ try (Connection conn = getConnectionToMetastore(true)) {
+ conn.close();
+ } catch (SQLException e) {
+ throw new SentryUserException("Failed to close sentry store connection", e);
+ }
+ }
+
+ /***
+ * get JDBC connection to sentry store db
+ *
+ * @param printInfo print connection parameters
+ * @return
+ * @throws SentryUserException
+ */
+ private Connection getConnectionToMetastore(boolean printInfo)
+ throws SentryUserException {
+ if (printInfo) {
+ System.out.println("Sentry store connection URL:\t " + connectionURL);
+ System.out.println("Sentry store Connection Driver :\t " + driver);
+ System.out.println("Sentry store connection User:\t " + userName);
+ }
+ if (userName == null || userName.isEmpty()) {
+ throw new SentryUserException("UserName empty ");
+ }
+ try {
+ // Connect using the JDBC URL and user/pass from conf
+ return DriverManager.getConnection(connectionURL, userName, passWord);
+ } catch (SQLException e) {
+ throw new SentryUserException("Failed to make connection to Sentry store.", e);
+ }
+ }
+
+ /**
+ * check if the current schema version in sentry store matches the Hive version
+ * @throws SentryUserException
+ */
+ public void verifySchemaVersion() throws SentryUserException {
+ // don't check version if its a dry run
+ if (dryRun) {
+ return;
+ }
+ String newSchemaVersion =
+ getMetaStoreSchemaVersion(getConnectionToMetastore(false));
+ // verify that the new version is added to schema
+ if (!sentryStoreSchemaInfo.getSentrySchemaVersion().equalsIgnoreCase(
+ newSchemaVersion)) {
+ throw new SentryUserException("Found unexpected schema version "
+ + newSchemaVersion);
+ }
+ }
+
+ /**
+ * Perform sentry store schema upgrade. extract the current schema version from sentry store
+ * @throws SentryUserException
+ */
+ public void doUpgrade() throws SentryUserException {
+ String fromVersion = getMetaStoreSchemaVersion(getConnectionToMetastore(false));
+ if (fromVersion == null || fromVersion.isEmpty()) {
+ throw new SentryUserException(
+ "Schema version not stored in the sentry store. "
+ +
+ "Metastore schema is too old or corrupt. Try specifying the version manually");
+ }
+ doUpgrade(fromVersion);
+ }
+
+ /**
+ * Perform sentry store schema upgrade
+ *
+ * @param fromSchemaVer
+ * Existing version of the sentry store. If null, then read from the sentry store
+ * @throws SentryUserException
+ */
+ public void doUpgrade(String fromSchemaVer) throws SentryUserException {
+ if (sentryStoreSchemaInfo.getSentrySchemaVersion().equals(fromSchemaVer)) {
+ System.out.println("No schema upgrade required from version " + fromSchemaVer);
+ return;
+ }
+ // Find the list of scripts to execute for this upgrade
+ List<String> upgradeScripts =
+ sentryStoreSchemaInfo.getUpgradeScripts(fromSchemaVer);
+ testConnectionToMetastore();
+ System.out.println("Starting upgrade sentry store schema from version " +
+ fromSchemaVer + " to "
+ + sentryStoreSchemaInfo.getSentrySchemaVersion());
+ String scriptDir = sentryStoreSchemaInfo.getSentryStoreScriptDir();
+ try {
+ for (String scriptFile : upgradeScripts) {
+ System.out.println("Upgrade script " + scriptFile);
+ if (!dryRun) {
+ runBeeLine(scriptDir, scriptFile);
+ System.out.println("Completed " + scriptFile);
+ }
+ }
+ } catch (IOException eIO) {
+ throw new SentryUserException(
+ "Upgrade FAILED! Metastore state would be inconsistent !!", eIO);
+ }
+
+ // Revalidated the new version after upgrade
+ verifySchemaVersion();
+ }
+
+ /**
+ * Initialize the sentry store schema to current version
+ *
+ * @throws SentryUserException
+ */
+ public void doInit() throws SentryUserException {
+ doInit(sentryStoreSchemaInfo.getSentrySchemaVersion());
+
+ // Revalidated the new version after upgrade
+ verifySchemaVersion();
+ }
+
+ /**
+ * Initialize the sentry store schema
+ *
+ * @param toVersion
+ * If null then current hive version is used
+ * @throws SentryUserException
+ */
+ public void doInit(String toVersion) throws SentryUserException {
+ testConnectionToMetastore();
+ System.out.println("Starting sentry store schema initialization to " + toVersion);
+
+ String initScriptDir = sentryStoreSchemaInfo.getSentryStoreScriptDir();
+ String initScriptFile = sentryStoreSchemaInfo.generateInitFileName(toVersion);
+
+ try {
+ System.out.println("Initialization script " + initScriptFile);
+ if (!dryRun) {
+ runBeeLine(initScriptDir, initScriptFile);
+ System.out.println("Initialization script completed");
+ }
+ } catch (IOException e) {
+ throw new SentryUserException("Schema initialization FAILED!"
+ + " Metastore state would be inconsistent !!", e);
+ }
+ }
+
+ // Flatten the nested upgrade script into a buffer
+ public static String buildCommand(NestedScriptParser dbCommandParser,
+ String scriptDir, String scriptFile) throws IllegalFormatException, IOException {
+
+ BufferedReader bfReader =
+ new BufferedReader(new FileReader(scriptDir + File.separatorChar + scriptFile));
+ String currLine;
+ StringBuilder sb = new StringBuilder();
+ String currentCommand = null;
+ while ((currLine = bfReader.readLine()) != null) {
+ currLine = currLine.trim();
+ if (currLine.isEmpty()) {
+ continue; // skip empty lines
+ }
+
+ if (currentCommand == null) {
+ currentCommand = currLine;
+ } else {
+ currentCommand = currentCommand + " " + currLine;
+ }
+ if (dbCommandParser.isPartialCommand(currLine)) {
+ // if its a partial line, continue collecting the pieces
+ continue;
+ }
+
+ // if this is a valid executable command then add it to the buffer
+ if (!dbCommandParser.isNonExecCommand(currentCommand)) {
+ currentCommand = dbCommandParser.cleanseCommand(currentCommand);
+
+ if (dbCommandParser.isNestedScript(currentCommand)) {
+ // if this is a nested sql script then flatten it
+ String currScript = dbCommandParser.getScriptName(currentCommand);
+ sb.append(buildCommand(dbCommandParser, scriptDir, currScript));
+ } else {
+ // Now we have a complete statement, process it
+ // write the line to buffer
+ sb.append(currentCommand);
+ sb.append(System.getProperty("line.separator"));
+ }
+ }
+ currentCommand = null;
+ }
+ bfReader.close();
+ return sb.toString();
+ }
+
+ // run beeline on the given sentry store scrip, flatten the nested scripts into single file
+ private void runBeeLine(String scriptDir, String scriptFile) throws IOException {
+ NestedScriptParser dbCommandParser =
+ SentrySchemaHelper.getDbCommandParser(dbType);
+ dbCommandParser.setDbOpts(getDbOpts());
+ // expand the nested script
+ String sqlCommands = buildCommand(dbCommandParser, scriptDir, scriptFile);
+ File tmpFile = File.createTempFile("schematool", ".sql");
+ tmpFile.deleteOnExit();
+
+ // write out the buffer into a file. Add beeline commands for autocommit and close
+ try (FileWriter fstream = new FileWriter(tmpFile.getPath());
+ BufferedWriter out = new BufferedWriter(fstream)) {
+
+ out.write("!set Silent " + verbose + System.getProperty("line.separator"));
+ out.write("!autocommit on" + System.getProperty("line.separator"));
+ out.write("!set Isolation TRANSACTION_READ_COMMITTED"
+ + System.getProperty("line.separator"));
+ out.write("!set AllowMultiLineCommand false"
+ + System.getProperty("line.separator"));
+ out.write(sqlCommands);
+ out.write("!closeall" + System.getProperty("line.separator"));
+ out.close();
+ }
+ runBeeLine(tmpFile.getPath());
+ }
+
+ // Generate the beeline args per hive conf and execute the given script
+ public void runBeeLine(String sqlScriptFile) throws IOException {
+ List<String> argList = new ArrayList<String>();
+ argList.add("-u");
+ argList.add(connectionURL);
+ argList.add("-d");
+ argList
+ .add(driver);
+ argList.add("-n");
+ argList.add(userName);
+ argList.add("-p");
+ argList.add(passWord);
+ argList.add("-f");
+ argList.add(sqlScriptFile);
+
+ BeeLine beeLine = new BeeLine();
+ if (!verbose) {
+ beeLine.setOutputStream(new PrintStream(new NullOutputStream()));
+ // beeLine.getOpts().setSilent(true);
+ }
+ // beeLine.getOpts().setAllowMultiLineCommand(false);
+ // beeLine.getOpts().setIsolation("TRANSACTION_READ_COMMITTED");
+ int status = beeLine.begin(argList.toArray(new String[0]), null);
+ if (status != 0) {
+ throw new IOException("Schema script failed, errorcode " + status);
+ }
+ }
+
+ private String getValidConfVar(String confVar) throws IOException {
+ String confVarKey = confVar;
+ String confVarValue = sentryConf.get(confVarKey);
+ if (confVarValue == null || confVarValue.isEmpty()) {
+ throw new IOException("Empty " + confVar);
+ }
+ return confVarValue;
+ }
+
+ // Create the required command line options
+ @SuppressWarnings("static-access")
+ private static void initOptions(Options cmdLineOptions) {
+ Option help = new Option("help", "print this message");
+ Option upgradeOpt = new Option("upgradeSchema", "Schema upgrade");
+ Option upgradeFromOpt = OptionBuilder.withArgName("upgradeFrom").hasArg().
+ withDescription("Schema upgrade from a version").
+ create("upgradeSchemaFrom");
+ Option initOpt = new Option("initSchema", "Schema initialization");
+ Option initToOpt = OptionBuilder.withArgName("initTo").hasArg().
+ withDescription("Schema initialization to a version").
+ create("initSchemaTo");
+ Option infoOpt = new Option("info", "Show config and schema details");
+
+ OptionGroup optGroup = new OptionGroup();
+ optGroup.addOption(upgradeOpt).addOption(initOpt).
+ addOption(help).addOption(upgradeFromOpt).
+ addOption(initToOpt).addOption(infoOpt);
+ optGroup.setRequired(true);
+
+ Option userNameOpt = OptionBuilder.withArgName("user")
+ .hasArg()
+ .withDescription("Override config file user name")
+ .create("userName");
+ Option passwdOpt = OptionBuilder.withArgName("password")
+ .hasArg()
+ .withDescription("Override config file password")
+ .create("passWord");
+ Option dbTypeOpt = OptionBuilder.withArgName("databaseType")
+ .hasArg().withDescription("Metastore database type [" +
+ SentrySchemaHelper.DB_DERBY + "," +
+ SentrySchemaHelper.DB_MYSQL + "," +
+ SentrySchemaHelper.DB_ORACLE + "," +
+ SentrySchemaHelper.DB_POSTGRACE + "," +
+ SentrySchemaHelper.DB_DB2 + "]")
+ .create("dbType");
+ Option dbOpts = OptionBuilder.withArgName("databaseOpts")
+ .hasArgs().withDescription("Backend DB specific options")
+ .create("dbOpts");
+
+ Option dryRunOpt = new Option("dryRun", "list SQL scripts (no execute)");
+ Option verboseOpt = new Option("verbose", "only print SQL statements");
+
+ Option configOpt = OptionBuilder.withArgName("confName").hasArgs()
+ .withDescription("Sentry Service configuration file").isRequired(true)
+ .create(ServiceConstants.ServiceArgs.CONFIG_FILE_LONG);
+
+ cmdLineOptions.addOption(help);
+ cmdLineOptions.addOption(dryRunOpt);
+ cmdLineOptions.addOption(userNameOpt);
+ cmdLineOptions.addOption(passwdOpt);
+ cmdLineOptions.addOption(dbTypeOpt);
+ cmdLineOptions.addOption(verboseOpt);
+ cmdLineOptions.addOption(dbOpts);
+ cmdLineOptions.addOption(configOpt);
+ cmdLineOptions.addOptionGroup(optGroup);
+ }
+
+ public static class CommandImpl implements Command {
+ @Override
+ public void run(String[] args) throws Exception {
+ CommandLineParser parser = new GnuParser();
+ CommandLine line = null;
+ String dbType = null;
+ String schemaVer = null;
+ Options cmdLineOptions = new Options();
+ String configFileName = null;
+
+ // Argument handling
+ initOptions(cmdLineOptions);
+ try {
+ line = parser.parse(cmdLineOptions, args);
+ } catch (ParseException e) {
+ System.err.println("SentrySchemaTool:Parsing failed. Reason: "
+ + e.getLocalizedMessage());
+ printAndExit(cmdLineOptions);
+ }
+
+ if (line.hasOption("help")) {
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("schemaTool", cmdLineOptions);
+ return;
+ }
+
+ if (line.hasOption("dbType")) {
+ dbType = line.getOptionValue("dbType");
+ if (!dbType.equalsIgnoreCase(SentrySchemaHelper.DB_DERBY)
+ && !dbType.equalsIgnoreCase(SentrySchemaHelper.DB_MYSQL)
+ && !dbType.equalsIgnoreCase(SentrySchemaHelper.DB_POSTGRACE)
+ && !dbType.equalsIgnoreCase(SentrySchemaHelper.DB_ORACLE)
+ && !dbType.equalsIgnoreCase(SentrySchemaHelper.DB_DB2)) {
+ System.err.println("Unsupported dbType " + dbType);
+ printAndExit(cmdLineOptions);
+ }
+ } else {
+ System.err.println("no dbType supplied");
+ printAndExit(cmdLineOptions);
+ }
+ if (line.hasOption(ServiceConstants.ServiceArgs.CONFIG_FILE_LONG)) {
+ configFileName = line
+ .getOptionValue(ServiceConstants.ServiceArgs.CONFIG_FILE_LONG);
+ } else {
+ System.err.println("no config file specified");
+ printAndExit(cmdLineOptions);
+ }
+ try {
+ SentrySchemaTool schemaTool = new SentrySchemaTool(
+ SentryService.loadConfig(configFileName), dbType);
+
+ if (line.hasOption("userName")) {
+ schemaTool.setUserName(line.getOptionValue("userName"));
+ }
+ if (line.hasOption("passWord")) {
+ schemaTool.setPassWord(line.getOptionValue("passWord"));
+ }
+ if (line.hasOption("dryRun")) {
+ schemaTool.setDryRun(true);
+ }
+ if (line.hasOption("verbose")) {
+ schemaTool.setVerbose(true);
+ }
+ if (line.hasOption("dbOpts")) {
+ schemaTool.setDbOpts(line.getOptionValue("dbOpts"));
+ }
+
+ if (line.hasOption("info")) {
+ schemaTool.showInfo();
+ } else if (line.hasOption("upgradeSchema")) {
+ schemaTool.doUpgrade();
+ } else if (line.hasOption("upgradeSchemaFrom")) {
+ schemaVer = line.getOptionValue("upgradeSchemaFrom");
+ schemaTool.doUpgrade(schemaVer);
+ } else if (line.hasOption("initSchema")) {
+ schemaTool.doInit();
+ } else if (line.hasOption("initSchemaTo")) {
+ schemaVer = line.getOptionValue("initSchemaTo");
+ schemaTool.doInit(schemaVer);
+ } else {
+ System.err.println("no valid option supplied");
+ printAndExit(cmdLineOptions);
+ }
+ } catch (SentryUserException e) {
+ System.err.println(e);
+ if (line.hasOption("verbose")) {
+ e.printStackTrace();
+ }
+ System.err.println("*** Sentry schemaTool failed ***");
+ System.exit(1);
+ } catch (MalformedURLException e) {
+ System.err.println(e);
+ if (line.hasOption("verbose")) {
+ e.printStackTrace();
+ }
+ System.err.println("*** Sentry schemaTool failed ***");
+ System.exit(1);
+ }
+ System.out.println("Sentry schemaTool completed");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/GSSCallback.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/GSSCallback.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/GSSCallback.java
new file mode 100644
index 0000000..b668b95
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/GSSCallback.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.sentry.service.thrift;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.SaslRpcServer;
+import org.apache.sentry.core.common.exception.ConnectionDeniedException;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+
+public class GSSCallback extends SaslRpcServer.SaslGssCallbackHandler {
+
+ private final Configuration conf;
+ public GSSCallback(Configuration conf) {
+ super();
+ this.conf = conf;
+ }
+
+ boolean comparePrincipals(String principal1, String principal2) {
+ String[] principalParts1 = SaslRpcServer.splitKerberosName(principal1);
+ String[] principalParts2 = SaslRpcServer.splitKerberosName(principal2);
+ if (principalParts1.length == 0 || principalParts2.length == 0) {
+ return false;
+ }
+ if (principalParts1.length == principalParts2.length) {
+ for (int i=0; i < principalParts1.length; i++) {
+ if (!principalParts1[i].equals(principalParts2[i])) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ boolean allowConnect(String principal) {
+ String allowedPrincipals = conf.get(ServerConfig.ALLOW_CONNECT);
+ if (allowedPrincipals == null) {
+ return false;
+ }
+ String principalShortName = getShortName(principal);
+ List<String> items = Arrays.asList(allowedPrincipals.split("\\s*,\\s*"));
+ for (String item : items) {
+ if (comparePrincipals(item, principalShortName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private String getShortName(String principal) {
+ String parts[] = SaslRpcServer.splitKerberosName(principal);
+ return parts[0];
+ }
+
+ @Override
+ public void handle(Callback[] callbacks)
+ throws UnsupportedCallbackException, ConnectionDeniedException {
+ AuthorizeCallback ac = null;
+ for (Callback callback : callbacks) {
+ if (callback instanceof AuthorizeCallback) {
+ ac = (AuthorizeCallback) callback;
+ } else {
+ throw new UnsupportedCallbackException(callback,
+ "Unrecognized SASL GSSAPI Callback");
+ }
+ }
+ if (ac != null) {
+ String authid = ac.getAuthenticationID();
+ String authzid = ac.getAuthorizationID();
+
+ if (allowConnect(authid)) {
+ if (authid.equals(authzid)) {
+ ac.setAuthorized(true);
+ } else {
+ ac.setAuthorized(false);
+ }
+ if (ac.isAuthorized()) {
+ ac.setAuthorizedID(authzid);
+ }
+ } else {
+ throw new ConnectionDeniedException(ac,
+ "Connection to sentry service denied due to lack of client credentials",
+ authid);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/KerberosConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/KerberosConfiguration.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/KerberosConfiguration.java
new file mode 100644
index 0000000..41e4fe4
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/KerberosConfiguration.java
@@ -0,0 +1,107 @@
+/**
+ * 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.service.thrift;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.login.AppConfigurationEntry;
+
+public class KerberosConfiguration extends javax.security.auth.login.Configuration {
+ private String principal;
+ private String keytab;
+ private boolean isInitiator;
+ private static final boolean IBM_JAVA = System.getProperty("java.vendor").contains("IBM");
+
+ private KerberosConfiguration(String principal, File keytab,
+ boolean client) {
+ this.principal = principal;
+ this.keytab = keytab.getAbsolutePath();
+ this.isInitiator = client;
+ }
+
+ public static javax.security.auth.login.Configuration createClientConfig(String principal,
+ File keytab) {
+ return new KerberosConfiguration(principal, keytab, true);
+ }
+
+ public static javax.security.auth.login.Configuration createServerConfig(String principal,
+ File keytab) {
+ return new KerberosConfiguration(principal, keytab, false);
+ }
+
+ private static String getKrb5LoginModuleName() {
+ return (IBM_JAVA ? "com.ibm.security.auth.module.Krb5LoginModule"
+ : "com.sun.security.auth.module.Krb5LoginModule");
+ }
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+ Map<String, String> options = new HashMap<String, String>();
+
+ if (IBM_JAVA) {
+ // IBM JAVA's UseKeytab covers both keyTab and useKeyTab options
+ options.put("useKeytab",keytab.startsWith("file://") ? keytab : "file://" + keytab);
+
+ options.put("principal", principal);
+ options.put("refreshKrb5Config", "true");
+
+ // Both "initiator" and "acceptor"
+ options.put("credsType", "both");
+ } else {
+ options.put("keyTab", keytab);
+ options.put("principal", principal);
+ options.put("useKeyTab", "true");
+ options.put("storeKey", "true");
+ options.put("doNotPrompt", "true");
+ options.put("useTicketCache", "true");
+ options.put("renewTGT", "true");
+ options.put("refreshKrb5Config", "true");
+ options.put("isInitiator", Boolean.toString(isInitiator));
+ }
+
+ String ticketCache = System.getenv("KRB5CCNAME");
+ if (IBM_JAVA) {
+ // If cache is specified via env variable, it takes priority
+ if (ticketCache != null) {
+ // IBM JAVA only respects system property so copy ticket cache to system property
+ // The first value searched when "useDefaultCcache" is true.
+ System.setProperty("KRB5CCNAME", ticketCache);
+ } else {
+ ticketCache = System.getProperty("KRB5CCNAME");
+ }
+
+ if (ticketCache != null) {
+ options.put("useDefaultCcache", "true");
+ options.put("renewTGT", "true");
+ }
+ } else {
+ if (ticketCache != null) {
+ options.put("ticketCache", ticketCache);
+ }
+ }
+ options.put("debug", "true");
+
+ return new AppConfigurationEntry[]{
+ new AppConfigurationEntry(getKrb5LoginModuleName(),
+ AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+ options)};
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
new file mode 100644
index 0000000..a3bb6ab
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
@@ -0,0 +1,31 @@
+/**
+ * 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.service.thrift;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.thrift.TMultiplexedProcessor;
+
+public abstract class ProcessorFactory {
+ protected final Configuration conf;
+
+ public ProcessorFactory(Configuration conf) {
+ this.conf = conf;
+ }
+
+ public abstract boolean register(TMultiplexedProcessor processor) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryKerberosContext.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryKerberosContext.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryKerberosContext.java
new file mode 100644
index 0000000..f54f161
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryKerberosContext.java
@@ -0,0 +1,157 @@
+/**
+ * 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.service.thrift;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
+
+public class SentryKerberosContext implements Runnable {
+ private static final float TICKET_RENEW_WINDOW = 0.80f;
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(SentryKerberosContext.class);
+ private LoginContext loginContext;
+ private Subject subject;
+ private final javax.security.auth.login.Configuration kerberosConfig;
+ @Deprecated
+ private Thread renewerThread;
+ @Deprecated
+ private boolean shutDownRenewer = false;
+
+ public SentryKerberosContext(String principal, String keyTab, boolean autoRenewTicket)
+ throws LoginException {
+ subject = new Subject(false, Sets.newHashSet(new KerberosPrincipal(principal)),
+ new HashSet<Object>(), new HashSet<Object>());
+ kerberosConfig = KerberosConfiguration.createClientConfig(principal, new File(keyTab));
+ loginWithNewContext();
+ if (autoRenewTicket) {
+ startRenewerThread();
+ }
+ }
+
+ private void loginWithNewContext() throws LoginException {
+ LOGGER.info("Logging in with new Context");
+ logoutSubject();
+ loginContext = new LoginContext("", subject, null, kerberosConfig);
+ loginContext.login();
+ subject = loginContext.getSubject();
+ }
+
+ private void logoutSubject() {
+ if (loginContext != null) {
+ try {
+ loginContext.logout();
+ } catch (LoginException e) {
+ LOGGER.warn("Error logging out the subject", e);
+ }
+ }
+ loginContext = null;
+ }
+
+ public Subject getSubject() {
+ return subject;
+ }
+
+ /**
+ * Get the Kerberos TGT
+ * @return the user's TGT or null if none was found
+ */
+ @Deprecated
+ private KerberosTicket getTGT() {
+ Set<KerberosTicket> tickets = subject.getPrivateCredentials(KerberosTicket.class);
+ for(KerberosTicket ticket: tickets) {
+ KerberosPrincipal server = ticket.getServer();
+ if (server.getName().equals("krbtgt/" + server.getRealm() +
+ "@" + server.getRealm())) {
+ return ticket;
+ }
+ }
+ return null;
+ }
+
+ @Deprecated
+ private long getRefreshTime(KerberosTicket tgt) {
+ long start = tgt.getStartTime().getTime();
+ long end = tgt.getEndTime().getTime();
+ LOGGER.debug("Ticket start time: " + start);
+ LOGGER.debug("Ticket End time: " + end);
+ return start + (long) ((end - start) * TICKET_RENEW_WINDOW);
+ }
+
+ /***
+ * Ticket renewer thread
+ * wait till 80% time interval left on the ticket and then renew it
+ */
+ @Deprecated
+ @Override
+ public void run() {
+ try {
+ LOGGER.info("Sentry Ticket renewer thread started");
+ while (!shutDownRenewer) {
+ KerberosTicket tgt = getTGT();
+ if (tgt == null) {
+ LOGGER.warn("No ticket found in the cache");
+ return;
+ }
+ long nextRefresh = getRefreshTime(tgt);
+ while (System.currentTimeMillis() < nextRefresh) {
+ Thread.sleep(1000);
+ if (shutDownRenewer) {
+ return;
+ }
+ }
+ loginWithNewContext();
+ LOGGER.debug("Renewed ticket");
+ }
+ } catch (InterruptedException e1) {
+ LOGGER.warn("Sentry Ticket renewer thread interrupted", e1);
+ return;
+ } catch (LoginException e) {
+ LOGGER.warn("Failed to renew ticket", e);
+ } finally {
+ logoutSubject();
+ LOGGER.info("Sentry Ticket renewer thread finished");
+ }
+ }
+
+ @Deprecated
+ public void startRenewerThread() {
+ renewerThread = new Thread(this);
+ renewerThread.start();
+ }
+
+ public void shutDown() throws LoginException {
+ if (renewerThread != null) {
+ shutDownRenewer = true;
+ } else {
+ logoutSubject();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryService.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryService.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryService.java
new file mode 100644
index 0000000..5783649
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryService.java
@@ -0,0 +1,426 @@
+/**
+ * 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.service.thrift;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+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.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+
+import javax.security.auth.Subject;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.net.NetUtils;
+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;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.server.TServer;
+import org.apache.thrift.server.TServerEventHandler;
+import org.apache.thrift.server.TThreadPoolServer;
+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.eclipse.jetty.util.MultiException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+public class SentryService implements Callable {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(SentryService.class);
+
+ private static enum Status {
+ NOT_STARTED(), STARTED();
+ }
+
+ private final Configuration conf;
+ private final InetSocketAddress address;
+ private final int maxThreads;
+ private final int minThreads;
+ private boolean kerberos;
+ private final String principal;
+ private final String[] principalParts;
+ private final String keytab;
+ private final ExecutorService serviceExecutor;
+ private Future serviceStatus;
+ private TServer thriftServer;
+ private Status status;
+ private int webServerPort;
+ private SentryWebServer sentryWebServer;
+ private long maxMessageSize;
+
+ public SentryService(Configuration conf) {
+ this.conf = conf;
+ int port = conf
+ .getInt(ServerConfig.RPC_PORT, ServerConfig.RPC_PORT_DEFAULT);
+ if (port == 0) {
+ port = findFreePort();
+ conf.setInt(ServerConfig.RPC_PORT, port);
+ }
+ this.address = NetUtils.createSocketAddr(
+ conf.get(ServerConfig.RPC_ADDRESS, ServerConfig.RPC_ADDRESS_DEFAULT),
+ port);
+ LOGGER.info("Configured on address " + address);
+ kerberos = ServerConfig.SECURITY_MODE_KERBEROS.equalsIgnoreCase(
+ conf.get(ServerConfig.SECURITY_MODE, ServerConfig.SECURITY_MODE_KERBEROS).trim());
+ maxThreads = conf.getInt(ServerConfig.RPC_MAX_THREADS,
+ 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 {
+ String rawPrincipal = Preconditions.checkNotNull(conf.get(ServerConfig.PRINCIPAL), ServerConfig.PRINCIPAL + " is required");
+ principal = SecurityUtil.getServerPrincipal(rawPrincipal, address.getAddress());
+ } catch(IOException io) {
+ throw new RuntimeException("Can't translate kerberos principal'", io);
+ }
+ LOGGER.info("Using kerberos principal: " + principal);
+
+ principalParts = SaslRpcServer.splitKerberosName(principal);
+ Preconditions.checkArgument(principalParts.length == 3,
+ "Kerberos principal should have 3 parts: " + principal);
+ keytab = Preconditions.checkNotNull(conf.get(ServerConfig.KEY_TAB),
+ ServerConfig.KEY_TAB + " is required");
+ File keytabFile = new File(keytab);
+ Preconditions.checkState(keytabFile.isFile() && keytabFile.canRead(),
+ "Keytab " + keytab + " does not exist or is not readable.");
+ } else {
+ principal = null;
+ principalParts = null;
+ keytab = null;
+ }
+ serviceExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+ private int count = 0;
+
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, SentryService.class.getSimpleName() + "-"
+ + (count++));
+ }
+ });
+ webServerPort = conf.getInt(ServerConfig.SENTRY_WEB_PORT, ServerConfig.SENTRY_WEB_PORT_DEFAULT);
+ status = Status.NOT_STARTED;
+ }
+
+ @Override
+ public String call() throws Exception {
+ SentryKerberosContext kerberosContext = null;
+ try {
+ status = Status.STARTED;
+ if (kerberos) {
+ Boolean autoRenewTicket = conf.getBoolean(ServerConfig.SENTRY_KERBEROS_TGT_AUTORENEW, ServerConfig.SENTRY_KERBEROS_TGT_AUTORENEW_DEFAULT);
+ kerberosContext = new SentryKerberosContext(principal, keytab, autoRenewTicket);
+ Subject.doAs(kerberosContext.getSubject(), new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ runServer();
+ return null;
+ }
+ });
+ } else {
+ runServer();
+ }
+ } catch (Exception t) {
+ LOGGER.error("Error starting server", t);
+ throw new Exception("Error starting server", t);
+ } finally {
+ if (kerberosContext != null) {
+ kerberosContext.shutDown();
+ }
+ status = Status.NOT_STARTED;
+ }
+ return null;
+ }
+
+ private void runServer() throws Exception {
+ Iterable<String> processorFactories = ConfUtilties.CLASS_SPLITTER
+ .split(conf.get(ServerConfig.PROCESSOR_FACTORIES,
+ ServerConfig.PROCESSOR_FACTORIES_DEFAULT).trim());
+ TMultiplexedProcessor processor = new TMultiplexedProcessor();
+ boolean registeredProcessor = false;
+ for (String processorFactory : processorFactories) {
+ Class<?> clazz = conf.getClassByName(processorFactory);
+ if (!ProcessorFactory.class.isAssignableFrom(clazz)) {
+ throw new IllegalArgumentException("Processor Factory "
+ + processorFactory + " is not a "
+ + ProcessorFactory.class.getName());
+ }
+ try {
+ Constructor<?> constructor = clazz
+ .getConstructor(Configuration.class);
+ LOGGER.info("ProcessorFactory being used: " + clazz.getCanonicalName());
+ ProcessorFactory factory = (ProcessorFactory) constructor
+ .newInstance(conf);
+ boolean registerStatus = factory.register(processor);
+ if (!registerStatus) {
+ LOGGER.error("Failed to register " + clazz.getCanonicalName());
+ }
+ registeredProcessor = registerStatus || registeredProcessor;
+ } catch (Exception e) {
+ throw new IllegalStateException("Could not create "
+ + processorFactory, e);
+ }
+ }
+ if (!registeredProcessor) {
+ throw new IllegalStateException(
+ "Failed to register any processors from " + processorFactories);
+ }
+ TServerTransport serverTransport = new TServerSocket(address);
+ TTransportFactory transportFactory = null;
+ if (kerberos) {
+ TSaslServerTransport.Factory saslTransportFactory = new TSaslServerTransport.Factory();
+ saslTransportFactory.addServerDefinition(AuthMethod.KERBEROS
+ .getMechanismName(), principalParts[0], principalParts[1],
+ ServerConfig.SASL_PROPERTIES, new GSSCallback(conf));
+ transportFactory = saslTransportFactory;
+ } else {
+ transportFactory = new TTransportFactory();
+ }
+ TThreadPoolServer.Args args = new TThreadPoolServer.Args(
+ serverTransport).processor(processor)
+ .transportFactory(transportFactory)
+ .protocolFactory(new TBinaryProtocol.Factory(true, true, maxMessageSize, maxMessageSize))
+ .minWorkerThreads(minThreads).maxWorkerThreads(maxThreads);
+ thriftServer = new TThreadPoolServer(args);
+ LOGGER.info("Serving on " + address);
+ startSentryWebServer();
+ thriftServer.serve();
+ }
+
+ private void startSentryWebServer() throws Exception{
+ Boolean sentryReportingEnable = conf.getBoolean(ServerConfig.SENTRY_WEB_ENABLE,
+ ServerConfig.SENTRY_WEB_ENABLE_DEFAULT);
+ if(sentryReportingEnable) {
+ List<EventListener> listenerList = new ArrayList<EventListener>();
+ listenerList.add(new SentryHealthCheckServletContextListener());
+ listenerList.add(new SentryMetricsServletContextListener());
+ sentryWebServer = new SentryWebServer(listenerList, webServerPort, conf);
+ sentryWebServer.start();
+ }
+
+ }
+
+ private void stopSentryWebServer() throws Exception{
+ if( sentryWebServer != null) {
+ sentryWebServer.stop();
+ sentryWebServer = null;
+ }
+ }
+
+ public InetSocketAddress getAddress() {
+ return address;
+ }
+
+ public synchronized boolean isRunning() {
+ return status == Status.STARTED && thriftServer != null
+ && thriftServer.isServing();
+ }
+
+ public synchronized void start() throws Exception{
+ if (status != Status.NOT_STARTED) {
+ throw new IllegalStateException("Cannot start when " + status);
+ }
+ LOGGER.info("Attempting to start...");
+ serviceStatus = serviceExecutor.submit(this);
+ }
+
+ public synchronized void stop() throws Exception{
+ MultiException exception = null;
+ LOGGER.info("Attempting to stop...");
+ if (isRunning()) {
+ LOGGER.info("Attempting to stop sentry thrift service...");
+ try {
+ thriftServer.stop();
+ thriftServer = null;
+ status = Status.NOT_STARTED;
+ } catch (Exception e) {
+ LOGGER.error("Error while stopping sentry thrift service", e);
+ exception = addMultiException(exception,e);
+ }
+ } else {
+ thriftServer = null;
+ status = Status.NOT_STARTED;
+ LOGGER.info("Sentry thrift service is already stopped...");
+ }
+ if (isWebServerRunning()) {
+ try {
+ LOGGER.info("Attempting to stop sentry web service...");
+ stopSentryWebServer();
+ } catch (Exception e) {
+ LOGGER.error("Error while stopping sentry web service", e);
+ exception = addMultiException(exception,e);
+ }
+ } else {
+ LOGGER.info("Sentry web service is already stopped...");
+ }
+ if (exception != null) {
+ exception.ifExceptionThrow();
+ }
+ LOGGER.info("Stopped...");
+ }
+
+ // wait for the service thread to finish execution
+ public synchronized void waitOnFuture() throws ExecutionException, InterruptedException {
+ LOGGER.info("Waiting on future.get()");
+ serviceStatus.get();
+ }
+
+ private MultiException addMultiException(MultiException exception, Exception e) {
+ MultiException newException = exception;
+ if (newException == null) {
+ newException = new MultiException();
+ }
+ newException.add(e);
+ return newException;
+ }
+
+ private boolean isWebServerRunning() {
+ return sentryWebServer != null
+ && sentryWebServer.isAlive();
+ }
+
+ private static int findFreePort() {
+ int attempts = 0;
+ while (attempts++ <= 1000) {
+ try {
+ ServerSocket s = new ServerSocket(0);
+ int port = s.getLocalPort();
+ s.close();
+ return port;
+ } catch (IOException e) {
+ // ignore and retry
+ }
+ }
+ throw new IllegalStateException("Unable to find a port after 1000 attempts");
+ }
+
+ public static Configuration loadConfig(String configFileName)
+ throws MalformedURLException {
+ File configFile = null;
+ if (configFileName == null) {
+ throw new IllegalArgumentException("Usage: "
+ + ServiceConstants.ServiceArgs.CONFIG_FILE_LONG
+ + " path/to/sentry-service.xml");
+ } else if (!((configFile = new File(configFileName)).isFile() && configFile
+ .canRead())) {
+ throw new IllegalArgumentException("Cannot read configuration file "
+ + configFile);
+ }
+ Configuration conf = new Configuration(false);
+ conf.addResource(configFile.toURI().toURL());
+ return conf;
+ }
+
+ public static class CommandImpl implements Command {
+ @Override
+ public void run(String[] args) throws Exception {
+ CommandLineParser parser = new GnuParser();
+ Options options = new Options();
+ options.addOption(ServiceConstants.ServiceArgs.CONFIG_FILE_SHORT,
+ ServiceConstants.ServiceArgs.CONFIG_FILE_LONG,
+ true, "Sentry Service configuration file");
+ CommandLine commandLine = parser.parse(options, args);
+ String configFileName = commandLine.getOptionValue(ServiceConstants.
+ ServiceArgs.CONFIG_FILE_LONG);
+ File configFile = null;
+ if (configFileName == null || commandLine.hasOption("h") || commandLine.hasOption("help")) {
+ // print usage
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("sentry --command service", options);
+ System.exit(-1);
+ } else if(!((configFile = new File(configFileName)).isFile() && configFile.canRead())) {
+ throw new IllegalArgumentException("Cannot read configuration file " + configFile);
+ }
+ Configuration serverConf = loadConfig(configFileName);
+ final SentryService server = new SentryService(serverConf);
+ server.start();
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ LOGGER.info("ShutdownHook shutting down server");
+ try {
+ server.stop();
+ } catch (Throwable t) {
+ LOGGER.error("Error stopping SentryService", t);
+ }
+ }
+ });
+
+ // Let's wait on the service to stop
+ try {
+ server.waitOnFuture();
+ } finally {
+ server.serviceExecutor.shutdown();
+ }
+ }
+ }
+
+ public Configuration getConf() {
+ return conf;
+ }
+
+ /**
+ * Add Thrift event handler to underlying thrift threadpool server
+ * @param eventHandler
+ */
+ public void setThriftEventHandler(TServerEventHandler eventHandler) throws IllegalStateException {
+ if (thriftServer == null) {
+ throw new IllegalStateException("Server is not initialized or stopped");
+ }
+ thriftServer.setServerEventHandler(eventHandler);
+ }
+
+ public TServerEventHandler getThriftEventHandler() throws IllegalStateException {
+ if (thriftServer == null) {
+ throw new IllegalStateException("Server is not initialized or stopped");
+ }
+ return thriftServer.getEventHandler();
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryServiceFactory.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryServiceFactory.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryServiceFactory.java
new file mode 100644
index 0000000..1685702
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/SentryServiceFactory.java
@@ -0,0 +1,28 @@
+/**
+ * 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.service.thrift;
+import org.apache.hadoop.conf.Configuration;
+
+public class SentryServiceFactory {
+
+ public SentryService create(Configuration conf) throws Exception {
+ return new SentryService(conf);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.derby.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.derby.sql b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.derby.sql
new file mode 100644
index 0000000..04353d1
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.derby.sql
@@ -0,0 +1,2 @@
+-- SENTRY-327
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD COLUMN WITH_GRANT_OPTION CHAR(1) NOT NULL DEFAULT 'N';
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.mysql.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.mysql.sql b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.mysql.sql
new file mode 100644
index 0000000..7d96bc0
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.mysql.sql
@@ -0,0 +1,2 @@
+-- SENTRY-327
+ALTER TABLE `SENTRY_DB_PRIVILEGE` ADD `WITH_GRANT_OPTION` CHAR(1) NOT NULL DEFAULT 'N';
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.oracle.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.oracle.sql b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.oracle.sql
new file mode 100644
index 0000000..f42ccdf
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.oracle.sql
@@ -0,0 +1,2 @@
+-- SENTRY-327
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD WITH_GRANT_OPTION CHAR(1) DEFAULT 'N' NOT NULL;
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.postgres.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.postgres.sql b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.postgres.sql
new file mode 100644
index 0000000..1b670ec
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/001-SENTRY-327.postgres.sql
@@ -0,0 +1,2 @@
+-- SENTRY-327
+ALTER TABLE "SENTRY_DB_PRIVILEGE" ADD COLUMN "WITH_GRANT_OPTION" CHAR(1) NOT NULL DEFAULT 'N';
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.derby.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.derby.sql b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.derby.sql
new file mode 100644
index 0000000..647e9e2
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.derby.sql
@@ -0,0 +1,13 @@
+-- SENTRY-339
+DROP INDEX SENTRYPRIVILEGENAME;
+CREATE UNIQUE INDEX SENTRYPRIVILEGENAME ON SENTRY_DB_PRIVILEGE ("SERVER_NAME",DB_NAME,"TABLE_NAME",URI,"ACTION",WITH_GRANT_OPTION);
+
+ALTER TABLE SENTRY_DB_PRIVILEGE DROP COLUMN PRIVILEGE_NAME;
+
+ALTER TABLE SENTRY_DB_PRIVILEGE ALTER COLUMN DB_NAME SET DEFAULT '__NULL__';
+ALTER TABLE SENTRY_DB_PRIVILEGE ALTER COLUMN TABLE_NAME SET DEFAULT '__NULL__';
+ALTER TABLE SENTRY_DB_PRIVILEGE ALTER COLUMN URI SET DEFAULT '__NULL__';
+
+UPDATE SENTRY_DB_PRIVILEGE SET DB_NAME = DEFAULT WHERE DB_NAME is null;
+UPDATE SENTRY_DB_PRIVILEGE SET TABLE_NAME = DEFAULT WHERE TABLE_NAME is null;
+UPDATE SENTRY_DB_PRIVILEGE SET URI = DEFAULT WHERE URI is null;
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.mysql.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.mysql.sql b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.mysql.sql
new file mode 100644
index 0000000..cd4ec7c
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.mysql.sql
@@ -0,0 +1,13 @@
+-- SENTRY-339
+ALTER TABLE `SENTRY_DB_PRIVILEGE` DROP INDEX `SENTRY_DB_PRIV_PRIV_NAME_UNIQ`;
+ALTER TABLE `SENTRY_DB_PRIVILEGE` ADD UNIQUE `SENTRY_DB_PRIV_PRIV_NAME_UNIQ` (`SERVER_NAME`,`DB_NAME`,`TABLE_NAME`,`URI`(250),`ACTION`,`WITH_GRANT_OPTION`);
+ALTER TABLE `SENTRY_DB_PRIVILEGE` DROP `PRIVILEGE_NAME`;
+
+ALTER TABLE SENTRY_DB_PRIVILEGE ALTER COLUMN DB_NAME SET DEFAULT '__NULL__';
+ALTER TABLE SENTRY_DB_PRIVILEGE ALTER COLUMN TABLE_NAME SET DEFAULT '__NULL__';
+ALTER TABLE SENTRY_DB_PRIVILEGE ALTER COLUMN URI SET DEFAULT '__NULL__';
+
+UPDATE SENTRY_DB_PRIVILEGE SET DB_NAME = DEFAULT WHERE DB_NAME is null;
+UPDATE SENTRY_DB_PRIVILEGE SET TABLE_NAME = DEFAULT WHERE TABLE_NAME is null;
+UPDATE SENTRY_DB_PRIVILEGE SET URI = DEFAULT WHERE URI is null;
+
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.oracle.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.oracle.sql b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.oracle.sql
new file mode 100644
index 0000000..f5f596d
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.oracle.sql
@@ -0,0 +1,13 @@
+-- SENTRY-339
+ALTER TABLE SENTRY_DB_PRIVILEGE DROP CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" DROP INDEX;
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" UNIQUE ("SERVER_NAME","DB_NAME","TABLE_NAME","URI","ACTION","WITH_GRANT_OPTION");
+ALTER TABLE SENTRY_DB_PRIVILEGE DROP COLUMN PRIVILEGE_NAME;
+
+ALTER TABLE SENTRY_DB_PRIVILEGE MODIFY DB_NAME DEFAULT '__NULL__';
+ALTER TABLE SENTRY_DB_PRIVILEGE MODIFY TABLE_NAME DEFAULT '__NULL__';
+ALTER TABLE SENTRY_DB_PRIVILEGE MODIFY URI DEFAULT '__NULL__';
+
+UPDATE SENTRY_DB_PRIVILEGE SET DB_NAME = DEFAULT WHERE DB_NAME is null;
+UPDATE SENTRY_DB_PRIVILEGE SET TABLE_NAME = DEFAULT WHERE TABLE_NAME is null;
+UPDATE SENTRY_DB_PRIVILEGE SET URI = DEFAULT WHERE URI is null;
+
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.postgres.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.postgres.sql b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.postgres.sql
new file mode 100644
index 0000000..458e447
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/002-SENTRY-339.postgres.sql
@@ -0,0 +1,13 @@
+-- SENTRY-339
+ALTER TABLE "SENTRY_DB_PRIVILEGE" DROP CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ";
+ALTER TABLE "SENTRY_DB_PRIVILEGE" ADD CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" UNIQUE ("SERVER_NAME","DB_NAME","TABLE_NAME","URI", "ACTION","WITH_GRANT_OPTION");
+ALTER TABLE "SENTRY_DB_PRIVILEGE" DROP COLUMN "PRIVILEGE_NAME";
+
+ALTER TABLE "SENTRY_DB_PRIVILEGE" ALTER COLUMN "DB_NAME" SET DEFAULT '__NULL__';
+AlTER TABLE "SENTRY_DB_PRIVILEGE" ALTER COLUMN "TABLE_NAME" SET DEFAULT '__NULL__';
+ALTER TABLE "SENTRY_DB_PRIVILEGE" ALTER COLUMN "URI" SET DEFAULT '__NULL__';
+
+UPDATE "SENTRY_DB_PRIVILEGE" SET "DB_NAME" = DEFAULT where "DB_NAME" is null;
+UPDATE "SENTRY_DB_PRIVILEGE" SET "TABLE_NAME" = DEFAULT where "TABLE_NAME" is null;
+UPDATE "SENTRY_DB_PRIVILEGE" SET "URI" = DEFAULT where "URI" is null;
+
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.derby.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.derby.sql b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.derby.sql
new file mode 100644
index 0000000..f27b358
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.derby.sql
@@ -0,0 +1,7 @@
+-- SENTRY-380
+ALTER TABLE SENTRY_DB_PRIVILEGE DROP GRANTOR_PRINCIPAL;
+ALTER TABLE SENTRY_ROLE DROP GRANTOR_PRINCIPAL;
+ALTER TABLE SENTRY_GROUP DROP GRANTOR_PRINCIPAL;
+
+ALTER TABLE SENTRY_ROLE_DB_PRIVILEGE_MAP ADD GRANTOR_PRINCIPAL VARCHAR(128);
+ALTER TABLE SENTRY_ROLE_GROUP_MAP ADD GRANTOR_PRINCIPAL VARCHAR(128);
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.mysql.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.mysql.sql b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.mysql.sql
new file mode 100644
index 0000000..8e0a633
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.mysql.sql
@@ -0,0 +1,7 @@
+-- SENTRY-380
+ALTER TABLE `SENTRY_DB_PRIVILEGE` DROP `GRANTOR_PRINCIPAL`;
+ALTER TABLE `SENTRY_ROLE` DROP `GRANTOR_PRINCIPAL`;
+ALTER TABLE `SENTRY_GROUP` DROP `GRANTOR_PRINCIPAL`;
+
+ALTER TABLE `SENTRY_ROLE_DB_PRIVILEGE_MAP` ADD `GRANTOR_PRINCIPAL` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin;
+ALTER TABLE `SENTRY_ROLE_GROUP_MAP` ADD `GRANTOR_PRINCIPAL` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.oracle.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.oracle.sql b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.oracle.sql
new file mode 100644
index 0000000..d07d20e
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.oracle.sql
@@ -0,0 +1,7 @@
+-- SENTRY-380
+ALTER TABLE "SENTRY_DB_PRIVILEGE" DROP COLUMN "GRANTOR_PRINCIPAL";
+ALTER TABLE "SENTRY_ROLE" DROP COLUMN "GRANTOR_PRINCIPAL";
+ALTER TABLE "SENTRY_GROUP" DROP COLUMN "GRANTOR_PRINCIPAL";
+
+ALTER TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP" ADD "GRANTOR_PRINCIPAL" VARCHAR2(128);
+ALTER TABLE "SENTRY_ROLE_GROUP_MAP" ADD "GRANTOR_PRINCIPAL" VARCHAR2(128);
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.postgres.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.postgres.sql b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.postgres.sql
new file mode 100644
index 0000000..95a2ef1
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/003-SENTRY-380.postgres.sql
@@ -0,0 +1,7 @@
+-- SENTRY-380
+ALTER TABLE "SENTRY_DB_PRIVILEGE" DROP "GRANTOR_PRINCIPAL";
+ALTER TABLE "SENTRY_ROLE" DROP "GRANTOR_PRINCIPAL";
+ALTER TABLE "SENTRY_GROUP" DROP "GRANTOR_PRINCIPAL";
+
+ALTER TABLE "SENTRY_ROLE_DB_PRIVILEGE_MAP" ADD "GRANTOR_PRINCIPAL" character varying(128);
+ALTER TABLE "SENTRY_ROLE_GROUP_MAP" ADD "GRANTOR_PRINCIPAL" character varying(128);
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.derby.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.derby.sql b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.derby.sql
new file mode 100644
index 0000000..da1f4d6
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.derby.sql
@@ -0,0 +1,4 @@
+-- SENTRY-74
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD COLUMN COLUMN_NAME VARCHAR(4000) DEFAULT '__NULL__';
+DROP INDEX SENTRYPRIVILEGENAME;
+CREATE UNIQUE INDEX SENTRYPRIVILEGENAME ON SENTRY_DB_PRIVILEGE ("SERVER_NAME",DB_NAME,"TABLE_NAME","COLUMN_NAME",URI,"ACTION",WITH_GRANT_OPTION);
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.mysql.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.mysql.sql b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.mysql.sql
new file mode 100644
index 0000000..1419ca3
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.mysql.sql
@@ -0,0 +1,4 @@
+-- SENTRY-74
+ALTER TABLE `SENTRY_DB_PRIVILEGE` ADD `COLUMN_NAME` VARCHAR(128) DEFAULT '__NULL__';
+ALTER TABLE `SENTRY_DB_PRIVILEGE` DROP INDEX `SENTRY_DB_PRIV_PRIV_NAME_UNIQ`;
+ALTER TABLE `SENTRY_DB_PRIVILEGE` ADD UNIQUE `SENTRY_DB_PRIV_PRIV_NAME_UNIQ` (`SERVER_NAME`,`DB_NAME`,`TABLE_NAME`,`COLUMN_NAME`,`URI`(250),`ACTION`,`WITH_GRANT_OPTION`);
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.oracle.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.oracle.sql b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.oracle.sql
new file mode 100644
index 0000000..a70ae0a
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.oracle.sql
@@ -0,0 +1,4 @@
+-- SENTRY-74
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD COLUMN_NAME VARCHAR2(128) DEFAULT '__NULL__';
+ALTER TABLE SENTRY_DB_PRIVILEGE DROP CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" DROP INDEX;
+ALTER TABLE SENTRY_DB_PRIVILEGE ADD CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" UNIQUE ("SERVER_NAME","DB_NAME","TABLE_NAME","COLUMN_NAME","URI","ACTION","WITH_GRANT_OPTION");
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.postgres.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.postgres.sql b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.postgres.sql
new file mode 100644
index 0000000..81bdfa3
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/004-SENTRY-74.postgres.sql
@@ -0,0 +1,4 @@
+-- SENTRY-74
+ALTER TABLE "SENTRY_DB_PRIVILEGE" ADD COLUMN "COLUMN_NAME" character varying(128) DEFAULT '__NULL__';
+ALTER TABLE "SENTRY_DB_PRIVILEGE" DROP CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ";
+ALTER TABLE "SENTRY_DB_PRIVILEGE" ADD CONSTRAINT "SENTRY_DB_PRIV_PRIV_NAME_UNIQ" UNIQUE ("SERVER_NAME","DB_NAME","TABLE_NAME","COLUMN_NAME","URI", "ACTION","WITH_GRANT_OPTION");
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.derby.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.derby.sql b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.derby.sql
new file mode 100644
index 0000000..c038b81
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.derby.sql
@@ -0,0 +1,43 @@
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE SENTRY_GM_PRIVILEGE
+(
+ GM_PRIVILEGE_ID BIGINT NOT NULL,
+ "ACTION" VARCHAR(40),
+ COMPONENT_NAME VARCHAR(400),
+ CREATE_TIME BIGINT NOT NULL,
+ WITH_GRANT_OPTION CHAR(1) NOT NULL DEFAULT 'N',
+ RESOURCE_NAME_0 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_NAME_1 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_NAME_2 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_NAME_3 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_0 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_1 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_2 VARCHAR(400) DEFAULT '__NULL__',
+ RESOURCE_TYPE_3 VARCHAR(400) DEFAULT '__NULL__',
+ "SCOPE" VARCHAR(40),
+ SERVICE_NAME VARCHAR(400)
+);
+-- Primary key(GM_PRIVILEGE_ID)
+ALTER TABLE SENTRY_GM_PRIVILEGE ADD CONSTRAINT SENTRY_GM_PRIVILEGE_PK PRIMARY KEY (GM_PRIVILEGE_ID);
+
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE UNIQUE INDEX GM_PRIVILEGE_INDEX ON SENTRY_GM_PRIVILEGE (COMPONENT_NAME,SERVICE_NAME,RESOURCE_NAME_0,RESOURCE_TYPE_0,RESOURCE_NAME_1,RESOURCE_TYPE_1,RESOURCE_NAME_2,RESOURCE_TYPE_2,RESOURCE_NAME_3,RESOURCE_TYPE_3,"ACTION",WITH_GRANT_OPTION);
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP
+(
+ ROLE_ID BIGINT NOT NULL,
+ GM_PRIVILEGE_ID BIGINT NOT NULL
+);
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_PK PRIMARY KEY (ROLE_ID,GM_PRIVILEGE_ID);
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+CREATE INDEX SENTRY_ROLE_GM_PRIVILEGE_MAP_N50 ON SENTRY_ROLE_GM_PRIVILEGE_MAP (ROLE_ID);
+
+CREATE INDEX SENTRY_ROLE_GM_PRIVILEGE_MAP_N49 ON SENTRY_ROLE_GM_PRIVILEGE_MAP (GM_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_FK2 FOREIGN KEY (GM_PRIVILEGE_ID) REFERENCES SENTRY_GM_PRIVILEGE (GM_PRIVILEGE_ID);
+
+ALTER TABLE SENTRY_ROLE_GM_PRIVILEGE_MAP ADD CONSTRAINT SENTRY_ROLE_GM_PRIVILEGE_MAP_FK1 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID);
+
+
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.mysql.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.mysql.sql b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.mysql.sql
new file mode 100644
index 0000000..920737f
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.mysql.sql
@@ -0,0 +1,62 @@
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE `SENTRY_GM_PRIVILEGE`
+(
+ `GM_PRIVILEGE_ID` BIGINT NOT NULL,
+ `ACTION` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `COMPONENT_NAME` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `CREATE_TIME` BIGINT NOT NULL,
+ `WITH_GRANT_OPTION` CHAR(1) NOT NULL DEFAULT 'N',
+ `RESOURCE_NAME_0` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_NAME_1` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_NAME_2` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_NAME_3` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_0` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_1` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_2` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `RESOURCE_TYPE_3` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '__NULL__',
+ `SCOPE` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `SERVICE_NAME` VARCHAR(64) BINARY CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
+) ENGINE=INNODB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD CONSTRAINT `SENTRY_GM_PRIVILEGE_PK` PRIMARY KEY (`GM_PRIVILEGE_ID`);
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD UNIQUE `GM_PRIVILEGE_UNIQUE` (`COMPONENT_NAME`,`SERVICE_NAME`,`RESOURCE_NAME_0`,`RESOURCE_TYPE_0`,`RESOURCE_NAME_1`,`RESOURCE_TYPE_1`,`RESOURCE_NAME_2`,`RESOURCE_TYPE_2`,`RESOURCE_NAME_3`,`RESOURCE_TYPE_3`,`ACTION`,`WITH_GRANT_OPTION`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_COMP_IDX` (`COMPONENT_NAME`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_SERV_IDX` (`SERVICE_NAME`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES0_IDX` (`RESOURCE_NAME_0`,`RESOURCE_TYPE_0`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES1_IDX` (`RESOURCE_NAME_1`,`RESOURCE_TYPE_1`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES2_IDX` (`RESOURCE_NAME_2`,`RESOURCE_TYPE_2`);
+
+ALTER TABLE `SENTRY_GM_PRIVILEGE`
+ ADD INDEX `SENTRY_GM_PRIV_RES3_IDX` (`RESOURCE_NAME_3`,`RESOURCE_TYPE_3`);
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+(
+ `ROLE_ID` BIGINT NOT NULL,
+ `GM_PRIVILEGE_ID` BIGINT NOT NULL
+) ENGINE=INNODB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SENTRY_ROLE_GM_PRIVILEGE_MAP_PK` PRIMARY KEY (`ROLE_ID`,`GM_PRIVILEGE_ID`);
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+ALTER TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SEN_RLE_GM_PRV_MAP_SN_RLE_FK`
+ FOREIGN KEY (`ROLE_ID`) REFERENCES `SENTRY_ROLE`(`ROLE_ID`);
+
+ALTER TABLE `SENTRY_ROLE_GM_PRIVILEGE_MAP`
+ ADD CONSTRAINT `SEN_RL_GM_PRV_MAP_SN_DB_PRV_FK`
+ FOREIGN KEY (`GM_PRIVILEGE_ID`) REFERENCES `SENTRY_GM_PRIVILEGE`(`GM_PRIVILEGE_ID`);
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.oracle.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.oracle.sql b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.oracle.sql
new file mode 100644
index 0000000..412bc45
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.oracle.sql
@@ -0,0 +1,55 @@
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE "SENTRY_GM_PRIVILEGE" (
+ "GM_PRIVILEGE_ID" NUMBER NOT NULL,
+ "COMPONENT_NAME" VARCHAR2(32) NOT NULL,
+ "CREATE_TIME" NUMBER NOT NULL,
+ "WITH_GRANT_OPTION" CHAR(1) DEFAULT 'N' NOT NULL,
+ "RESOURCE_NAME_0" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_1" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_2" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_3" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_0" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_1" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_2" VARCHAR2(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_3" VARCHAR2(64) DEFAULT '__NULL__',
+ "ACTION" VARCHAR2(32) NOT NULL,
+ "SCOPE" VARCHAR2(128) NOT NULL,
+ "SERVICE_NAME" VARCHAR2(64) NOT NULL
+);
+
+ALTER TABLE "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PK" PRIMARY KEY ("GM_PRIVILEGE_ID");
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+ALTER TABLE "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PRIV_NAME_UNIQ" UNIQUE ("COMPONENT_NAME","SERVICE_NAME","RESOURCE_NAME_0","RESOURCE_NAME_1","RESOURCE_NAME_2",
+ "RESOURCE_NAME_3","RESOURCE_TYPE_0","RESOURCE_TYPE_1","RESOURCE_TYPE_2","RESOURCE_TYPE_3","ACTION","WITH_GRANT_OPTION");
+
+CREATE INDEX "SENTRY_GM_PRIV_COMP_IDX" ON "SENTRY_GM_PRIVILEGE" ("COMPONENT_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_SERV_IDX" ON "SENTRY_GM_PRIVILEGE" ("SERVICE_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES0_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_0","RESOURCE_TYPE_0");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES1_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_1","RESOURCE_TYPE_1");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES2_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_2","RESOURCE_TYPE_2");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES3_IDX" ON "SENTRY_GM_PRIVILEGE" ("RESOURCE_NAME_3","RESOURCE_TYPE_3");
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP" (
+ "ROLE_ID" NUMBER NOT NULL,
+ "GM_PRIVILEGE_ID" NUMBER NOT NULL
+);
+
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_GM_PRIV_MAP_PK" PRIMARY KEY ("ROLE_ID","GM_PRIVILEGE_ID");
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_GM_PRV_MAP_SN_RLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") INITIALLY DEFERRED;
+
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RL_GM_PRV_MAP_SN_DB_PRV_FK"
+ FOREIGN KEY ("GM_PRIVILEGE_ID") REFERENCES "SENTRY_GM_PRIVILEGE"("GM_PRIVILEGE_ID") INITIALLY DEFERRED;
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.postgres.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.postgres.sql b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.postgres.sql
new file mode 100644
index 0000000..e9e1655
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/005-SENTRY-398.postgres.sql
@@ -0,0 +1,54 @@
+-- Table SENTRY_GM_PRIVILEGE for classes [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+CREATE TABLE "SENTRY_GM_PRIVILEGE" (
+ "GM_PRIVILEGE_ID" BIGINT NOT NULL,
+ "COMPONENT_NAME" character varying(32) NOT NULL,
+ "CREATE_TIME" BIGINT NOT NULL,
+ "WITH_GRANT_OPTION" CHAR(1) NOT NULL DEFAULT 'N',
+ "RESOURCE_NAME_0" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_1" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_2" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_NAME_3" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_0" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_1" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_2" character varying(64) DEFAULT '__NULL__',
+ "RESOURCE_TYPE_3" character varying(64) DEFAULT '__NULL__',
+ "ACTION" character varying(32) NOT NULL,
+ "SCOPE" character varying(128) NOT NULL,
+ "SERVICE_NAME" character varying(64) NOT NULL
+);
+ALTER TABLE ONLY "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PK" PRIMARY KEY ("GM_PRIVILEGE_ID");
+-- Constraints for table SENTRY_GM_PRIVILEGE for class(es) [org.apache.sentry.provider.db.service.model.MSentryGMPrivilege]
+ALTER TABLE ONLY "SENTRY_GM_PRIVILEGE"
+ ADD CONSTRAINT "SENTRY_GM_PRIV_PRIV_NAME_UNIQ" UNIQUE ("COMPONENT_NAME","SERVICE_NAME","RESOURCE_NAME_0","RESOURCE_NAME_1","RESOURCE_NAME_2",
+ "RESOURCE_NAME_3","RESOURCE_TYPE_0","RESOURCE_TYPE_1","RESOURCE_TYPE_2","RESOURCE_TYPE_3","ACTION","WITH_GRANT_OPTION");
+
+CREATE INDEX "SENTRY_GM_PRIV_COMP_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("COMPONENT_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_SERV_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("SERVICE_NAME");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES0_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_0","RESOURCE_TYPE_0");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES1_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_1","RESOURCE_TYPE_1");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES2_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_2","RESOURCE_TYPE_2");
+
+CREATE INDEX "SENTRY_GM_PRIV_RES3_IDX" ON "SENTRY_GM_PRIVILEGE" USING btree ("RESOURCE_NAME_3","RESOURCE_TYPE_3");
+
+-- Table SENTRY_ROLE_GM_PRIVILEGE_MAP for join relationship
+CREATE TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP" (
+ "ROLE_ID" BIGINT NOT NULL,
+ "GM_PRIVILEGE_ID" BIGINT NOT NULL
+);
+
+ALTER TABLE "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SENTRY_ROLE_GM_PRIVILEGE_MAP_PK" PRIMARY KEY ("ROLE_ID","GM_PRIVILEGE_ID");
+
+-- Constraints for table SENTRY_ROLE_GM_PRIVILEGE_MAP
+ALTER TABLE ONLY "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RLE_GM_PRV_MAP_SN_RLE_FK"
+ FOREIGN KEY ("ROLE_ID") REFERENCES "SENTRY_ROLE"("ROLE_ID") DEFERRABLE;
+
+ALTER TABLE ONLY "SENTRY_ROLE_GM_PRIVILEGE_MAP"
+ ADD CONSTRAINT "SEN_RL_GM_PRV_MAP_SN_DB_PRV_FK"
+ FOREIGN KEY ("GM_PRIVILEGE_ID") REFERENCES "SENTRY_GM_PRIVILEGE"("GM_PRIVILEGE_ID") DEFERRABLE;
http://git-wip-us.apache.org/repos/asf/sentry/blob/e72e6eac/sentry-service/sentry-service-server/src/main/resources/006-SENTRY-711.derby.sql
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/main/resources/006-SENTRY-711.derby.sql b/sentry-service/sentry-service-server/src/main/resources/006-SENTRY-711.derby.sql
new file mode 100644
index 0000000..807a62b
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/main/resources/006-SENTRY-711.derby.sql
@@ -0,0 +1,27 @@
+CREATE TABLE SENTRY_USER
+(
+ USER_ID BIGINT NOT NULL generated always as identity (start with 1),
+ CREATE_TIME BIGINT NOT NULL,
+ USER_NAME VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_USER ADD CONSTRAINT SENTRY_USER_PK PRIMARY KEY (USER_ID);
+
+CREATE UNIQUE INDEX SENTRYUSERNAME ON SENTRY_USER (USER_NAME);
+
+CREATE TABLE SENTRY_ROLE_USER_MAP
+(
+ USER_ID BIGINT NOT NULL,
+ ROLE_ID BIGINT NOT NULL,
+ GRANTOR_PRINCIPAL VARCHAR(128)
+);
+
+ALTER TABLE SENTRY_ROLE_USER_MAP ADD CONSTRAINT SENTRY_ROLE_USER_MAP_PK PRIMARY KEY (USER_ID,ROLE_ID);
+
+CREATE INDEX SENTRY_ROLE_USER_MAP_N49 ON SENTRY_ROLE_USER_MAP (USER_ID);
+
+CREATE INDEX SENTRY_ROLE_USER_MAP_N50 ON SENTRY_ROLE_USER_MAP (ROLE_ID);
+
+ALTER TABLE SENTRY_ROLE_USER_MAP ADD CONSTRAINT SENTRY_ROLE_USER_MAP_FK2 FOREIGN KEY (ROLE_ID) REFERENCES SENTRY_ROLE (ROLE_ID) ;
+
+ALTER TABLE SENTRY_ROLE_USER_MAP ADD CONSTRAINT SENTRY_ROLE_USER_MAP_FK1 FOREIGN KEY (USER_ID) REFERENCES SENTRY_USER (USER_ID) ;
\ No newline at end of file