LENS-1504 : Authorization usinf Apache ranger in Lens.
authorRajitha R <rajithar@apache.org>
Mon, 13 Aug 2018 09:23:14 +0000 (14:53 +0530)
committerRajitha.R <rajithar@IM0318-L0.corp.inmobi.com>
Mon, 13 Aug 2018 09:23:14 +0000 (14:53 +0530)
48 files changed:
lens-api/src/main/resources/lens-errors.conf
lens-client/src/main/java/org/apache/lens/client/LensMetadataClient.java
lens-cube/pom.xml
lens-cube/src/main/java/org/apache/lens/cube/authorization/AuthorizationUtil.java [new file with mode: 0644]
lens-cube/src/main/java/org/apache/lens/cube/authorization/RangerLensAuthorizer.java [new file with mode: 0644]
lens-cube/src/main/java/org/apache/lens/cube/authorization/RangerLensResource.java [new file with mode: 0644]
lens-cube/src/main/java/org/apache/lens/cube/metadata/AbstractBaseTable.java
lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeFactTable.java
lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeMetastoreClient.java
lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreConstants.java
lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
lens-cube/src/main/java/org/apache/lens/cube/parse/QueryAuthorizationResolver.java [new file with mode: 0644]
lens-cube/src/main/resources/ranger-sample.json [new file with mode: 0644]
lens-driver-hive/src/main/resources/hivedriver-default.xml
lens-driver-jdbc/src/main/resources/jdbcdriver-default.xml
lens-examples/src/main/resources/dim_table.xml
lens-query-lib/src/main/java/org/apache/lens/lib/query/FileSystemUtil.java [new file with mode: 0644]
lens-query-lib/src/main/java/org/apache/lens/lib/query/ZipFileFormatter.java
lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
lens-server-api/src/main/java/org/apache/lens/server/api/SessionValidator.java
lens-server-api/src/main/java/org/apache/lens/server/api/authorization/ActionType.java [new file with mode: 0644]
lens-server-api/src/main/java/org/apache/lens/server/api/authorization/Authorizer.java [new file with mode: 0644]
lens-server-api/src/main/java/org/apache/lens/server/api/authorization/DefaultAuthorizer.java [new file with mode: 0644]
lens-server-api/src/main/java/org/apache/lens/server/api/authorization/LensPrivilegeObject.java [new file with mode: 0644]
lens-server-api/src/main/java/org/apache/lens/server/api/metastore/CubeMetastoreService.java
lens-server-api/src/main/java/org/apache/lens/server/api/query/AbstractQueryContext.java
lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryExecutionService.java
lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/PrivilegeException.java
lens-server-api/src/main/java/org/apache/lens/server/api/user/UserGroupConfigLoader.java [new file with mode: 0644]
lens-server-api/src/main/java/org/apache/lens/server/api/user/UserGroupLoaderException.java [new file with mode: 0644]
lens-server/src/main/java/org/apache/lens/server/BaseLensService.java
lens-server/src/main/java/org/apache/lens/server/LensServices.java
lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
lens-server/src/main/java/org/apache/lens/server/user/usergroup/FixedUserGroupConfigLoader.java [new file with mode: 0644]
lens-server/src/main/java/org/apache/lens/server/user/usergroup/UserGroupLoaderFactory.java [new file with mode: 0644]
lens-server/src/main/resources/lensserver-default.xml
lens-server/src/main/resources/ranger-lens-audit.xml [new file with mode: 0644]
lens-server/src/main/resources/ranger-lens-security.xml [new file with mode: 0644]
lens-server/src/main/resources/ranger-policymgr-ssl.xml [new file with mode: 0644]
pom.xml
src/site/apt/admin/config.apt
src/site/apt/admin/hivedriver-config.apt
src/site/apt/admin/jdbcdriver-config.apt

index fafd655..9001a45 100644 (file)
@@ -25,7 +25,7 @@
 
 BAD_REQUEST = 400
 NOT_FOUND = 404
-UNAUTHORIZED = 401
+UNAUTHORIZED = 403
 GONE = 410
 TOO_MANY_REQUESTS = 429
 INTERNAL_SERVER_ERROR = 500
index 7b37769..48e1208 100644 (file)
@@ -297,7 +297,6 @@ public class LensMetadataClient {
     return storages.getElements();
   }
 
-
   public APIResult createNewStorage(XStorage storage) {
     WebTarget target = getMetastoreWebTarget();
     return translate(target.path("storages")
index deaeb36..fca0106 100644 (file)
   <description>OLAP cube queries</description>
 
   <dependencies>
+
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.ranger</groupId>
+      <artifactId>ranger-plugins-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.core</groupId>
+      <artifactId>jersey-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.core</groupId>
+      <artifactId>jersey-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.containers</groupId>
+      <artifactId>jersey-container-grizzly2-servlet</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.glassfish.jersey.containers</groupId>
+      <artifactId>jersey-container-servlet-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.ranger</groupId>
+      <artifactId>ranger-plugins-cred</artifactId>
+    </dependency>
+    <dependency>
+    <groupId>org.apache.ranger</groupId>
+    <artifactId>ranger-plugins-audit</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apache.lens</groupId>
       <artifactId>lens-server-api</artifactId>
       <version>${project.version}</version>
     </dependency>
-
     <dependency>
       <groupId>org.apache.hive</groupId>
       <artifactId>hive-exec</artifactId>
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/authorization/AuthorizationUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/authorization/AuthorizationUtil.java
new file mode 100644 (file)
index 0000000..ccd46a3
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * 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.lens.cube.authorization;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.lens.server.api.LensConfConstants;
+import org.apache.lens.server.api.authorization.ActionType;
+import org.apache.lens.server.api.authorization.Authorizer;
+import org.apache.lens.server.api.authorization.LensPrivilegeObject;
+import org.apache.lens.server.api.error.LensException;
+import org.apache.lens.server.api.query.save.exception.PrivilegeException;
+
+import org.apache.hadoop.conf.Configuration;
+
+/*
+Helper class for all Authorization needs
+*/
+public class AuthorizationUtil {
+
+  private AuthorizationUtil(){}
+
+  public static boolean isAuthorized(Authorizer authorizer, String tableName,
+    LensPrivilegeObject.LensPrivilegeObjectType privilegeObjectType, ActionType actionType, Configuration configuration)
+    throws LensException {
+    return isAuthorized(authorizer, tableName, null, privilegeObjectType, actionType, configuration);
+  }
+
+  public static boolean isAuthorized(Authorizer authorizer, String tableName, String colName,
+    LensPrivilegeObject.LensPrivilegeObjectType privilegeObjectType, ActionType actionType, Configuration configuration)
+    throws LensException {
+    String user = null;
+    Set<String> userGroups = new HashSet<>();
+    if (configuration.getBoolean(LensConfConstants.USER_NAME_BASED_AUTHORIZATION,
+      LensConfConstants.DEFAULT_USER_NAME_AUTHORIZATION)){
+      user = configuration.get(LensConfConstants.SESSION_LOGGEDIN_USER);
+    }
+    if (configuration.getBoolean(LensConfConstants.USER_GROUPS_BASED_AUTHORIZATION,
+      LensConfConstants.DEFAULT_USER_GROUPS_AUTHORIZATION)) {
+      userGroups = (Set<String>)
+        configuration.getTrimmedStringCollection(LensConfConstants.SESSION_USER_GROUPS);
+    }
+    LensPrivilegeObject lp = new LensPrivilegeObject(privilegeObjectType, tableName, colName);
+    if (!authorizer.authorize(lp, actionType, user, userGroups)) {
+      throw new PrivilegeException(privilegeObjectType.toString(), tableName, actionType.toString());
+    }
+    return true;
+  }
+}
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/authorization/RangerLensAuthorizer.java b/lens-cube/src/main/java/org/apache/lens/cube/authorization/RangerLensAuthorizer.java
new file mode 100644 (file)
index 0000000..2fe08ef
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * 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.lens.cube.authorization;
+
+import java.util.Set;
+
+import org.apache.lens.server.api.authorization.ActionType;
+import org.apache.lens.server.api.authorization.Authorizer;
+import org.apache.lens.server.api.authorization.LensPrivilegeObject;
+
+import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+// Apache Ranger implementation for Authorization in Lens
+
+@Slf4j
+public class RangerLensAuthorizer implements Authorizer {
+
+  @Getter
+  private RangerBasePlugin rangerBasePlugin;
+
+  RangerLensAuthorizer() {
+    this.init();
+  }
+
+  public void init() {
+    rangerBasePlugin = new RangerBasePlugin("lens", "lens");
+    rangerBasePlugin.setResultProcessor(new RangerDefaultAuditHandler());
+    rangerBasePlugin.init();
+  }
+
+  @Override
+  public boolean authorize(LensPrivilegeObject lensPrivilegeObject, ActionType accessType, String user,
+    Set<String> userGroups) {
+
+    log.info("==> Lens Ranger Authorize User : "+ user + "User groups : " + userGroups + " Accesstype : "
+      + accessType + "Object : "+ lensPrivilegeObject.getTable());
+
+    RangerLensResource rangerLensResource = getLensResource(lensPrivilegeObject);
+
+    boolean res = false;
+
+    if (rangerLensResource != null) {
+      RangerAccessRequest rangerAccessRequest = new RangerAccessRequestImpl(rangerLensResource,
+        accessType.toString().toLowerCase(), user, userGroups);
+      RangerAccessResult rangerAccessResult = getRangerBasePlugin().isAccessAllowed(rangerAccessRequest);
+      res = rangerAccessResult != null && rangerAccessResult.getIsAllowed();
+    }
+
+    log.info("<== Lens Ranger Authorize User : "+ user + " User groups : " + userGroups + " Accesstype : "+ accessType
+      + " Object : "+ lensPrivilegeObject.getTable() + " Access : "+ res);
+
+    return res;
+  }
+
+  private RangerLensResource getLensResource(LensPrivilegeObject lensPrivilegeObject) {
+
+    RangerLensResource lensResource = null;
+    switch (lensPrivilegeObject.getObjectType()) {
+    case COLUMN:
+      lensResource = new RangerLensResource(LensObjectType.COLUMN, lensPrivilegeObject.getTable(),
+        lensPrivilegeObject.getColumn());
+      break;
+    case DATABASE:
+      lensResource = new RangerLensResource(LensObjectType.TABLE, lensPrivilegeObject.getTable(), null);
+      break;
+
+    case NONE:
+    default:
+      break;
+    }
+    return lensResource;
+  }
+
+  enum LensObjectType {NONE, TABLE, COLUMN}
+
+  ;
+}
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/authorization/RangerLensResource.java b/lens-cube/src/main/java/org/apache/lens/cube/authorization/RangerLensResource.java
new file mode 100644 (file)
index 0000000..c449424
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * 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.lens.cube.authorization;
+
+import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
+
+// Ranger equivalent for a lens resource
+
+class RangerLensResource extends RangerAccessResourceImpl {
+
+  private static final String KEY_TABLE = "table";
+  private static final String KEY_COLUMN = "column";
+
+  RangerLensResource(RangerLensAuthorizer.LensObjectType objectType, String table, String column) {
+
+    switch(objectType) {
+
+    case COLUMN:
+      setValue(KEY_TABLE, table);
+      setValue(KEY_COLUMN, column);
+      break;
+
+    case TABLE:
+      setValue(KEY_TABLE, table);
+      break;
+
+    case NONE:
+    default:
+      break;
+    }
+  }
+}
index 5543308..e7c109f 100644 (file)
@@ -158,6 +158,22 @@ public abstract class AbstractBaseTable extends AbstractCubeTable {
     return getExpressionByName(column);
   }
 
+
+
+  /**
+   * Return restricted columns of the table, which can be specified by property
+   * MetastoreUtil.getRestrictedColumnsKey(getName())
+   *
+   * @return set of restricted columns
+   */
+  public Set<String> getRestrictedColumns() {
+    String restrictedColsStr =
+      MetastoreUtil.getNamedStringValue(getProperties(), MetastoreUtil.getRestrictedColumnsKey(getName()));
+    log.info("Restricted cols : "+ restrictedColsStr + " for table : "+ this.getName());
+    return restrictedColsStr == null ? new HashSet<>() : new HashSet<>(Arrays.asList(StringUtils.split(restrictedColsStr
+        .toLowerCase(), ',')));
+  }
+
   /**
    * Alters the expression if already existing or just adds if it is new expression.
    *
index 43e827a..8f3f4aa 100644 (file)
@@ -48,7 +48,6 @@ public class CubeFactTable extends AbstractCubeTable implements FactTable {
     this.storagePrefixUpdatePeriodMap = getUpdatePeriodMap(getName(), getProperties());
   }
 
-
   public CubeFactTable(String cubeName, String factName, List<FieldSchema> columns,
     Map<String, Set<UpdatePeriod>> storageUpdatePeriods) {
     this(cubeName, factName, columns, storageUpdatePeriods, 0L, new HashMap<String, String>());
index 3952696..e6afcff 100644 (file)
@@ -29,12 +29,19 @@ import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.lens.api.metastore.*;
+
+import org.apache.lens.cube.authorization.AuthorizationUtil;
 import org.apache.lens.cube.error.LensCubeErrorCode;
 import org.apache.lens.cube.metadata.Storage.LatestInfo;
 import org.apache.lens.cube.metadata.Storage.LatestPartColumnInfo;
 import org.apache.lens.cube.metadata.timeline.PartitionTimeline;
 import org.apache.lens.cube.metadata.timeline.PartitionTimelineFactory;
+
 import org.apache.lens.server.api.LensConfConstants;
+import org.apache.lens.server.api.authorization.ActionType;
+import org.apache.lens.server.api.authorization.Authorizer;
+import org.apache.lens.server.api.authorization.LensPrivilegeObject;
+
 import org.apache.lens.server.api.error.LensException;
 import org.apache.lens.server.api.metastore.DataCompletenessChecker;
 import org.apache.lens.server.api.util.LensUtil;
@@ -110,22 +117,50 @@ public class CubeMetastoreClient {
 
   private Boolean isDataCompletenessCheckEnabled;
 
+  private Boolean isAuthorizationCheckEnabled;
+
+  private Authorizer authorizer;
+
   public DataCompletenessChecker getCompletenessChecker() {
     if (completenessChecker == null) {
       completenessChecker = ReflectionUtils.newInstance(config.getClass(LensConfConstants.COMPLETENESS_CHECKER_CLASS,
-              LensConfConstants.DEFAULT_COMPLETENESS_CHECKER, DataCompletenessChecker.class), this.config);
+        LensConfConstants.DEFAULT_COMPLETENESS_CHECKER, DataCompletenessChecker.class), this.config);
     }
     return completenessChecker;
   }
 
+  public Authorizer getAuthorizer() {
+    if (authorizer == null) {
+      authorizer = ReflectionUtils.newInstance(config.getClass(MetastoreConstants.AUTHORIZER_CLASS,
+        LensConfConstants.DEFAULT_AUTHORIZER, Authorizer.class), this.config);
+    }
+    return authorizer;
+  }
+
   public boolean isDataCompletenessCheckEnabled() {
     if (isDataCompletenessCheckEnabled == null) {
       isDataCompletenessCheckEnabled = config.getBoolean(LensConfConstants.ENABLE_DATACOMPLETENESS_CHECK,
-              LensConfConstants.DEFAULT_ENABLE_DATACOMPLETENESS_CHECK);
+        LensConfConstants.DEFAULT_ENABLE_DATACOMPLETENESS_CHECK);
     }
     return isDataCompletenessCheckEnabled;
   }
 
+  private boolean isAuthorizationEnabled() {
+    if (isAuthorizationCheckEnabled == null) {
+      isAuthorizationCheckEnabled = config.getBoolean(LensConfConstants.ENABLE_METASTORE_SCHEMA_AUTHORIZATION_CHECK,
+        LensConfConstants.DEFAULT_ENABLE_METASTORE_SCHEMA_AUTHORIZATION_CHECK);
+    }
+    return isAuthorizationCheckEnabled;
+  }
+
+  private void checkIfAuthorized() throws LensException {
+    if (isAuthorizationEnabled()) {
+      String currentdb = SessionState.get().getCurrentDatabase();
+      AuthorizationUtil.isAuthorized(getAuthorizer(), currentdb,
+        LensPrivilegeObject.LensPrivilegeObjectType.DATABASE, ActionType.UPDATE, getConf());
+    }
+  }
+
   /** extract storage name from fact and storage table name. String operation */
   private String extractStorageName(FactTable fact, String storageTableName) throws LensException {
     int ind = storageTableName.lastIndexOf(fact.getSourceFactName());
@@ -306,6 +341,7 @@ public class CubeMetastoreClient {
     Map<String, Set<UpdatePeriod>> storageAggregatePeriods, double weight, Map<String, String> properties,
     Map<String, StorageTableDesc> storageTableDescs, Map<String, Map<UpdatePeriod, String>> storageUpdatePeriodMap)
     throws LensException {
+    checkIfAuthorized();
     CubeFactTable factTable = new CubeFactTable(cubeName, factName, columns, storageAggregatePeriods, weight,
       properties, storageUpdatePeriodMap);
     createCubeTable(factTable, storageTableDescs);
@@ -314,11 +350,12 @@ public class CubeMetastoreClient {
 
   }
 
-  public <T extends Equals & HashCode & ToString> void createEntity(T entity) throws LensException {
+  public <T extends Equals & HashCode & ToString> void createEntity(T entity)
+    throws LensException {
     if (entity instanceof XStorage) {
       createStorage((XStorage) entity);
-    } else if  (entity instanceof XCube) {
-      createCube((XCube)entity);
+    } else if (entity instanceof XCube) {
+      createCube((XCube) entity);
     } else if (entity instanceof XDimension) {
       createDimension((XDimension) entity);
     } else if (entity instanceof XFact) {
@@ -328,7 +365,7 @@ public class CubeMetastoreClient {
     } else if (entity instanceof XSegmentation) {
       createSegmentation((XSegmentation) entity);
     } else {
-      throw new LensException("Unable to create entity " + entity + " as it's unrecognizable: "+ entity.getClass());
+      throw new LensException("Unable to create entity " + entity + " as it's unrecognizable: " + entity.getClass());
     }
   }
 
@@ -336,7 +373,7 @@ public class CubeMetastoreClient {
     throws LensException, HiveException {
     if (entity instanceof XStorage) {
       alterStorage((XStorage) entity);
-    } else if  (entity instanceof XCube) {
+    } else if (entity instanceof XCube) {
       alterCube((XCube)entity);
     } else if (entity instanceof XDimension) {
       alterDimension((XDimension) entity);
@@ -380,7 +417,7 @@ public class CubeMetastoreClient {
   public void createVirtualFactTable(String cubeName, String virtualFactName, String sourceFactName, Double weight,
     Map<String, String> properties) throws LensException {
     FactTable sourceFact = getFactTable(sourceFactName);
-
+    checkIfAuthorized();
     Optional<Double> optionalWeight = Optional.fromNullable(weight);
 
     CubeVirtualFactTable factTable = new CubeVirtualFactTable(cubeName, virtualFactName,
@@ -571,7 +608,7 @@ public class CubeMetastoreClient {
         .computeIfAbsent(timeLineKey, s -> new TreeMap<>())
         .computeIfAbsent(updatePeriod, k -> new CaseInsensitiveStringHashMap<>())
         .computeIfAbsent(partitionColumn, c -> PartitionTimelineFactory.get(
-        CubeMetastoreClient.this, storagTableName, updatePeriod, c));
+          CubeMetastoreClient.this, storagTableName, updatePeriod, c));
     }
 
     /** check partition existence in the appropriate timeline if it exists */
@@ -588,8 +625,8 @@ public class CubeMetastoreClient {
     public PartitionTimeline get(String fact, String storage, UpdatePeriod updatePeriod, String partCol)
       throws HiveException, LensException {
       return get(fact, storage) != null && get(fact, storage).get(updatePeriod) != null
-               && get(fact, storage).get(updatePeriod).get(partCol) != null ? get(fact, storage).get(updatePeriod)
-               .get(partCol) : null;
+        && get(fact, storage).get(updatePeriod).get(partCol) != null ? get(fact, storage).get(updatePeriod)
+        .get(partCol) : null;
     }
 
     /**
@@ -645,7 +682,7 @@ public class CubeMetastoreClient {
    * Get the instance of {@link CubeMetastoreClient} corresponding to {@link HiveConf}
    *
    * @param conf                  conf
-   * @return                      CubeMetastoreClient instance
+   * @return CubeMetastoreClient instance
    * @throws HiveException
    */
   public static CubeMetastoreClient getInstance(HiveConf conf) throws HiveException {
@@ -713,6 +750,7 @@ public class CubeMetastoreClient {
   }
 
   public void createStorage(Storage storage) throws LensException {
+    checkIfAuthorized();
     createCubeHiveTable(storage);
     // do a get to update cache
     getStorage(storage.getName());
@@ -731,6 +769,7 @@ public class CubeMetastoreClient {
    * @throws LensException
    */
   public void createCube(CubeInterface cube) throws LensException {
+    checkIfAuthorized();
     createCubeHiveTable((AbstractCubeTable) cube);
     // do a get to update cache
     getCube(cube.getName());
@@ -816,6 +855,7 @@ public class CubeMetastoreClient {
   public void createDimension(XDimension dim) throws LensException {
     createDimension(JAXBUtils.dimensionFromXDimension(dim));
   }
+
   /**
    * Create dimension in metastore defined by {@link Dimension} object
    *
@@ -823,6 +863,7 @@ public class CubeMetastoreClient {
    * @throws LensException
    */
   public void createDimension(Dimension dim) throws LensException {
+    checkIfAuthorized();
     createCubeHiveTable(dim);
     // do a get to update cache
     getDimension(dim.getName());
@@ -862,6 +903,7 @@ public class CubeMetastoreClient {
     Map<String, StorageTableDesc> storageTableDescs) throws LensException {
     CubeFactTable factTable =
       new CubeFactTable(cubeName, factName, columns, storageAggregatePeriods, weight, properties);
+    checkIfAuthorized();
     createCubeTable(factTable, storageTableDescs);
     // do a get to update cache
     getFactTable(factName);
@@ -877,9 +919,9 @@ public class CubeMetastoreClient {
    * @throws LensException
    */
   public void createSegmentation(String baseCubeName, String segmentationName, Set<Segment> segments,
-                                     double weight, Map<String, String> properties) throws LensException {
+    double weight, Map<String, String> properties) throws LensException {
     Segmentation cubeSeg =
-            new Segmentation(baseCubeName, segmentationName, segments, weight, properties);
+      new Segmentation(baseCubeName, segmentationName, segments, weight, properties);
     createSegmentation(cubeSeg);
     // do a get to update cache
     getSegmentation(segmentationName);
@@ -897,6 +939,7 @@ public class CubeMetastoreClient {
     createCubeDimensionTable(xDimTable.getDimensionName(), xDimTable.getTableName(), columns, xDimTable.getWeight(),
       updatePeriodMap, properties, storageDesc);
   }
+
   /**
    * Create a cube dimension table
    *
@@ -914,6 +957,7 @@ public class CubeMetastoreClient {
     throws LensException {
     CubeDimensionTable dimTable =
       new CubeDimensionTable(dimName, dimTblName, columns, weight, storageNames, properties);
+    checkIfAuthorized();
     createCubeTable(dimTable, storageTableDescs);
     // do a get to update cache
     getDimensionTable(dimTblName);
@@ -934,6 +978,7 @@ public class CubeMetastoreClient {
   public void createCubeDimensionTable(String dimName, String dimTblName, List<FieldSchema> columns, double weight,
     Map<String, UpdatePeriod> dumpPeriods, Map<String, String> properties,
     Map<String, StorageTableDesc> storageTableDescs) throws LensException {
+    checkIfAuthorized();
     CubeDimensionTable dimTable = new CubeDimensionTable(dimName, dimTblName, columns, weight, dumpPeriods, properties);
     createCubeTable(dimTable, storageTableDescs);
     // do a get to update cache
@@ -968,8 +1013,10 @@ public class CubeMetastoreClient {
       cubeSeg.getWeight(),
       JAXBUtils.mapFromXProperties(cubeSeg.getProperties()));
   }
+
   public void createSegmentation(Segmentation cubeSeg)
     throws LensException {
+    checkIfAuthorized();
     // create virtual cube table in metastore
     createCubeHiveTable(cubeSeg);
   }
@@ -986,6 +1033,7 @@ public class CubeMetastoreClient {
   public void addStorage(CubeFactTable fact, String storage, Set<UpdatePeriod> updatePeriods,
     Map<String, StorageTableDesc> storageTableDescs, Map<UpdatePeriod, String> updatePeriodStoragePrefix)
     throws LensException {
+    checkIfAuthorized();
     fact.addStorage(storage, updatePeriods, updatePeriodStoragePrefix);
     for (Map.Entry entry : storageTableDescs.entrySet()) {
       createOrAlterStorageHiveTable(getTableWithTypeFailFast(fact.getName(), CubeTableType.FACT),
@@ -1006,6 +1054,7 @@ public class CubeMetastoreClient {
    */
   public void addStorage(CubeDimensionTable dim, String storage, UpdatePeriod dumpPeriod,
     StorageTableDesc storageTableDesc) throws LensException {
+    checkIfAuthorized();
     dim.alterSnapshotDumpPeriod(storage, dumpPeriod);
     createOrAlterStorageHiveTable(getTableWithTypeFailFast(dim.getName(), CubeTableType.DIM_TABLE), storage,
       storageTableDesc);
@@ -1054,7 +1103,8 @@ public class CubeMetastoreClient {
    * @throws LensException
    */
   private List<Partition> addPartitions(String factOrDimTable, String storageName, UpdatePeriod updatePeriod,
-    List<StoragePartitionDesc> storagePartitionDescs, CubeTableType type) throws HiveException, LensException {
+    List<StoragePartitionDesc> storagePartitionDescs, CubeTableType type)
+    throws HiveException, LensException {
     String storageTableName = getStorageTableName(factOrDimTable, storageName, updatePeriod);
     if (type == CubeTableType.DIM_TABLE) {
       // Adding partition in dimension table.
@@ -1079,12 +1129,12 @@ public class CubeMetastoreClient {
       List<Partition> partsAdded = new ArrayList<>();
       // first update in memory, then add to hive table's partitions. delete is reverse.
       partitionTimelineCache.updateForAddition(factOrDimTable, storageName, updatePeriod,
-              getTimePartSpecs(storagePartitionDescs, getStorageTableStartDate(storageTableName,
-                getFactTable(factOrDimTable)), getStorageTableEndDate(storageTableName, getFactTable(factOrDimTable))));
+        getTimePartSpecs(storagePartitionDescs, getStorageTableStartDate(storageTableName,
+          getFactTable(factOrDimTable)), getStorageTableEndDate(storageTableName, getFactTable(factOrDimTable))));
       // Adding partition in fact table.
       if (storagePartitionDescs.size() > 0) {
         partsAdded = getStorage(storageName).addPartitions(getClient(), factOrDimTable, updatePeriod,
-                storagePartitionDescs, null, storageTableName);
+          storagePartitionDescs, null, storageTableName);
       }
       // update hive table
       alterTablePartitionCache((Storage.getPrefix(storageName) + factOrDimTable).toLowerCase(), updatePeriod,
@@ -1124,7 +1174,7 @@ public class CubeMetastoreClient {
 
 
   private Map<String, TreeSet<Date>> getTimePartSpecs(List<StoragePartitionDesc> storagePartitionDescs,
-                                                      Date storageStartDate, Date storageEndDate) throws LensException {
+    Date storageStartDate, Date storageEndDate) throws LensException {
     Date now = new Date();
     Map<String, HashSet<Date>> skippedParts = Maps.newHashMap();
     Map<String, TreeSet<Date>> timeSpecs = Maps.newHashMap();
@@ -1138,7 +1188,7 @@ public class CubeMetastoreClient {
         // check whether partition falls between storage table start_time and
         // end_time or d+2, in such case partition is eligible for registration.
         if ((entry.getValue().compareTo(storageStartDate) >= 0 && entry.getValue().compareTo(storageEndDate) < 0)
-                && entry.getValue().compareTo(DateUtil.resolveRelativeDate("now +2 days", now)) < 0) {
+          && entry.getValue().compareTo(DateUtil.resolveRelativeDate("now +2 days", now)) < 0) {
           timeSpecs.get(entry.getKey()).add(entry.getValue());
         } else {
           if (!skippedParts.containsKey(entry.getKey())) {
@@ -1153,7 +1203,7 @@ public class CubeMetastoreClient {
     }
     if (!skippedParts.isEmpty()) {
       log.info("List of partitions skipped : {}, because they fall before fact start time "
-          + "or after end time or they are future partitions", skippedParts);
+        + "or after end time or they are future partitions", skippedParts);
     }
     return timeSpecs;
   }
@@ -1432,8 +1482,8 @@ public class CubeMetastoreClient {
   }
 
   public boolean factPartitionExists(String factName, String storageName, UpdatePeriod updatePeriod,
-                                     Map<String, Date> partitionTimestamp,
-                                     Map<String, String> partSpec) throws HiveException, LensException {
+    Map<String, Date> partitionTimestamp,
+    Map<String, String> partSpec) throws HiveException, LensException {
     String storageTableName = getStorageTableName(factName, storageName, updatePeriod);
     return partitionExists(storageTableName, updatePeriod, partitionTimestamp, partSpec);
   }
@@ -1506,7 +1556,7 @@ public class CubeMetastoreClient {
     throws HiveException, LensException {
     String storageTableName = getFactOrDimtableStorageTableName(dimTblName, storageName);
     return partitionExists(storageTableName, getDimensionTable(dimTblName).getSnapshotDumpPeriods().get(storageName),
-            partitionTimestamps);
+      partitionTimestamps);
   }
 
   boolean latestPartitionExists(String factOrDimTblName, String storageName, String latestPartCol)
@@ -1561,9 +1611,11 @@ public class CubeMetastoreClient {
     }
     return ret == null ? new ArrayList<String>() : ret;
   }
+
   public Table getTableWithTypeFailFast(String tableName, CubeTableType type) throws LensException {
     return getTableWithType(tableName, type, true);
   }
+
   public Table getTableWithType(String tableName, CubeTableType type, boolean throwException) throws LensException {
     String typeName = type == null ? "nativetable" : type.name().toLowerCase();
     Table table = getTable(tableName, false);
@@ -1593,9 +1645,11 @@ public class CubeMetastoreClient {
     }
     return table;
   }
+
   public Table getTable(String tableName) throws LensException {
     return getTable(tableName, true);
   }
+
   public Table getTable(String tableName, boolean throwException) throws LensException {
     Table tbl;
     try {
@@ -1745,7 +1799,7 @@ public class CubeMetastoreClient {
    * Is the hive table a cube table?
    *
    * @param tbl table
-   * @return    whether it's a cube table or not
+   * @return whether it's a cube table or not
    */
   boolean isCube(Table tbl) {
     String tableType = tbl.getParameters().get(MetastoreConstants.TABLE_TYPE_KEY);
@@ -1756,9 +1810,9 @@ public class CubeMetastoreClient {
    * Is the hive table a dimension?
    *
    * @param tbl  table
-   * @return     whether the hive table is a dimension or not
+   * @return whether the hive table is a dimension or not
    */
-  boolean isDimension(Table tbl)  {
+  boolean isDimension(Table tbl) {
     String tableType = tbl.getParameters().get(MetastoreConstants.TABLE_TYPE_KEY);
     return CubeTableType.DIMENSION.name().equals(tableType);
   }
@@ -1766,6 +1820,7 @@ public class CubeMetastoreClient {
   public XFact getXFactTable(String tableName) throws LensException {
     return getXFactTable(getFactTable(tableName));
   }
+
   public XFact getXFactTable(FactTable ft) throws LensException {
 
     XFact fact;
@@ -1823,6 +1878,7 @@ public class CubeMetastoreClient {
   public XDimensionTable getXDimensionTable(String dimTable) throws LensException {
     return getXDimensionTable(getDimensionTable(dimTable));
   }
+
   public XDimensionTable getXDimensionTable(CubeDimensionTable dimTable) throws LensException {
     XDimensionTable dt = JAXBUtils.dimTableFromCubeDimTable(dimTable);
     if (!dimTable.getStorages().isEmpty()) {
@@ -1839,6 +1895,7 @@ public class CubeMetastoreClient {
     }
     return dt;
   }
+
   /**
    * Get {@link CubeDimensionTable} object corresponding to the name
    *
@@ -1849,6 +1906,7 @@ public class CubeMetastoreClient {
   public CubeDimensionTable getDimensionTable(String tableName) throws LensException {
     return getDimensionTable(tableName, true);
   }
+
   private CubeDimensionTable getDimensionTable(String tableName, boolean throwException)
     throws LensException {
     tableName = tableName.trim().toLowerCase();
@@ -1896,6 +1954,7 @@ public class CubeMetastoreClient {
   public Storage getStorage(String storageName) throws LensException {
     return getStorage(storageName, true);
   }
+
   public Storage getStorage(String storageName, boolean throwException) throws LensException {
     storageName = storageName.trim().toLowerCase();
     Storage storage = allStorages.get(storageName);
@@ -1964,6 +2023,7 @@ public class CubeMetastoreClient {
   public Dimension getDimension(String tableName) throws LensException {
     return getDimension(tableName, true);
   }
+
   private Dimension getDimension(String tableName, boolean throwException) throws LensException {
     if (tableName == null) {
       return null;
@@ -1996,6 +2056,7 @@ public class CubeMetastoreClient {
   public FactTable getFactTable(String tableName) throws LensException {
     return getFactTable(tableName, true);
   }
+
   private FactTable getFactTable(String tableName, boolean throwException) throws LensException {
     tableName = tableName.trim().toLowerCase();
     FactTable fact = allFactTables.get(tableName);
@@ -2003,14 +2064,14 @@ public class CubeMetastoreClient {
       synchronized (allFactTables) {
         if (!allFactTables.containsKey(tableName)) {
           Table tbl = getTableWithType(tableName, CubeTableType.FACT, throwException);
-          if (tbl != null){
+          if (tbl != null) {
             String sourceFactName = tbl.getParameters().get(getSourceFactNameKey(tbl.getTableName()));
             if (sourceFactName != null) {
               fact = new CubeVirtualFactTable(tbl, getCubeFactTable(sourceFactName));
               if (factToVirtualFactMapping.get(sourceFactName) != null) {
                 List<String> prevList = factToVirtualFactMapping.get(sourceFactName);
                 prevList.add(tableName);
-              }else{
+              } else {
                 List<String> newList = new ArrayList<>();
                 newList.add(tableName);
                 factToVirtualFactMapping.put(sourceFactName, newList);
@@ -2042,6 +2103,7 @@ public class CubeMetastoreClient {
   public Segmentation getSegmentation(String segName) throws LensException {
     return getSegmentation(segName, true);
   }
+
   public Segmentation getSegmentation(String segName, boolean throwException) throws LensException {
     segName = segName.trim().toLowerCase();
     Segmentation seg = allSegmentations.get(segName);
@@ -2164,7 +2226,7 @@ public class CubeMetastoreClient {
       List<Dimension> dims = new ArrayList<>();
       try {
         for (String table : getAllHiveTableNames()) {
-          Dimension dim =  getDimension(table, false);
+          Dimension dim = getDimension(table, false);
           if (dim != null) {
             dims.add(dim);
           }
@@ -2454,6 +2516,7 @@ public class CubeMetastoreClient {
       ((XDerivedCube) cube).getParent()) : null;
     alterCube(cube.getName(), JAXBUtils.hiveCubeFromXCube(cube, parent));
   }
+
   /**
    * Alter cube specified by the name to new definition
    *
@@ -2461,7 +2524,9 @@ public class CubeMetastoreClient {
    * @param cube     The new cube definition {@link Cube} or {@link DerivedCube}
    * @throws HiveException
    */
-  public void alterCube(String cubeName, CubeInterface cube) throws HiveException, LensException {
+  public void alterCube(String cubeName, CubeInterface cube)
+    throws HiveException, LensException {
+    checkIfAuthorized();
     Table cubeTbl = getTableWithTypeFailFast(cubeName, CubeTableType.CUBE);
     alterCubeTable(cubeName, cubeTbl, (AbstractCubeTable) cube);
     if (enableCaching) {
@@ -2479,7 +2544,9 @@ public class CubeMetastoreClient {
     alterDimension(newDim.getName(), JAXBUtils.dimensionFromXDimension(newDim));
   }
 
-  public void alterDimension(String dimName, Dimension newDim) throws HiveException, LensException {
+  public void alterDimension(String dimName, Dimension newDim)
+    throws HiveException, LensException {
+    checkIfAuthorized();
     Table tbl = getTableWithTypeFailFast(dimName, CubeTableType.DIMENSION);
     alterCubeTable(dimName, tbl, newDim);
     if (enableCaching) {
@@ -2496,7 +2563,10 @@ public class CubeMetastoreClient {
   public void alterStorage(XStorage storage) throws LensException, HiveException {
     alterStorage(storage.getName(), JAXBUtils.storageFromXStorage(storage));
   }
-  public void alterStorage(String storageName, Storage storage) throws LensException, HiveException {
+
+  public void alterStorage(String storageName, Storage storage)
+    throws LensException, HiveException {
+    checkIfAuthorized();
     Table storageTbl = getTableWithTypeFailFast(storageName, CubeTableType.STORAGE);
     alterCubeTable(storageName, storageTbl, storage);
     if (enableCaching) {
@@ -2523,7 +2593,8 @@ public class CubeMetastoreClient {
    * @throws LensException
    */
   public void dropCube(String cubeName) throws LensException {
-    getTableWithTypeFailFast(cubeName, CubeTableType.CUBE);
+    checkIfAuthorized();
+    getCube(getTableWithTypeFailFast(cubeName, CubeTableType.CUBE));
     allCubes.remove(cubeName.trim().toLowerCase());
     dropHiveTable(cubeName);
   }
@@ -2536,6 +2607,7 @@ public class CubeMetastoreClient {
    */
   public void dropDimension(String dimName) throws LensException {
     getTableWithTypeFailFast(dimName, CubeTableType.DIMENSION);
+    checkIfAuthorized();
     allDims.remove(dimName.trim().toLowerCase());
     dropHiveTable(dimName);
   }
@@ -2550,6 +2622,7 @@ public class CubeMetastoreClient {
   public void dropFact(String factName, boolean cascade) throws LensException {
     getTableWithTypeFailFast(factName, CubeTableType.FACT);
     FactTable fact = getFactTable(factName);
+    checkIfAuthorized();
     if (cascade) {
       for (String storage : fact.getStorages()) {
         dropStorageFromFact(factName, storage, false);
@@ -2602,6 +2675,7 @@ public class CubeMetastoreClient {
 
   public void dropSegmentation(String segName) throws LensException {
     getTableWithTypeFailFast(segName, CubeTableType.SEGMENTATION);
+    checkIfAuthorized();
     dropHiveTable(segName);
     allSegmentations.remove(segName.trim().toLowerCase());
   }
@@ -2615,13 +2689,14 @@ public class CubeMetastoreClient {
    */
   public void dropStorageFromFact(String factName, String storage) throws LensException {
     CubeFactTable cft = getCubeFactTable(factName);
+    checkIfAuthorized();
     dropHiveTablesForStorage(factName, storage);
     cft.dropStorage(storage);
     alterCubeTable(factName, getTableWithTypeFailFast(factName, CubeTableType.FACT), cft);
     updateFactCache(factName);
   }
 
-  private void dropHiveTablesForStorage(String factName, String storage) throws LensException{
+  private void dropHiveTablesForStorage(String factName, String storage) throws LensException {
     CubeFactTable cft = getCubeFactTable(factName);
     Set<String> droppedTables = new HashSet<>();
     for (Map.Entry updatePeriodEntry : cft.getStoragePrefixUpdatePeriodMap().get(storage).entrySet()) {
@@ -2633,6 +2708,7 @@ public class CubeMetastoreClient {
       droppedTables.add(storageTableName);
     }
   }
+
   // updateFact will be false when fact is fully dropped
   private void dropStorageFromFact(String factName, String storage, boolean updateFact)
     throws LensException {
@@ -2645,6 +2721,7 @@ public class CubeMetastoreClient {
     }
   }
 
+
   /**
    * Drop a storage from dimension
    *
@@ -2652,13 +2729,15 @@ public class CubeMetastoreClient {
    * @param storage    storage
    * @throws HiveException
    */
-  public void dropStorageFromDim(String dimTblName, String storage) throws HiveException, LensException {
+  public void dropStorageFromDim(String dimTblName, String storage)
+    throws HiveException, LensException {
     dropStorageFromDim(dimTblName, storage, true);
   }
 
   // updateDimTbl will be false when dropping dimTbl
   private void dropStorageFromDim(String dimTblName, String storage, boolean updateDimTbl)
     throws LensException {
+    checkIfAuthorized();
     CubeDimensionTable cdt = getDimensionTable(dimTblName);
     String storageTableName = getFactOrDimtableStorageTableName(dimTblName, storage);
     dropHiveTable(storageTableName);
@@ -2677,7 +2756,9 @@ public class CubeMetastoreClient {
    * @param cascade    If true, will drop all the dimension storages
    * @throws HiveException
    */
-  public void dropDimensionTable(String dimTblName, boolean cascade) throws LensException {
+  public void dropDimensionTable(String dimTblName, boolean cascade)
+    throws LensException {
+    checkIfAuthorized();
     getTableWithTypeFailFast(dimTblName, CubeTableType.DIM_TABLE);
     CubeDimensionTable dim = getDimensionTable(dimTblName);
     if (cascade) {
@@ -2712,10 +2793,11 @@ public class CubeMetastoreClient {
    * @throws HiveException
    */
   public void alterCubeFactTable(String factTableName, FactTable cubeFactTable,
-                                 Map<String, StorageTableDesc> storageTableDescs,
-                                 Map<String, String> props)
+    Map<String, StorageTableDesc> storageTableDescs,
+    Map<String, String> props)
     throws HiveException, LensException {
     Table factTbl = getTableWithTypeFailFast(factTableName, CubeTableType.FACT);
+    checkIfAuthorized();
     if (!props.isEmpty()) {
       cubeFactTable.getProperties().putAll(props);
     }
@@ -2731,7 +2813,8 @@ public class CubeMetastoreClient {
     updateAllVirtualFacts(getFactTable(factTableName));
   }
 
-  public void alterSegmentation(XSegmentation cubeSeg) throws LensException, HiveException {
+  public void alterSegmentation(XSegmentation cubeSeg) throws LensException,
+    HiveException {
     alterSegmentation(cubeSeg.getName(), segmentationFromXSegmentation(cubeSeg));
   }
 
@@ -2748,6 +2831,7 @@ public class CubeMetastoreClient {
   public void alterSegmentation(String segName, Segmentation seg)
     throws HiveException, LensException {
     getTableWithTypeFailFast(segName, CubeTableType.SEGMENTATION);
+    checkIfAuthorized();
     if (!(getSegmentation(segName) == seg)) {
       dropSegmentation(segName);
       createSegmentation(seg);
@@ -2765,11 +2849,11 @@ public class CubeMetastoreClient {
     if (enableCaching) {
       Table factTbl = getTableWithTypeFailFast(factTableName, CubeTableType.FACT);
       FactTable refreshedTable;
-      if (factTbl.getParameters().get(getSourceFactNameKey(factTableName)) != null){
+      if (factTbl.getParameters().get(getSourceFactNameKey(factTableName)) != null) {
         String sourceFactName = factTbl.getParameters().get(getSourceFactNameKey(factTableName));
         refreshedTable = new CubeVirtualFactTable(refreshTable(factTableName),
           getCubeFactTable(sourceFactName));
-      }else {
+      } else {
         refreshedTable = new CubeFactTable(refreshTable(factTableName));
       }
       allFactTables.put(factTableName.trim().toLowerCase(), refreshedTable);
@@ -2817,11 +2901,14 @@ public class CubeMetastoreClient {
       allDimTables.put(dimTblName.trim().toLowerCase(), getDimensionTable(refreshTable(dimTblName)));
     }
   }
-  public void alterCubeDimensionTable(XDimensionTable dimensionTable) throws LensException, HiveException {
+
+  public void alterCubeDimensionTable(XDimensionTable dimensionTable)
+    throws LensException, HiveException {
     alterCubeDimensionTable(dimensionTable.getTableName(),
       JAXBUtils.cubeDimTableFromDimTable(dimensionTable),
       JAXBUtils.tableDescPrefixMapFromXStorageTables(dimensionTable.getStorageTables()));
   }
+
   /**
    * Alter dimension table with new dimension definition and underlying storage tables as well
    *
@@ -2830,7 +2917,9 @@ public class CubeMetastoreClient {
    * @throws HiveException
    */
   public void alterCubeDimensionTable(String dimTableName, CubeDimensionTable cubeDimensionTable,
-    Map<String, StorageTableDesc> storageTableDescs) throws HiveException, LensException {
+    Map<String, StorageTableDesc> storageTableDescs)
+    throws HiveException, LensException {
+    checkIfAuthorized();
     Table dimTbl = getTableWithTypeFailFast(dimTableName, CubeTableType.DIM_TABLE);
     alterCubeTable(dimTableName, dimTbl, cubeDimensionTable);
     if (storageTableDescs != null) {
@@ -2862,7 +2951,7 @@ public class CubeMetastoreClient {
   public boolean isStorageTableCandidateForRange(String storageTableName, Date fromDate, Date toDate)
     throws LensException {
     List<Date> storageEndDates = getStorageTimes(storageTableName, MetastoreUtil.getStoragetableEndTimesKey());
-    for(Date endDate : storageEndDates) {
+    for (Date endDate : storageEndDates) {
       // endDate is exclusive
       if (endDate.before(fromDate) || endDate.equals(fromDate)) {
         log.debug("from date {} is after validity end time: {}, hence discarding {}",
@@ -2872,7 +2961,7 @@ public class CubeMetastoreClient {
     }
 
     List<Date> storageStartDates = getStorageTimes(storageTableName, MetastoreUtil.getStoragetableStartTimesKey());
-    for(Date startDate : storageStartDates) {
+    for (Date startDate : storageStartDates) {
       // toDate is exclusive on the range
       if (startDate.after(toDate) || startDate.equals(toDate)) {
         log.debug("to date {} is before validity start time: {}, hence discarding {}",
@@ -2887,7 +2976,7 @@ public class CubeMetastoreClient {
   public boolean isStorageTablePartitionACandidate(String storageTableName, Date partDate)
     throws LensException {
     List<Date> storageStartDates = getStorageTimes(storageTableName, MetastoreUtil.getStoragetableStartTimesKey());
-    for(Date startDate : storageStartDates) {
+    for (Date startDate : storageStartDates) {
       if (partDate.before(startDate)) {
         log.info("part date {} is before validity start time: {}, hence discarding {}",
           partDate, startDate, storageTableName);
@@ -2896,7 +2985,7 @@ public class CubeMetastoreClient {
     }
 
     List<Date> storageEndDates = getStorageTimes(storageTableName, MetastoreUtil.getStoragetableEndTimesKey());
-    for(Date endDate : storageEndDates) {
+    for (Date endDate : storageEndDates) {
       // end date should be exclusive
       if (partDate.after(endDate) || partDate.equals(endDate)) {
         log.info("part date {} is after validity end time: {}, hence discarding {}",
index 945fe26..160addb 100644 (file)
@@ -26,6 +26,7 @@ public final class MetastoreConstants {
   public static final String TABLE_TYPE_KEY = "cube.table.type";
   public static final String CUBE_TABLE_PFX = "cube.table.";
   public static final String WEIGHT_KEY_SFX = ".weight";
+  public static final String AUTHORIZER_CLASS = "authorizer.class";
 
   public static final String BASE_KEY_PFX = "base.";
   public static final String EXPRESSIONS_LIST_SFX = ".expressions.list";
@@ -51,6 +52,7 @@ public final class MetastoreConstants {
   public static final String CUBE_NAME_SFX = ".cubename";
   public static final String SOURCE_NAME_SFX = ".source";
   public static final String VALID_COLUMNS_SFX = ".valid.columns";
+  public static final String RESTRICTED_COLUMNS_SFX = ".restricted.columns";
   public static final String FACT_AGGREGATED_PROPERTY = "cube.fact.is.aggregated";
   public static final String FACT_ABSOLUTE_START_TIME = "cube.fact.absolute.start.time";
   public static final String FACT_RELATIVE_START_TIME = "cube.fact.relative.start.time";
index fbc37ac..44411f2 100644 (file)
@@ -374,6 +374,10 @@ public class MetastoreUtil {
     return getFactKeyPrefix(name) + VALID_COLUMNS_SFX;
   }
 
+  public static String getRestrictedColumnsKey(String name) {
+    return getCubePrefix(name) + RESTRICTED_COLUMNS_SFX;
+  }
+
   public static String getCubeTableWeightKey(String name) {
     return getCubeTableKeyPrefix(name) + WEIGHT_KEY_SFX;
   }
index 143b266..5ddc950 100644 (file)
@@ -146,6 +146,7 @@ public class CubeQueryRewriter {
     // Rewrite base trees (groupby, having, orderby, limit) using aliases
     rewriters.add(new AliasReplacer());
     ExpressionResolver exprResolver = new ExpressionResolver();
+    QueryAuthorizationResolver queryAuthorizationResolver = new QueryAuthorizationResolver(conf);
     DenormalizationResolver denormResolver = new DenormalizationResolver();
     CandidateTableResolver candidateTblResolver = new CandidateTableResolver(conf);
     StorageTableResolver storageTableResolver = new StorageTableResolver(conf);
@@ -155,6 +156,8 @@ public class CubeQueryRewriter {
     rewriters.add(exprResolver);
     // Phase 1 of denormResolver: De-normalized columns resolved
     rewriters.add(denormResolver);
+    // authorization check
+    rewriters.add(queryAuthorizationResolver);
     // Resolve time ranges
     rewriters.add(new TimerangeResolver());
     // Phase 1 of candidateTblResolver: Resolve candidate storages and dimension tables for columns queried
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/QueryAuthorizationResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/QueryAuthorizationResolver.java
new file mode 100644 (file)
index 0000000..78dd642
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * 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.lens.cube.parse;
+
+import java.util.*;
+
+import org.apache.lens.cube.authorization.AuthorizationUtil;
+import org.apache.lens.cube.metadata.*;
+import org.apache.lens.server.api.LensConfConstants;
+import org.apache.lens.server.api.authorization.ActionType;
+import org.apache.lens.server.api.authorization.Authorizer;
+import org.apache.lens.server.api.authorization.LensPrivilegeObject;
+import org.apache.lens.server.api.error.LensException;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.util.ReflectionUtils;
+
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class QueryAuthorizationResolver implements ContextRewriter {
+
+  @Getter
+  private Authorizer authorizer;
+  @Getter
+  private Boolean isAuthorizationCheckEnabled;
+
+  QueryAuthorizationResolver(Configuration conf) {
+    isAuthorizationCheckEnabled = conf.getBoolean(LensConfConstants.ENABLE_QUERY_AUTHORIZATION_CHECK,
+      LensConfConstants.DEFAULT_ENABLE_QUERY_AUTHORIZATION_CHECK);
+    authorizer = ReflectionUtils.newInstance(
+      conf.getClass(MetastoreConstants.AUTHORIZER_CLASS, LensConfConstants.DEFAULT_AUTHORIZER, Authorizer.class),
+      conf);
+  }
+  @Override
+  public void rewriteContext(CubeQueryContext cubeql) throws LensException {
+
+    log.info("==> Query Authorization enabled : "+ isAuthorizationCheckEnabled);
+    if (isAuthorizationCheckEnabled) {
+      for (Map.Entry<String, Set<String>> entry : cubeql.getTblAliasToColumns().entrySet()) {
+        String alias = entry.getKey();
+        // skip default alias
+        if (Objects.equals(alias, CubeQueryContext.DEFAULT_TABLE)) {
+          continue;
+        }
+        AbstractCubeTable tbl = cubeql.getCubeTableForAlias(alias);
+        Set<String> queriedColumns = entry.getValue();
+
+        Set<String> restrictedFieldsQueried =
+          getRestrictedColumnsFromQuery(((AbstractBaseTable) tbl).getRestrictedColumns(), queriedColumns);
+        log.info("Restricted queriedColumns queried : "+ restrictedFieldsQueried);
+        if (restrictedFieldsQueried != null && !restrictedFieldsQueried.isEmpty()) {
+          for (String col : restrictedFieldsQueried) {
+            AuthorizationUtil.isAuthorized(getAuthorizer(), tbl.getName(), col,
+              LensPrivilegeObject.LensPrivilegeObjectType.COLUMN, ActionType.SELECT, cubeql.getConf());
+          }
+        }
+      }
+    }
+    log.info("<== Query Authorization enabled : "+ isAuthorizationCheckEnabled);
+  }
+
+  /*
+  * Returns the intersection of queried and restricted columns of table
+  * */
+  private static Set<String> getRestrictedColumnsFromQuery(Set<String> restrictedColumns, Set<String> queriedColumns){
+    restrictedColumns.retainAll(queriedColumns);
+    return restrictedColumns;
+  }
+}
diff --git a/lens-cube/src/main/resources/ranger-sample.json b/lens-cube/src/main/resources/ranger-sample.json
new file mode 100644 (file)
index 0000000..51e0e60
--- /dev/null
@@ -0,0 +1,100 @@
+{
+  "id":1,
+  "name": "lens",
+  "implClass": "org.apache.ranger.plugin.service.RangerDefaultService",
+  "label": "Sample Repository",
+  "description": "Sample Repository",
+  "guid": "test",
+  "resources":
+  [
+    {
+      "itemId": 1,
+      "name": "table",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": true,
+      "excludesSupported": false,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+      "matcherOptions": { "wildCard":true, "ignoreCase":false },
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Lens database/cube",
+      "description": "Lens database/cube"
+    },
+    {
+      "itemId": 2,
+      "name": "column",
+      "type": "string",
+      "level": 30,
+      "parent": "table",
+      "mandatory": false,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": { "wildCard":true, "ignoreCase":true },
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Lens Column",
+      "description": "Lens Column"
+    }
+  ],
+
+  "accessTypes":
+  [
+    {
+      "itemId": 1,
+      "name": "create",
+      "label": "create"
+    },
+
+    {
+      "itemId": 2,
+      "name": "read",
+      "label": "read"
+    },
+    {
+      "itemId": 3,
+      "name": "update",
+      "label": "update"
+    },
+
+    {
+      "itemId": 4,
+      "name": "delete",
+      "label": "delete"
+    },
+
+    {
+      "itemId": 5,
+      "name": "select",
+      "label": "select"
+    }
+  ],
+
+  "configs":
+  [
+
+  ],
+
+  "enums":
+  [
+
+  ],
+
+  "contextEnrichers":
+  [
+
+  ],
+
+  "policyConditions":
+  [
+
+  ]
+}
+
index 2776123..2a912ad 100644 (file)
     <description>List of policy decider classes</description>
   </property>
 
+  <property>
+    <name>lens.cube.query.user.groups.authorization.enable</name>
+    <value>false</value>
+    <description>true if authorization is based on User Groups, false otherwise</description>
+  </property>
+
+  <property>
+    <name>lens.cube.query.user.name.authorization.enable</name>
+    <value>false</value>
+    <description>true if authorization is based on User Name, false otherwise</description>
+  </property>
+
 </configuration>
index 2c69eef..c18d732 100644 (file)
     <description>List of classes to decide policies</description>
   </property>
 
+  <property>
+    <name>lens.cube.query.user.groups.authorization.enable</name>
+    <value>false</value>
+    <description>true if authorization is based on User Groups, false otherwise</description>
+  </property>
+
+  <property>
+    <name>lens.cube.query.user.name.authorization.enable</name>
+    <value>false</value>
+    <description>true if authorization is based on User Name, false otherwise</description>
+  </property>
+
 </configuration>
index 7659555..d25932d 100644 (file)
@@ -43,6 +43,5 @@
         <time_part_cols>dt</time_part_cols>
       </table_desc>
     </storage_table>
-
   </storage_tables>
 </x_dimension_table>
diff --git a/lens-query-lib/src/main/java/org/apache/lens/lib/query/FileSystemUtil.java b/lens-query-lib/src/main/java/org/apache/lens/lib/query/FileSystemUtil.java
new file mode 100644 (file)
index 0000000..c4eeb8e
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * 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.lens.lib.query;
+
+import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.UserGroupInformation;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class FileSystemUtil {
+
+  private FileSystemUtil() {}
+
+  public static FileSystem createFileSystem(String proxyUser, Path path) {
+    try {
+      UserGroupInformation ugi = UserGroupInformation.createProxyUser(proxyUser, UserGroupInformation.getLoginUser());
+      return ugi.doAs((PrivilegedExceptionAction<FileSystem>) () -> open(path));
+    } catch (IOException e) {
+      log.error("error initializing filesystem, giving up leadership", e);
+      throw new RuntimeException(e);
+    } catch (InterruptedException e) {
+      log.error("interrupted while initializing filesystem, giving up leadership", e);
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static FileSystem open(Path filePath) throws IOException {
+    Configuration conf = new Configuration();
+    conf.setBoolean("fs.automatic.close", false);
+    return filePath.getFileSystem(conf);
+  }
+
+}
index 8e9859f..3ba4655 100644 (file)
@@ -23,6 +23,8 @@ import java.io.OutputStreamWriter;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+import org.apache.lens.server.api.LensConfConstants;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -107,8 +109,12 @@ public class ZipFileFormatter extends AbstractFileFormatter {
     finalPath = new Path(pathStr, finalPathStr + ctx.getQueryHandle().toString() + ".zip");
     tmpPath = new Path(pathStr, ctx.getQueryHandle().toString() + ".tmp.zip");
 
-    fs = finalPath.getFileSystem(ctx.getConf());
-
+    if (ctx.getConf().getBoolean(LensConfConstants.READ_RESULT_FROM_HDFS,
+      LensConfConstants.DEFAULT_READ_RESULT_FROM_HDFS)) {
+      fs = FileSystemUtil.createFileSystem(ctx.getSubmittedUser(), new Path(pathStr));
+    } else {
+      fs = finalPath.getFileSystem(ctx.getConf());
+    }
     zipOut = new ZipOutputStream((fs.create(tmpPath)));
     ZipEntry zipEntry = new ZipEntry(getQueryResultFileName());
     zipOut.putNextEntry(zipEntry);
index 58a235a..efaf5d2 100644 (file)
@@ -21,6 +21,8 @@ package org.apache.lens.server.api;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.lens.api.parse.Parser;
+import org.apache.lens.server.api.authorization.Authorizer;
+import org.apache.lens.server.api.authorization.DefaultAuthorizer;
 import org.apache.lens.server.api.error.LensException;
 import org.apache.lens.server.api.metastore.*;
 import org.apache.lens.server.api.query.DefaultDownloadResultUrlProvider;
@@ -270,6 +272,11 @@ public final class LensConfConstants {
   public static final String SESSION_CLUSTER_USER = SESSION_PFX + "cluster.user";
 
   /**
+   * The Constant SESSION_USER_GROUPS.
+   */
+  public static final String SESSION_USER_GROUPS = SESSION_PFX + "user.groups";
+
+  /**
    * The Constant MAPRED_JOB_QUEUE_NAME.
    */
   public static final String MAPRED_JOB_QUEUE_NAME = "mapred.job.queue.name";
@@ -290,12 +297,23 @@ public final class LensConfConstants {
    */
   public static final String USER_RESOLVER_TYPE = SERVER_PFX + "user.resolver.type";
 
+  // ldap user to user group for authorization checks
+  /**
+   * The Constant USER_GROUP_TYPE.
+   */
+  public static final String USER_GROUP_TYPE = SERVER_PFX + "user.group.type";
+
   /**
    * The Constant USER_RESOLVER_FIXED_VALUE.
    */
   public static final String USER_RESOLVER_FIXED_VALUE = SERVER_PFX + "user.resolver.fixed.value";
 
   /**
+   * The Constant USER_GROUP_FIXED_VALUE.
+   */
+  public static final String USER_GROUP_FIXED_VALUE = SERVER_PFX + "user.group.fixed.value";
+
+  /**
    * The Constant USER_RESOLVER_PROPERTYBASED_FILENAME.
    */
   public static final String USER_RESOLVER_PROPERTYBASED_FILENAME = SERVER_PFX + "user.resolver.propertybased.filename";
@@ -316,6 +334,11 @@ public final class LensConfConstants {
   public static final String USER_RESOLVER_CUSTOM_CLASS = SERVER_PFX + "user.resolver.custom.class";
 
   /**
+   * The Constant USER_GROUP_CUSTOM_CLASS.
+   */
+  public static final String USER_GROUP_CUSTOM_CLASS = SERVER_PFX + "user.group.custom.class";
+
+  /**
    * The Constant USER_RESOLVER_CACHE_EXPIRY.
    */
   public static final String USER_RESOLVER_CACHE_EXPIRY = SERVER_PFX + "user.resolver.cache.expiry";
@@ -374,6 +397,26 @@ public final class LensConfConstants {
   public static final String USER_RESOLVER_LDAP_SEARCH_FILTER = SERVER_PFX + "user.resolver.ldap.search.filter";
 
   /**
+   * The Constant USER_AUTHORIZATION.
+   */
+  public static final String USER_NAME_BASED_AUTHORIZATION =  "lens.cube.query.user.name.authorization.enable";
+
+  /**
+   * The Constant USER_GROUPS_BASED_AUTHORIZATION.
+   */
+  public static final String USER_GROUPS_BASED_AUTHORIZATION = "lens.cube.query.user.groups.authorization.enable";
+
+  /**
+   * The default USER_AUTHORIZATION.
+   */
+  public static final Boolean DEFAULT_USER_NAME_AUTHORIZATION = false;
+
+  /**
+   * The default USER_GROUPS_BASED_AUTHORIZATION.
+   */
+  public static final Boolean DEFAULT_USER_GROUPS_AUTHORIZATION = false;
+
+  /**
    * The Constant STORAGE_COST.
    */
   public static final String STORAGE_COST = METASTORE_PFX + "table.storage.cost";
@@ -439,7 +482,7 @@ public final class LensConfConstants {
     return SERVER_PFX + featureName + WS_FEATURE_IMPL_SFX;
   }
 
-  /**
+    /**
    * Gets the WS listener impl conf key.
    *
    * @param listenerName the listener name
@@ -715,6 +758,16 @@ public final class LensConfConstants {
   public static final String RESULT_FS_READ_URL = QUERY_PFX + "result.fs.read.url";
 
   /**
+   * The Constant READ_RESULT_FROM_HDFS.
+   */
+  public static final String READ_RESULT_FROM_HDFS = QUERY_PFX + "read.result.hdfs";
+
+  /**
+   * The Constant DEFAULT_READ_RESULT_FROM_HDFS.
+   */
+  public static final Boolean DEFAULT_READ_RESULT_FROM_HDFS = false;
+
+  /**
    * The Constant AUX_JARS.
    */
   public static final String AUX_JARS = SESSION_PFX + "aux.jars";
@@ -1284,6 +1337,10 @@ public final class LensConfConstants {
   public static final Class<? extends DataCompletenessChecker> DEFAULT_COMPLETENESS_CHECKER =
           DefaultChecker.class.asSubclass(DataCompletenessChecker.class);
 
+
+  public static final Class<? extends Authorizer> DEFAULT_AUTHORIZER =
+    DefaultAuthorizer.class.asSubclass(Authorizer.class);
+
   /**
    * This property is to enable Data Completeness Checks while resolving partitions.
    */
@@ -1295,6 +1352,38 @@ public final class LensConfConstants {
   public static final boolean DEFAULT_ENABLE_DATACOMPLETENESS_CHECK = false;
 
   /**
+   * This property is to enable authorization checks while query planning.
+   */
+  public static final String ENABLE_QUERY_AUTHORIZATION_CHECK = "lens.cube.metastore.enable.query.authorization.check";
+
+  /**
+   * Default Value of the config "lens.cube.metastore.enable.query.authorization.check"
+   */
+  public static final boolean DEFAULT_ENABLE_QUERY_AUTHORIZATION_CHECK = false;
+
+  /**
+   * This property is to enable authorization checks while downloading result.
+   */
+  public static final String ENABLE_RESULT_DOWNLOAD_AUTHORIZATION_CHECK =
+    "lens.enable.result.download.authorization.check";
+
+  /**
+   * Default Value of the config "lens.enable.result.download.authorization.check"
+   */
+  public static final boolean DEFAULT_ENABLE_RESULT_DOWNLOAD_AUTHORIZATION_CHECK = false;
+
+  /**
+   * This property is to enable authorization checks for schema changes.
+   */
+  public static final String ENABLE_METASTORE_SCHEMA_AUTHORIZATION_CHECK =
+    "lens.cube.metastore.enable.metastore.authorization.check";
+
+  /**
+   * Default Value of the config "lens.cube.metastore.enable.schema.authorization.check"
+   */
+  public static final boolean DEFAULT_ENABLE_METASTORE_SCHEMA_AUTHORIZATION_CHECK = false;
+
+  /**
    * This property is for setting static cost to driver
    */
   public static final String DRIVER_QUERY_COST = DRIVER_PFX + "query.cost";
index 449120d..21c3027 100644 (file)
@@ -31,4 +31,32 @@ public class LensErrorInfo {
   @Getter
   private String errorName;
 
+  @Override
+  public boolean equals(final Object o) {
+
+    if (this == o) {
+      return true;
+    }
+
+    if (!(o instanceof LensErrorInfo)) {
+      return false;
+    }
+
+    LensErrorInfo e = (LensErrorInfo) o;
+    return errorCode == e.errorCode && errorWeight == e.errorWeight && errorName.equals(e.errorName);
+  }
+
+
+  @Override
+  public int hashCode() {
+
+    final int PRIME = 59;
+    int result = 1;
+
+    result = result * PRIME + errorCode;
+    result = result * PRIME + errorWeight;
+    result = result * PRIME + errorName.hashCode();
+    return result;
+  }
+
 }
index 1185274..6540319 100644 (file)
@@ -23,4 +23,6 @@ import org.apache.lens.server.api.error.LensException;
 
 public interface SessionValidator {
   void validateSession(LensSessionHandle handle) throws LensException;
+
+  void validateAndAuthorizeSession(LensSessionHandle handle, String userPrincipalName) throws  LensException;
 }
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/ActionType.java b/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/ActionType.java
new file mode 100644 (file)
index 0000000..c8c4a66
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * 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.lens.server.api.authorization;
+
+import lombok.Getter;
+
+public enum ActionType {
+  CREATE,
+  READ,
+  UPDATE,
+  DELETE,
+  SELECT;
+
+  @Getter
+  private String actionName;
+
+  ActionType(){
+    this.actionName = name().toLowerCase();
+  }
+}
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/Authorizer.java b/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/Authorizer.java
new file mode 100644 (file)
index 0000000..502a8a7
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.lens.server.api.authorization;
+
+import java.util.Set;
+
+public interface Authorizer {
+ /**
+ * @param lensPrivilegeObject the privilege object
+ * @param accessType the access type
+ * @param userGroups the user groups
+ * @return if authorized or no
+ */
+  boolean authorize(LensPrivilegeObject lensPrivilegeObject, ActionType accessType, String user,
+    Set<String> userGroups);
+}
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/DefaultAuthorizer.java b/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/DefaultAuthorizer.java
new file mode 100644 (file)
index 0000000..553fa3c
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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.lens.server.api.authorization;
+
+import java.util.Set;
+
+public class DefaultAuthorizer implements Authorizer {
+
+  @Override
+  public boolean authorize(LensPrivilegeObject lensPrivilegeObject, ActionType accessType, String user,
+    Set<String> userGroups) {
+    return true;
+  }
+}
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/LensPrivilegeObject.java b/lens-server-api/src/main/java/org/apache/lens/server/api/authorization/LensPrivilegeObject.java
new file mode 100644 (file)
index 0000000..afeea95
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * 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.lens.server.api.authorization;
+
+import lombok.Data;
+
+@Data
+public class LensPrivilegeObject {
+
+  private final LensPrivilegeObjectType objectType;
+  private final String table;
+  private final String column;
+
+  public LensPrivilegeObject(LensPrivilegeObjectType objectType, String table) {
+    this(objectType, table, null);
+  }
+
+  public LensPrivilegeObject(LensPrivilegeObjectType objectType, String table, String column) {
+    this.objectType = objectType;
+    this.table = table;
+    this.column = column;
+  }
+
+  public enum LensPrivilegeObjectType {
+    DATABASE, COLUMN, NONE
+  };
+
+}
+
+
index 4780955..67038bd 100644 (file)
@@ -622,5 +622,4 @@ public interface CubeMetastoreService extends LensService, SessionValidator {
    */
   List<String> getAllSegmentations(LensSessionHandle sessionid, String cubeName) throws LensException;
 
-
 }
index c6a872d..81b415b 100644 (file)
 package org.apache.lens.server.api.query;
 
 import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -137,8 +134,13 @@ public abstract class AbstractQueryContext implements Serializable {
   @Setter
   private Priority priority;
 
+
   protected AbstractQueryContext(final String query, final String user, final LensConf qconf, final Configuration conf,
     final Collection<LensDriver> drivers, boolean mergeDriverConf) {
+    this(query, user, qconf, conf, drivers, mergeDriverConf, null);
+  }
+  protected AbstractQueryContext(final String query, final String user, final LensConf qconf, final Configuration conf,
+    final Collection<LensDriver> drivers, boolean mergeDriverConf, Set<String> userGroups) {
     if (conf.getBoolean(LensConfConstants.ENABLE_QUERY_METRICS, LensConfConstants.DEFAULT_ENABLE_QUERY_METRICS)) {
       UUID metricId = UUID.randomUUID();
       conf.set(LensConfConstants.QUERY_METRIC_UNIQUE_ID_CONF_KEY, metricId.toString());
index da774fa..a803109 100644 (file)
@@ -204,6 +204,21 @@ public interface QueryExecutionService extends LensService, SessionValidator {
    */
   Response getHttpResultSet(LensSessionHandle sessionHandle, QueryHandle queryHandle) throws LensException;
 
+
+  /**
+   * Get the secure http end point for the result set.
+   *
+   * @param sessionHandle The lens session handle
+   * @param queryHandle   The query handle
+   * @param userPrincipalName the principal name
+   * @return returns javax.ws.rs.core.Response object
+   * @throws LensException the lens exception
+   */
+  Response getAuthorizedHttpResultSet(LensSessionHandle sessionHandle, QueryHandle queryHandle,
+    String userPrincipalName)
+    throws LensException;
+
+
   /**
    * Closes result set by releasing any resources used in serving the resultset.
    *
index 0d85b8c..427e735 100644 (file)
@@ -23,12 +23,16 @@ import static org.apache.lens.api.error.LensCommonErrorCode.NOT_AUTHORIZED;
 import org.apache.lens.server.api.LensErrorInfo;
 import org.apache.lens.server.api.error.LensException;
 
+import lombok.EqualsAndHashCode;
 import lombok.Getter;
+import lombok.ToString;
 
 /**
  * The class PrivilegeException. Thrown when the user is
  * not having the required privileges to complete the action.
  */
+@EqualsAndHashCode(callSuper = true)
+@ToString
 public class PrivilegeException extends LensException {
 
   @Getter
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/user/UserGroupConfigLoader.java b/lens-server-api/src/main/java/org/apache/lens/server/api/user/UserGroupConfigLoader.java
new file mode 100644 (file)
index 0000000..a999e69
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * 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.lens.server.api.user;
+
+import java.util.Map;
+
+public interface UserGroupConfigLoader {
+
+  /**
+   * Gets the user groups config.
+   *
+   * @param loggedInUser the logged in user
+   * @return the user group config
+   * @throws UserGroupLoaderException the user group loader exception
+   */
+  Map<String, String> getUserConfig(String loggedInUser) throws UserGroupLoaderException;
+}
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/user/UserGroupLoaderException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/user/UserGroupLoaderException.java
new file mode 100644 (file)
index 0000000..54c47a8
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * 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.lens.server.api.user;
+
+public class UserGroupLoaderException extends RuntimeException {
+
+  /**
+   * Instantiates a new user group loader exception.
+   */
+  public UserGroupLoaderException() {
+    super();
+  }
+
+  /**
+   * Instantiates a new user group loader exception.
+   *
+   * @param s the s
+   */
+  public UserGroupLoaderException(String s) {
+    super(s);
+  }
+
+  /**
+   * Instantiates a new user group loader exception.
+   *
+   * @param e the e
+   */
+  public UserGroupLoaderException(Throwable e) {
+    super(e);
+  }
+
+  /**
+   * Instantiates a new user grouploader exception.
+   *
+   * @param message the message
+   * @param cause   the cause
+   */
+  public UserGroupLoaderException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}
index ebb3a95..9364872 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.lens.server;
 
 import static org.apache.lens.server.error.LensServerErrorCode.SESSION_CLOSED;
 import static org.apache.lens.server.error.LensServerErrorCode.SESSION_ID_NOT_PROVIDED;
+import static org.apache.lens.server.error.LensServerErrorCode.SESSION_UNAUTHORIZED;
 
 import java.io.*;
 import java.util.ArrayList;
@@ -52,6 +53,7 @@ import org.apache.lens.server.error.LensServerErrorCode;
 import org.apache.lens.server.query.QueryExecutionServiceImpl;
 import org.apache.lens.server.session.LensSessionImpl;
 import org.apache.lens.server.user.UserConfigLoaderFactory;
+import org.apache.lens.server.user.usergroup.UserGroupLoaderFactory;
 import org.apache.lens.server.util.UtilityMethods;
 
 import org.apache.commons.lang3.StringUtils;
@@ -207,6 +209,9 @@ public abstract class BaseLensService extends CompositeService implements Extern
         log.info("Got user config: {}", userConfig);
         UtilityMethods.mergeMaps(sessionConf, userConfig, false);
         sessionConf.put(LensConfConstants.SESSION_LOGGEDIN_USER, username);
+
+        Map<String, String> userGroupConfig = UserGroupLoaderFactory.getUserGroupConfig(username);
+        UtilityMethods.mergeMaps(sessionConf, userGroupConfig, false);
         if (sessionConf.get(LensConfConstants.SESSION_CLUSTER_USER) == null) {
           log.info("Didn't get cluster user from user config loader. Setting same as logged in user: {}", username);
           sessionConf.put(LensConfConstants.SESSION_CLUSTER_USER, username);
@@ -226,11 +231,18 @@ public abstract class BaseLensService extends CompositeService implements Extern
   }
 
   private void updateSessionsPerUser(String userName) {
-    Integer numOfSessions = SESSIONS_PER_USER.get(userName);
-    if (null == numOfSessions) {
-      SESSIONS_PER_USER.put(userName, 1);
-    } else {
-      SESSIONS_PER_USER.put(userName, ++numOfSessions);
+    SessionUser sessionUser = SESSION_USER_INSTANCE_MAP.get(userName);
+    if (sessionUser == null) {
+      log.info("Trying to update invalid session {} for user {}", userName);
+      return;
+    }
+    synchronized (sessionUser) {
+      Integer numOfSessions = SESSIONS_PER_USER.get(userName);
+      if (null == numOfSessions) {
+        SESSIONS_PER_USER.put(userName, 1);
+      } else {
+        SESSIONS_PER_USER.put(userName, ++numOfSessions);
+      }
     }
   }
 
@@ -572,6 +584,16 @@ public abstract class BaseLensService extends CompositeService implements Extern
     }
   }
 
+
+  @Override
+  public void validateAndAuthorizeSession(LensSessionHandle handle, String userPrincipalName) throws LensException {
+    validateSession(handle);
+    LensSessionImpl session = getSession(handle);
+    if (!session.getLoggedInUser().equals(userPrincipalName)) {
+      throw new LensException(SESSION_UNAUTHORIZED.getLensErrorInfo(), handle);
+    }
+  }
+
   public class SessionContext implements AutoCloseable {
     private LensSessionHandle sessionHandle;
 
index 5f4a699..60dc561 100644 (file)
@@ -42,6 +42,7 @@ import org.apache.lens.server.model.MappedDiagnosticLogSegregationContext;
 import org.apache.lens.server.session.LensSessionImpl;
 import org.apache.lens.server.stats.StatisticsService;
 import org.apache.lens.server.user.UserConfigLoaderFactory;
+import org.apache.lens.server.user.usergroup.UserGroupLoaderFactory;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;
@@ -212,6 +213,7 @@ public class LensServices extends CompositeService implements ServiceProvider {
         ServiceMode.valueOf(DEFAULT_SERVER_MODE));
       cliService = new CLIService(null);
       UserConfigLoaderFactory.init(conf);
+      UserGroupLoaderFactory.init(conf);
       // Add default services
       addService(cliService);
       addService(new EventServiceImpl(LensEventService.NAME));
index b9150e9..ef43371 100644 (file)
@@ -29,7 +29,8 @@ public enum LensServerErrorCode {
   SESSION_CLOSED(2005, 0),
   INVALID_HANDLE(2006, 0),
   NULL_OR_EMPTY_ARGUMENT(2007, 0),
-  SERVER_OVERLOADED(2008, 0);
+  SERVER_OVERLOADED(2008, 0),
+  SESSION_UNAUTHORIZED(2009, 0);
 
   public LensErrorInfo getLensErrorInfo() {
     return this.errorInfo;
index 443ad9d..0352151 100644 (file)
@@ -69,8 +69,7 @@ public class LensPersistentResult extends PersistentResultSet {
    * @param conf        the lens server conf
    */
   public LensPersistentResult(QueryHandle queryHandle, LensResultSetMetadata metadata, String outputPath, Integer
-    numRows, Long fileSize,
-    Configuration conf, LensConf qconf) {
+    numRows, Long fileSize, Configuration conf, LensConf qconf) {
     this.metadata = metadata;
     this.outputPath = outputPath;
     this.numRows = numRows;
index 4023a24..07a2107 100644 (file)
@@ -66,6 +66,7 @@ import org.apache.lens.server.api.query.comparators.*;
 import org.apache.lens.server.api.query.constraint.QueryLaunchingConstraint;
 import org.apache.lens.server.api.query.cost.QueryCost;
 import org.apache.lens.server.api.query.events.*;
+import org.apache.lens.server.api.query.save.exception.PrivilegeException;
 import org.apache.lens.server.api.retry.BackOffRetryHandler;
 import org.apache.lens.server.api.retry.ChainedRetryPolicyDecider;
 import org.apache.lens.server.api.retry.OperationRetryHandlerFactory;
@@ -3298,6 +3299,31 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       ? new HealthStatus(isHealthy, "QueryExecution service is healthy.")
       : new HealthStatus(isHealthy, details.toString());
   }
+    /*
+   * (non-Javadoc)
+   *
+   * @see org.apache.lens.server.api.query.QueryExecutionService#getHttpResultSet(org.apache.lens.api.LensSessionHandle,
+   * org.apache.lens.api.query.QueryHandle)
+   */
+
+  @Override
+  public Response getAuthorizedHttpResultSet(LensSessionHandle sessionHandle, QueryHandle queryHandle,
+    String userPrincipalName) throws LensException {
+
+    String loggedInUser;
+    if (sessionHandle != null) {
+      //@TODO this check can be introduced in other api calls as well if required
+      validateAndAuthorizeSession(sessionHandle, userPrincipalName);
+      loggedInUser = getSession(sessionHandle).getLoggedInUser();
+    } else {
+      loggedInUser = userPrincipalName;
+    }
+    final QueryContext ctx = getUpdatedQueryContext(sessionHandle, queryHandle);
+    if (!loggedInUser.equals(ctx.getSubmittedUser())) {
+      throw new PrivilegeException("Query", queryHandle.toString(), "download");
+    }
+    return getResponse(sessionHandle, queryHandle, ctx);
+  }
   /*
    * (non-Javadoc)
    *
@@ -3307,10 +3333,18 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
   @Override
   public Response getHttpResultSet(LensSessionHandle sessionHandle, QueryHandle queryHandle) throws LensException {
+    final QueryContext ctx = getUpdatedQueryContext(sessionHandle, queryHandle);
+    return getResponse(sessionHandle, queryHandle, ctx);
+  }
+
+  private Response getResponse(LensSessionHandle sessionHandle, final QueryHandle queryHandle, final QueryContext ctx)
+    throws LensException {
+
     LensResultSet resultSet = getResultset(queryHandle);
     if (!resultSet.isHttpResultAvailable()) {
       throw new NotFoundException("http result not available");
     }
+
     final Path resultPath = new Path(resultSet.getOutputPath());
     try {
       FileSystem fs = resultPath.getFileSystem(conf);
@@ -3320,7 +3354,6 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     } catch (IOException e) {
       throw new LensException(e);
     }
-    final QueryContext ctx = getUpdatedQueryContext(sessionHandle, queryHandle);
     String resultFSReadUrl = conf.get(RESULT_FS_READ_URL);
     if (resultFSReadUrl != null) {
       try {
index d00087a..47b40a8 100644 (file)
 package org.apache.lens.server.query;
 
 import static org.apache.lens.api.query.SubmitOp.*;
+import static org.apache.lens.server.api.LensConfConstants.ENABLE_RESULT_DOWNLOAD_AUTHORIZATION_CHECK;
 import static org.apache.lens.server.error.LensServerErrorCode.INVALID_HANDLE;
 import static org.apache.lens.server.error.LensServerErrorCode.NULL_OR_EMPTY_OR_BLANK_QUERY;
 
+import java.security.Principal;
 import java.util.List;
+import java.util.Optional;
 
 import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
 
 import org.apache.lens.api.APIResult;
 import org.apache.lens.api.APIResult.Status;
 import org.apache.lens.api.LensConf;
 import org.apache.lens.api.LensSessionHandle;
+import org.apache.lens.api.auth.AuthScheme;
 import org.apache.lens.api.query.*;
 import org.apache.lens.api.result.LensAPIResult;
+import org.apache.lens.server.LensServerConf;
 import org.apache.lens.server.LensServices;
+import org.apache.lens.server.api.LensConfConstants;
 import org.apache.lens.server.api.annotations.MultiPurposeResource;
 import org.apache.lens.server.api.error.LensException;
 import org.apache.lens.server.api.query.QueryExecutionService;
@@ -45,6 +53,7 @@ import org.apache.lens.server.model.LogSegregationContext;
 import org.apache.lens.server.util.UtilityMethods;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
 
 import org.glassfish.jersey.media.multipart.FormDataParam;
 
@@ -65,6 +74,15 @@ public class QueryServiceResource {
 
   private final LogSegregationContext logSegregationContext;
 
+  @Context
+  private SecurityContext securityContext;
+
+
+  public static final Configuration CONF = LensServerConf.getHiveConf();
+  public static final Optional<AuthScheme> AUTH_SCHEME =
+    AuthScheme.getFromString(CONF.get(LensConfConstants.AUTH_SCHEME));
+
+
   private void validateSessionId(final LensSessionHandle sessionHandle) throws LensException {
     queryServer.validateSession(sessionHandle);
   }
@@ -633,7 +651,17 @@ public class QueryServiceResource {
   @Produces({MediaType.APPLICATION_OCTET_STREAM})
   public Response getHttpResultSet(@QueryParam("sessionid") LensSessionHandle sessionid,
     @PathParam("queryHandle") String queryHandle) throws LensException {
+
+    if (AUTH_SCHEME.isPresent()) {
+      Principal userPrincipal = securityContext.getUserPrincipal();
+      String userPrincipalName = userPrincipal.getName();
+      if (CONF.getBoolean(ENABLE_RESULT_DOWNLOAD_AUTHORIZATION_CHECK,
+        LensConfConstants.DEFAULT_ENABLE_RESULT_DOWNLOAD_AUTHORIZATION_CHECK)) {
+        return queryServer.getAuthorizedHttpResultSet(sessionid, getQueryHandle(queryHandle), userPrincipalName);
+      }
+    }
     return queryServer.getHttpResultSet(sessionid, getQueryHandle(queryHandle));
+
   }
 
   /**
diff --git a/lens-server/src/main/java/org/apache/lens/server/user/usergroup/FixedUserGroupConfigLoader.java b/lens-server/src/main/java/org/apache/lens/server/user/usergroup/FixedUserGroupConfigLoader.java
new file mode 100644 (file)
index 0000000..46c21e1
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 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.lens.server.user.usergroup;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.lens.server.api.LensConfConstants;
+import org.apache.lens.server.api.user.UserGroupConfigLoader;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+
+import com.google.common.collect.Maps;
+
+public class FixedUserGroupConfigLoader implements UserGroupConfigLoader {
+
+  private final String fixedValue;
+
+  public FixedUserGroupConfigLoader(HiveConf conf) {
+    fixedValue = conf.get(LensConfConstants.USER_GROUP_FIXED_VALUE);
+  }
+
+  /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.lens.server.user.UserGroupConfigLoader#getUserConfig(java.lang.String)
+     */
+  @Override
+  public Map<String, String> getUserConfig(String loggedInUser) {
+    HashMap<String, String> userConfig = Maps.newHashMap();
+    userConfig.put(LensConfConstants.SESSION_USER_GROUPS, fixedValue);
+    return userConfig;
+  }
+}
+
diff --git a/lens-server/src/main/java/org/apache/lens/server/user/usergroup/UserGroupLoaderFactory.java b/lens-server/src/main/java/org/apache/lens/server/user/usergroup/UserGroupLoaderFactory.java
new file mode 100644 (file)
index 0000000..f4024a4
--- /dev/null
@@ -0,0 +1,136 @@
+/**
+ * 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.lens.server.user.usergroup;
+
+import static org.apache.lens.server.api.LensConfConstants.USER_GROUP_CUSTOM_CLASS;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+import org.apache.lens.server.api.LensConfConstants;
+import org.apache.lens.server.api.user.UserGroupConfigLoader;
+import org.apache.lens.server.api.user.UserGroupLoaderException;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * A factory for creating UserGroupConfigLoader objects.
+ */
+@Slf4j
+public final class UserGroupLoaderFactory {
+  private UserGroupLoaderFactory() {
+
+  }
+
+  /** The conf. */
+  private static HiveConf conf;
+
+  /** The user group config loader. */
+  private static UserGroupConfigLoader userGroupConfigLoader;
+
+  /**
+   * Inits the.
+   *
+   * @param c the c
+   */
+  public static void init(HiveConf c) {
+    conf = c;
+    userGroupConfigLoader = null;
+  }
+
+  /**
+   * The Enum GroupType.
+   */
+
+  public enum GroupType {
+
+    /** The custom. */
+    CUSTOM,
+
+    /** The fixed. */
+    FIXED
+  }
+
+  public static UserGroupConfigLoader getUserGroupConfigLoader() {
+    if (userGroupConfigLoader == null) {
+      userGroupConfigLoader = initializeUserGroupConfigLoader();
+    }
+    return userGroupConfigLoader;
+  }
+
+  /**
+   * Initialize user config loader.
+   *
+   * @return the user config loader
+   */
+  public static UserGroupConfigLoader initializeUserGroupConfigLoader() {
+    String groupType = conf.get(LensConfConstants.USER_GROUP_TYPE);
+    if (groupType == null || groupType.length() == 0) {
+      throw new UserGroupLoaderException("user group type not determined. value was not provided in conf");
+    }
+    for (GroupType type : GroupType.values()) {
+      if (type.name().equals(groupType)) {
+        return createUserGroupConfigLoader(type);
+      }
+    }
+    throw new UserGroupLoaderException("user resolver type not determined. provided value: " + groupType);
+  }
+
+  /**
+   * Gets the query user resolver.
+   *
+   * @param groupType the resolver type
+   * @return the query user resolver
+   */
+  public static UserGroupConfigLoader createUserGroupConfigLoader(GroupType groupType) {
+    switch (groupType) {
+    case CUSTOM:
+      try {
+        return (conf.getClass(USER_GROUP_CUSTOM_CLASS, UserGroupConfigLoader.class, UserGroupConfigLoader.class))
+          .getConstructor(HiveConf.class).newInstance(conf);
+      } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | InstantiationException e) {
+        throw new UserGroupLoaderException(e);
+      }
+    case FIXED:
+    default:
+      return new FixedUserGroupConfigLoader(conf);
+    }
+  }
+
+  /**
+   * Gets the user group grconfig.
+   *
+   * @param loggedInUser the logged in user
+   * @return the user config
+   */
+  public static Map<String, String> getUserGroupConfig(String loggedInUser) {
+    try {
+      Map<String, String> config = getUserGroupConfigLoader().getUserConfig(loggedInUser);
+      if (config == null) {
+        throw new UserGroupLoaderException("Got null User Group config for: " + loggedInUser);
+      }
+      return config;
+    } catch (RuntimeException e) {
+      log.error("Couldn't get user Group config for user: " + loggedInUser, e);
+      throw e;
+    }
+  }
+}
index dd81f62..2ea73a3 100644 (file)
   </property>
 
   <property>
+    <name>lens.server.user.group.type</name>
+    <value>FIXED</value>
+    <description>Type of user group config resolver. allowed values are FIXED, CUSTOM.
+    </description>
+  </property>
+
+  <property>
     <name>lens.server.user.resolver.fixed.value</name>
     <value></value>
     <description>Required for FIXED user resolver.
     </description>
   </property>
 
+
+  <property>
+    <name>lens.server.user.group.fixed.value</name>
+    <value>test</value>
+    <description>Required for FIXED user group resolver.
+      when lens.server.user.group.type=FIXED, This will be the value user groups will resolve to.
+    </description>
+  </property>
+
   <property>
     <name>lens.server.user.resolver.propertybased.filename</name>
     <value>/path/to/propertyfile</value>
diff --git a/lens-server/src/main/resources/ranger-lens-audit.xml b/lens-server/src/main/resources/ranger-lens-audit.xml
new file mode 100644 (file)
index 0000000..31d91d7
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+</configuration>
diff --git a/lens-server/src/main/resources/ranger-lens-security.xml b/lens-server/src/main/resources/ranger-lens-security.xml
new file mode 100644 (file)
index 0000000..7274c44
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <property>
+    <name>ranger.plugin.lens.service.name</name>
+    <value>lensservice</value>
+    <description>
+      Name of the Ranger service containing policies for this YARN instance
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.lens.policy.source.impl</name>
+    <value>org.apache.ranger.admin.client.RangerAdminRESTClient</value>
+    <description>
+      Class to retrieve policies from the source
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.lens.policy.rest.url</name>
+    <value>http://localhost:6080</value>
+    <description>
+      URL to Ranger Admin
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.lens.policy.rest.ssl.config.file</name>
+    <value>/tmp/ranger-policymgr-ssl.xml</value>
+    <description>
+      Path to the file containing SSL details to contact Ranger Admin
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.lens.policy.pollIntervalMs</name>
+    <value>30000</value>
+    <description>
+      How often to poll for changes in policies?
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.lens.policy.cache.dir</name>
+    <value>/tmp/policycache</value>
+    <description>
+      Directory where Ranger policies are cached after successful retrieval from the source
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.lens.policy.rest.client.connection.timeoutMs</name>
+    <value>120000</value>
+    <description>
+      Hdfs Plugin RangerRestClient Connection Timeout in Milli Seconds
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.lens.policy.rest.client.read.timeoutMs</name>
+    <value>30000</value>
+    <description>
+      Hdfs Plugin RangerRestClient read Timeout in Milli Seconds
+    </description>
+  </property>
+
+</configuration>
diff --git a/lens-server/src/main/resources/ranger-policymgr-ssl.xml b/lens-server/src/main/resources/ranger-policymgr-ssl.xml
new file mode 100644 (file)
index 0000000..31d91d7
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+</configuration>
diff --git a/pom.xml b/pom.xml
index 1b1831e..562e06e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -75,6 +75,9 @@
     <spring.shell.version>1.1.0.RELEASE</spring.shell.version>
     <javax.api.version>1.3</javax.api.version>
 
+    <!--Apache Ranger version-->
+    <ranger.version>1.0.0</ranger.version>
+
     <c3p0.version>0.9.5</c3p0.version>
     <hsqldb.version>2.2.9</hsqldb.version>
     <dbcp.version>1.4</dbcp.version>
           </exclusion>
         </exclusions>
       </dependency>
+
+      <dependency>
+        <groupId>com.sun.jersey</groupId>
+          <artifactId>jersey-core</artifactId>
+        <version>1.19.4</version>
+        <exclusions>
+          <exclusion>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
+      <dependency>
+        <groupId>com.sun.jersey</groupId>
+        <artifactId>jersey-bundle</artifactId>
+        <version>1.19.3</version>
+        <exclusions>
+          <exclusion>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
+      <dependency>
+        <groupId>org.apache.ranger</groupId>
+        <artifactId>ranger-plugins-common</artifactId>
+        <version>${ranger.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-audit</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-bundle</artifactId>
+          </exclusion>
+        </exclusions>
+
+      </dependency>
+      <dependency>
+        <groupId>org.apache.ranger</groupId>
+        <artifactId>ranger-plugins-audit</artifactId>
+        <version>${ranger.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-bundle</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>javax.persistence</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>eclipselink</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.ranger</groupId>
+        <artifactId>ranger-plugins-cred</artifactId>
+        <version>${ranger.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-bundle</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-jaxrs</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
       <dependency>
         <groupId>org.apache.hive</groupId>
         <artifactId>hive-exec</artifactId>
         <artifactId>jersey-container-grizzly2-servlet</artifactId>
         <version>${jersey.version}</version>
       </dependency>
+
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-servlet-core</artifactId>
+        <version>${jersey.version}</version>
+      </dependency>
+
       <dependency>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>jersey-media-jaxb</artifactId>
index b3dff28..e900f98 100644 (file)
@@ -263,44 +263,48 @@ Lens server configuration
 *--+--+---+--+
 |117|lens.server.total.query.cost.ceiling.per.user|-1.0|A query submitted by user will be launched only if total query cost of all current launched queries of user is less than or equal to total query cost ceiling defined by this property. This configuration value is only useful when TotalQueryCostCeilingConstraint is enabled by using org.apache.lens.server.query.constraint.TotalQueryCostCeilingConstraintFactory as one of the factories in lens.server.query.constraint.factories property. Default is -1.0 which means that there is no limit on the total query cost of launched queries submitted by a user.|
 *--+--+---+--+
-|118|lens.server.user.resolver.custom.class|full.package.name.Classname|Required for CUSTOM user resolver. In case the provided implementations are not sufficient for user config resolver, a custom classname can be provided. Class should extend org.apache.lens.server.user.UserConfigLoader|
+|118|lens.server.user.group.fixed.value|test|Required for FIXED user group resolver. when lens.server.user.group.type=FIXED, This will be the value user groups will resolve to.|
 *--+--+---+--+
-|119|lens.server.user.resolver.db.keys|lens.session.cluster.user,mapred.job.queue.name|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loaders, the conf keys that will be loaded from database.|
+|119|lens.server.user.group.type|FIXED|Type of user group config resolver. allowed values are FIXED, CUSTOM.|
 *--+--+---+--+
-|120|lens.server.user.resolver.db.query|select clusteruser,queue from user_config_table where username=?|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loader, this query will be run with single argument = logged in user and the result columns will be assigned to lens.server.user.resolver.db.keys in order. For ldap backed database resolver, the argument to this query will be the intermediate values obtained from ldap.|
+|120|lens.server.user.resolver.custom.class|full.package.name.Classname|Required for CUSTOM user resolver. In case the provided implementations are not sufficient for user config resolver, a custom classname can be provided. Class should extend org.apache.lens.server.user.UserConfigLoader|
 *--+--+---+--+
-|121|lens.server.user.resolver.fixed.value| |Required for FIXED user resolver. when lens.server.user.resolver.type=FIXED, This will be the value cluster user will resolve to.|
+|121|lens.server.user.resolver.db.keys|lens.session.cluster.user,mapred.job.queue.name|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loaders, the conf keys that will be loaded from database.|
 *--+--+---+--+
-|122|lens.server.user.resolver.ldap.bind.dn| |Required for LDAP_BACKED_DATABASE user resolvers. ldap dn for admin binding example: CN=company-it-admin,ou=service-account,ou=company-service-account,dc=dc1,dc=com...|
+|122|lens.server.user.resolver.db.query|select clusteruser,queue from user_config_table where username=?|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loader, this query will be run with single argument = logged in user and the result columns will be assigned to lens.server.user.resolver.db.keys in order. For ldap backed database resolver, the argument to this query will be the intermediate values obtained from ldap.|
 *--+--+---+--+
-|123|lens.server.user.resolver.ldap.bind.password| |Required for LDAP_BACKED_DATABASE user resolvers. ldap password for admin binding above|
+|123|lens.server.user.resolver.fixed.value| |Required for FIXED user resolver. when lens.server.user.resolver.type=FIXED, This will be the value cluster user will resolve to.|
 *--+--+---+--+
-|124|lens.server.user.resolver.ldap.fields|department|Required for LDAP_BACKED_DATABASE user resolvers. list of fields to be obtained from ldap. These will be cached by the intermediate db.|
+|124|lens.server.user.resolver.ldap.bind.dn| |Required for LDAP_BACKED_DATABASE user resolvers. ldap dn for admin binding example: CN=company-it-admin,ou=service-account,ou=company-service-account,dc=dc1,dc=com...|
 *--+--+---+--+
-|125|lens.server.user.resolver.ldap.intermediate.db.delete.sql|delete from user_department where username=?|Required for LDAP_BACKED_DATABASE user resolvers. query to delete intermediate values from database backing ldap as cache. one argument: logged in user.|
+|125|lens.server.user.resolver.ldap.bind.password| |Required for LDAP_BACKED_DATABASE user resolvers. ldap password for admin binding above|
 *--+--+---+--+
-|126|lens.server.user.resolver.ldap.intermediate.db.insert.sql|insert into user_department (username, department, expiry) values (?, ?, ?)|Required for LDAP_BACKED_DATABASE user resolvers. query to insert intermediate values from database backing ldap as cache. arguments: first logged in user, then all intermediate values, then current time + expiration time|
+|126|lens.server.user.resolver.ldap.fields|department|Required for LDAP_BACKED_DATABASE user resolvers. list of fields to be obtained from ldap. These will be cached by the intermediate db.|
 *--+--+---+--+
-|127|lens.server.user.resolver.ldap.intermediate.db.query|select department from user_department where username=? and expiry>?|Required for LDAP_BACKED_DATABASE user resolvers. query to obtain intermediate values from database backing ldap as cache. two arguments: logged in user and current time.|
+|127|lens.server.user.resolver.ldap.intermediate.db.delete.sql|delete from user_department where username=?|Required for LDAP_BACKED_DATABASE user resolvers. query to delete intermediate values from database backing ldap as cache. one argument: logged in user.|
 *--+--+---+--+
-|128|lens.server.user.resolver.ldap.search.base| |Required for LDAP_BACKED_DATABASE user resolvers. for searching intermediate values for a user, the search keys. example: cn=users,dc=dc1,dc=dc2...|
+|128|lens.server.user.resolver.ldap.intermediate.db.insert.sql|insert into user_department (username, department, expiry) values (?, ?, ?)|Required for LDAP_BACKED_DATABASE user resolvers. query to insert intermediate values from database backing ldap as cache. arguments: first logged in user, then all intermediate values, then current time + expiration time|
 *--+--+---+--+
-|129|lens.server.user.resolver.ldap.search.filter|(&(objectClass=user)(sAMAccountName=%s))|Required for LDAP_BACKED_DATABASE user resolvers. filter pattern for ldap search|
+|129|lens.server.user.resolver.ldap.intermediate.db.query|select department from user_department where username=? and expiry>?|Required for LDAP_BACKED_DATABASE user resolvers. query to obtain intermediate values from database backing ldap as cache. two arguments: logged in user and current time.|
 *--+--+---+--+
-|130|lens.server.user.resolver.ldap.url| |Required for LDAP_BACKED_DATABASE user resolvers. ldap url to connect to.|
+|130|lens.server.user.resolver.ldap.search.base| |Required for LDAP_BACKED_DATABASE user resolvers. for searching intermediate values for a user, the search keys. example: cn=users,dc=dc1,dc=dc2...|
 *--+--+---+--+
-|131|lens.server.user.resolver.propertybased.filename|/path/to/propertyfile|Required for PROPERTYBASED user resolver. when lens.server.user.resolver.type is PROPERTYBASED, then this file will be read and parsed to determine cluster user. Each line should contain username followed by DOT followed by property full name followed by equal-to sign and followed by value. example schema of the file is: user1.lens.server.cluster.user=clusteruser1 user1.mapred.job.queue.name=queue1 *.lens.server.cluster.user=defaultclusteruser *.mapred.job.queue.name=default|
+|131|lens.server.user.resolver.ldap.search.filter|(&(objectClass=user)(sAMAccountName=%s))|Required for LDAP_BACKED_DATABASE user resolvers. filter pattern for ldap search|
 *--+--+---+--+
-|132|lens.server.user.resolver.type|FIXED|Type of user config resolver. allowed values are FIXED, PROPERTYBASED, DATABASE, LDAP_BACKED_DATABASE, CUSTOM.|
+|132|lens.server.user.resolver.ldap.url| |Required for LDAP_BACKED_DATABASE user resolvers. ldap url to connect to.|
 *--+--+---+--+
-|133|lens.server.waiting.queries.selection.policy.factories|org.apache.lens.server.query.collect.UserSpecificWaitingQueriesSelectionPolicyFactory|Factories used to instantiate waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
+|133|lens.server.user.resolver.propertybased.filename|/path/to/propertyfile|Required for PROPERTYBASED user resolver. when lens.server.user.resolver.type is PROPERTYBASED, then this file will be read and parsed to determine cluster user. Each line should contain username followed by DOT followed by property full name followed by equal-to sign and followed by value. example schema of the file is: user1.lens.server.cluster.user=clusteruser1 user1.mapred.job.queue.name=queue1 *.lens.server.cluster.user=defaultclusteruser *.mapred.job.queue.name=default|
 *--+--+---+--+
-|134|lens.server.ws.featurenames|multipart,moxyjson,moxyjsonconfigresovler|These JAX-RS Feature(s) would be started in the specified order when lens-server starts up|
+|134|lens.server.user.resolver.type|FIXED|Type of user config resolver. allowed values are FIXED, PROPERTYBASED, DATABASE, LDAP_BACKED_DATABASE, CUSTOM.|
 *--+--+---+--+
-|135|lens.server.ws.filternames|requestlogger,consistentState,serverMode|These JAX-RS filters would be started in the specified order when lens-server starts up|
+|135|lens.server.waiting.queries.selection.policy.factories|org.apache.lens.server.query.collect.UserSpecificWaitingQueriesSelectionPolicyFactory|Factories used to instantiate waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
 *--+--+---+--+
-|136|lens.server.ws.listenernames|appevent|These listeners would be called in the specified order when lens-server starts up|
+|136|lens.server.ws.featurenames|multipart,moxyjson,moxyjsonconfigresovler|These JAX-RS Feature(s) would be started in the specified order when lens-server starts up|
 *--+--+---+--+
-|137|lens.server.ws.resourcenames|session,metastore,query,savedquery,quota,scheduler,index,log|These JAX-RS resources would be started in the specified order when lens-server starts up|
+|137|lens.server.ws.filternames|requestlogger,consistentState,serverMode|These JAX-RS filters would be started in the specified order when lens-server starts up|
+*--+--+---+--+
+|138|lens.server.ws.listenernames|appevent|These listeners would be called in the specified order when lens-server starts up|
+*--+--+---+--+
+|139|lens.server.ws.resourcenames|session,metastore,query,savedquery,quota,scheduler,index,log|These JAX-RS resources would be started in the specified order when lens-server starts up|
 *--+--+---+--+
 The configuration parameters and their default values
index 5d99892..1532a27 100644 (file)
@@ -42,21 +42,25 @@ Hive driver configuration
 *--+--+---+--+
 |9|lens.cube.query.replace.timedim|true|Tells whether timedim attribute queried in the time range should be replaced with its corresponding partition column name.|
 *--+--+---+--+
-|10|lens.driver.cost.query.decider.class|org.apache.lens.server.api.query.cost.RangeBasedQueryCostTypeDecider|Decider class which looks at ranges passed in config and decides the querycosttype|
+|10|lens.cube.query.user.groups.authorization.enable|false|true if authorization is based on User Groups, false otherwise|
 *--+--+---+--+
-|11|lens.driver.cost.type.ranges|LOW,0.0,HIGH|Cost based Query type mapping|
+|11|lens.cube.query.user.name.authorization.enable|false|true if authorization is based on User Name, false otherwise|
 *--+--+---+--+
-|12|lens.driver.hive.calculate.priority|true|Whether priority should be calculated for hive mr jobs or not|
+|12|lens.driver.cost.query.decider.class|org.apache.lens.server.api.query.cost.RangeBasedQueryCostTypeDecider|Decider class which looks at ranges passed in config and decides the querycosttype|
 *--+--+---+--+
-|13|lens.driver.hive.connection.class|org.apache.lens.driver.hive.EmbeddedThriftConnection|The connection class from HiveDriver to HiveServer. The default is an embedded connection which does not require a remote hive server. For connecting to a hiveserver end point, remote connection should be used. The possible values are org.apache.lens.driver.hive.EmbeddedThriftConnection and org.apache.lens.driver.hive.RemoteThriftConnection.|
+|13|lens.driver.cost.type.ranges|LOW,0.0,HIGH|Cost based Query type mapping|
 *--+--+---+--+
-|14|lens.driver.hive.cost.calculator.class|org.apache.lens.cube.query.cost.FactPartitionBasedQueryCostCalculator|Cost calculator class. By default calculating cost through fact partitions.|
+|14|lens.driver.hive.calculate.priority|true|Whether priority should be calculated for hive mr jobs or not|
 *--+--+---+--+
-|15|lens.driver.hive.hs2.connection.expiry.delay|600000|The idle time (in milliseconds) for expiring connection from hivedriver to HiveServer2|
+|15|lens.driver.hive.connection.class|org.apache.lens.driver.hive.EmbeddedThriftConnection|The connection class from HiveDriver to HiveServer. The default is an embedded connection which does not require a remote hive server. For connecting to a hiveserver end point, remote connection should be used. The possible values are org.apache.lens.driver.hive.EmbeddedThriftConnection and org.apache.lens.driver.hive.RemoteThriftConnection.|
 *--+--+---+--+
-|16|lens.driver.hive.kerberos.principal|hive/_HOST@APACHE.COM|Set principal name to be used for hive server.|
+|16|lens.driver.hive.cost.calculator.class|org.apache.lens.cube.query.cost.FactPartitionBasedQueryCostCalculator|Cost calculator class. By default calculating cost through fact partitions.|
 *--+--+---+--+
-|17|lens.driver.hive.priority.ranges|VERY_HIGH,7.0,HIGH,30.0,NORMAL,90,LOW|Priority Ranges. The numbers are the costs of the query.                                                                                                                                                    \ |
+|17|lens.driver.hive.hs2.connection.expiry.delay|600000|The idle time (in milliseconds) for expiring connection from hivedriver to HiveServer2|
+*--+--+---+--+
+|18|lens.driver.hive.kerberos.principal|hive/_HOST@APACHE.COM|Set principal name to be used for hive server.|
+*--+--+---+--+
+|19|lens.driver.hive.priority.ranges|VERY_HIGH,7.0,HIGH,30.0,NORMAL,90,LOW|Priority Ranges. The numbers are the costs of the query.                                                                                                                                                    \ |
 |  |                                |                                     |The cost is calculated based on partition weights and fact weights. The interpretation of the default config is:                                                                                            \ |
 |  |                                |                                     |                                                                                                                                                                                                            \ |
 |  |                                |                                     |cost \<= 7\ \ \ \ \ \ \ \ \ \ \ :\ \ \ \ \ Priority = VERY_HIGH                                                                                                                                             \ |
@@ -72,14 +76,14 @@ Hive driver configuration
 |  |                                |                                     |One use case in range tuning can be that you never want queries to run with VERY_HIGH, assuming no other changes, you'll modify the value of this param in hivedriver-site.xml to be HIGH,30.0,NORMAL,90,LOW\ |
 |  |                                |                                     |via the configs, you can tune both the ranges and partition weights. this would give the end user more control.                                                                                               |
 *--+--+---+--+
-|18|lens.driver.hive.query.hook.classes| |The query hook classes for hive driver. By default there are no hooks. To add a hook, you should look at the default implementation and from there it'll be easy to derive what value can be added through a new hook. Multiple hooks can be provided by providing comma seperated name of classes.|
+|20|lens.driver.hive.query.hook.classes| |The query hook classes for hive driver. By default there are no hooks. To add a hook, you should look at the default implementation and from there it'll be easy to derive what value can be added through a new hook. Multiple hooks can be provided by providing comma seperated name of classes.|
 *--+--+---+--+
-|19|lens.driver.hive.query.launching.constraint.factories| |Factories used to instantiate constraints enforced on queries by driver. A query will be launched only if all constraints pass. Every Factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.constraint.QueryLaunchingConstraint.|
+|21|lens.driver.hive.query.launching.constraint.factories| |Factories used to instantiate constraints enforced on queries by driver. A query will be launched only if all constraints pass. Every Factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.constraint.QueryLaunchingConstraint.|
 *--+--+---+--+
-|20|lens.driver.hive.waiting.queries.selection.policy.factories| |Factories used to instantiate driver specific waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
+|22|lens.driver.hive.waiting.queries.selection.policy.factories| |Factories used to instantiate driver specific waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
 *--+--+---+--+
-|21|query.retry.policy.classes|org.apache.lens.server.api.retry.SubstringMessagePolicyDecider|List of policy decider classes|
+|23|query.retry.policy.classes|org.apache.lens.server.api.retry.SubstringMessagePolicyDecider|List of policy decider classes|
 *--+--+---+--+
-|22|retry.messages.contains.map|Session handle not found=org.apache.lens.server.api.retry.ImmediateRetryHandler(2)|Comma separated error messages and retry policy|
+|24|retry.messages.contains.map|Session handle not found=org.apache.lens.server.api.retry.ImmediateRetryHandler(2)|Comma separated error messages and retry policy|
 *--+--+---+--+
 The configuration parameters and their default values
index 792278e..2455ac6 100644 (file)
@@ -34,75 +34,79 @@ Jdbc driver configuration
 *--+--+---+--+
 |5|lens.cube.query.time.range.writer.class|org.apache.lens.cube.parse.BetweenTimeRangeWriter|The timerange writer class which specifies how the resolved partitions in timeranges should be written in final query. Available writers are org.apache.lens.cube.parse.ORTimeRangeWriter and org.apache.lens.cube.parse.BetweenTimeRangeWriter|
 *--+--+---+--+
-|6|lens.driver.cost.query.decider.class|org.apache.lens.server.api.query.cost.RangeBasedQueryCostTypeDecider|Decider class which looks at ranges passed in config and decides the querycosttype|
+|6|lens.cube.query.user.groups.authorization.enable|false|true if authorization is based on User Groups, false otherwise|
 *--+--+---+--+
-|7|lens.driver.cost.type.ranges|LOW,0.0,HIGH|Cost based Query type mapping|
+|7|lens.cube.query.user.name.authorization.enable|false|true if authorization is based on User Name, false otherwise|
 *--+--+---+--+
-|8|lens.driver.jdbc.connection.properties| |Connection properties for jdbc connection.|
+|8|lens.driver.cost.query.decider.class|org.apache.lens.server.api.query.cost.RangeBasedQueryCostTypeDecider|Decider class which looks at ranges passed in config and decides the querycosttype|
 *--+--+---+--+
-|9|lens.driver.jdbc.connection.provider| |A contract for obtaining JDBC connections|
+|9|lens.driver.cost.type.ranges|LOW,0.0,HIGH|Cost based Query type mapping|
 *--+--+---+--+
-|10|lens.driver.jdbc.cost.calculator.class|org.apache.lens.cube.query.cost.StaticCostCalculator|Cost calculator class. By default calculating cost through static values|
+|10|lens.driver.jdbc.connection.properties| |Connection properties for jdbc connection.|
 *--+--+---+--+
-|11|lens.driver.jdbc.db.password| |The database user's password|
+|11|lens.driver.jdbc.connection.provider| |A contract for obtaining JDBC connections|
 *--+--+---+--+
-|12|lens.driver.jdbc.db.uri| |JDBC connection URL in the format jdbc:dbms://host:port/dbname|
+|12|lens.driver.jdbc.cost.calculator.class|org.apache.lens.cube.query.cost.StaticCostCalculator|Cost calculator class. By default calculating cost through static values|
 *--+--+---+--+
-|13|lens.driver.jdbc.db.user| |The database user on whose behalf the connection is being made|
+|13|lens.driver.jdbc.db.password| |The database user's password|
 *--+--+---+--+
-|14|lens.driver.jdbc.driver.class|com.mysql.jdbc.Driver|Type of JDBC driver used to connect backend database|
+|14|lens.driver.jdbc.db.uri| |JDBC connection URL in the format jdbc:dbms://host:port/dbname|
 *--+--+---+--+
-|15|lens.driver.jdbc.enable.resultset.streaming.retrieval|false|Flag to enable row by row retrieval of result set from the database server. This is used to enable streaming result sets for MySQL. This is set to false by default.|
+|15|lens.driver.jdbc.db.user| |The database user on whose behalf the connection is being made|
 *--+--+---+--+
-|16|lens.driver.jdbc.estimate.connection.properties| |Connection properties for jdbc estimate connection.|
+|16|lens.driver.jdbc.driver.class|com.mysql.jdbc.Driver|Type of JDBC driver used to connect backend database|
 *--+--+---+--+
-|17|lens.driver.jdbc.estimate.db.password| |The database user's password, for estimate queries. If this property is unspecified, value for lens.driver.jdbc.db.password would be used. Override this property to tune estimate connection pool|
+|17|lens.driver.jdbc.enable.resultset.streaming.retrieval|false|Flag to enable row by row retrieval of result set from the database server. This is used to enable streaming result sets for MySQL. This is set to false by default.|
 *--+--+---+--+
-|18|lens.driver.jdbc.estimate.db.uri| |JDBC connection URL in the format jdbc:dbms://host:port/dbname for estimate queries. If this property is unspecified, value for lens.driver.jdbc.db.uri will be used.|
+|18|lens.driver.jdbc.estimate.connection.properties| |Connection properties for jdbc estimate connection.|
 *--+--+---+--+
-|19|lens.driver.jdbc.estimate.db.user| |The database user on whose behalf the connection is being made, for estimate queries. If this property is unspecified, value for lens.driver.jdbc.db.user would be used. Override this property to tune estimate connection pool|
+|19|lens.driver.jdbc.estimate.db.password| |The database user's password, for estimate queries. If this property is unspecified, value for lens.driver.jdbc.db.password would be used. Override this property to tune estimate connection pool|
 *--+--+---+--+
-|20|lens.driver.jdbc.estimate.driver.class| |Type of JDBC driver used to connect backend database for estimate queries. If This property is not specified, value for lens.driver.jdbc.driver.class will be used. Override this property to tune estimate connection pool|
+|20|lens.driver.jdbc.estimate.db.uri| |JDBC connection URL in the format jdbc:dbms://host:port/dbname for estimate queries. If this property is unspecified, value for lens.driver.jdbc.db.uri will be used.|
 *--+--+---+--+
-|21|lens.driver.jdbc.estimate.get.connection.timeout| |Response timeout in milliseconds of any JDBC call invoking data transmission over a connection socket , for estimate queries. If this property is not specified, value for lens.driver.jdbc.get.connection.timeout would be used. Override this property to tune estimate connection pool.|
+|21|lens.driver.jdbc.estimate.db.user| |The database user on whose behalf the connection is being made, for estimate queries. If this property is unspecified, value for lens.driver.jdbc.db.user would be used. Override this property to tune estimate connection pool|
 *--+--+---+--+
-|22|lens.driver.jdbc.estimate.pool.idle.time| |Maximum idle time in sec before a connection is closed, for estimate queries. If this property is not specified, value for lens.driver.jdbc.pool.idle.time would be used. Override this property to tune estimate connection pool.|
+|22|lens.driver.jdbc.estimate.driver.class| |Type of JDBC driver used to connect backend database for estimate queries. If This property is not specified, value for lens.driver.jdbc.driver.class will be used. Override this property to tune estimate connection pool|
 *--+--+---+--+
-|23|lens.driver.jdbc.estimate.pool.max.size| |Maximum number of concurrent connections allowed in pool, for estimate queries. If this property is unspecified, value for lens.driver.jdbc.pool.max.size would be used. Override this property to tune estimate connection pool|
+|23|lens.driver.jdbc.estimate.get.connection.timeout| |Response timeout in milliseconds of any JDBC call invoking data transmission over a connection socket , for estimate queries. If this property is not specified, value for lens.driver.jdbc.get.connection.timeout would be used. Override this property to tune estimate connection pool.|
 *--+--+---+--+
-|24|lens.driver.jdbc.estimate.pool.max.statements| |Maximum number of prepared statements to cache per connection, for estimate queries. If this property is not specified, value for lens.driver.jdbc.pool.max.statements would be used.|
+|24|lens.driver.jdbc.estimate.pool.idle.time| |Maximum idle time in sec before a connection is closed, for estimate queries. If this property is not specified, value for lens.driver.jdbc.pool.idle.time would be used. Override this property to tune estimate connection pool.|
 *--+--+---+--+
-|25|lens.driver.jdbc.explain.keyword|Explain|Explain keyword used to get the query plan of underlying database|
+|25|lens.driver.jdbc.estimate.pool.max.size| |Maximum number of concurrent connections allowed in pool, for estimate queries. If this property is unspecified, value for lens.driver.jdbc.pool.max.size would be used. Override this property to tune estimate connection pool|
 *--+--+---+--+
-|26|lens.driver.jdbc.fetch.size|1000|Fetch size for JDBC result set|
+|26|lens.driver.jdbc.estimate.pool.max.statements| |Maximum number of prepared statements to cache per connection, for estimate queries. If this property is not specified, value for lens.driver.jdbc.pool.max.statements would be used.|
 *--+--+---+--+
-|27|lens.driver.jdbc.get.connection.timeout|10000|The number of milliseconds a client calling getConnection() will wait for a Connection to be checked-in or acquired when the pool is exhausted. Zero means wait indefinitely. Setting any positive value will cause the getConnection () call to time-out and break with an SQLException after the specified number of milliseconds. The default value of this property is 10 secs.|
+|27|lens.driver.jdbc.explain.keyword|Explain|Explain keyword used to get the query plan of underlying database|
 *--+--+---+--+
-|28|lens.driver.jdbc.pool.idle.time|600|Maximum idle time in sec before a connection is closed|
+|28|lens.driver.jdbc.fetch.size|1000|Fetch size for JDBC result set|
 *--+--+---+--+
-|29|lens.driver.jdbc.pool.max.size|15|Maximum number of concurrent connections allowed in pool|
+|29|lens.driver.jdbc.get.connection.timeout|10000|The number of milliseconds a client calling getConnection() will wait for a Connection to be checked-in or acquired when the pool is exhausted. Zero means wait indefinitely. Setting any positive value will cause the getConnection () call to time-out and break with an SQLException after the specified number of milliseconds. The default value of this property is 10 secs.|
 *--+--+---+--+
-|30|lens.driver.jdbc.pool.max.statements|20|Maximum number of prepared statements to cache per connection|
+|30|lens.driver.jdbc.pool.idle.time|600|Maximum idle time in sec before a connection is closed|
 *--+--+---+--+
-|31|lens.driver.jdbc.query.launching.constraint.factories|org.apache.lens.server.api.query.constraint.MaxConcurrentDriverQueriesConstraintFactory,
+|31|lens.driver.jdbc.pool.max.size|15|Maximum number of concurrent connections allowed in pool|
+*--+--+---+--+
+|32|lens.driver.jdbc.pool.max.statements|20|Maximum number of prepared statements to cache per connection|
+*--+--+---+--+
+|33|lens.driver.jdbc.query.launching.constraint.factories|org.apache.lens.server.api.query.constraint.MaxConcurrentDriverQueriesConstraintFactory,
       org.apache.lens.driver.jdbc.MaxJDBCConnectionCheckConstraintFactory|Factories used to instantiate constraints enforced on queries by driver. A query will be launched only if all constraints pass. Every Factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.constraint.QueryLaunchingConstraint.|
 *--+--+---+--+
-|32|lens.driver.jdbc.query.rewriter|org.apache.lens.driver.jdbc.ColumnarSQLRewriter|Rewriting the HQL to optimized sql queries|
+|34|lens.driver.jdbc.query.rewriter|org.apache.lens.driver.jdbc.ColumnarSQLRewriter|Rewriting the HQL to optimized sql queries|
 *--+--+---+--+
-|33|lens.driver.jdbc.regex.replacement.values|to_date=date, format_number=format, date_sub\((.*?)\,\s*([0-9]+\s*)\)=date_sub($1\, interval $2 day), date_add\((.*?)\,\s*([0-9]+\s*)\)=date_add($1\, interval $2 day)|Rewriting the HQL to optimized sql queries|
+|35|lens.driver.jdbc.regex.replacement.values|to_date=date, format_number=format, date_sub\((.*?)\,\s*([0-9]+\s*)\)=date_sub($1\, interval $2 day), date_add\((.*?)\,\s*([0-9]+\s*)\)=date_add($1\, interval $2 day)|Rewriting the HQL to optimized sql queries|
 *--+--+---+--+
-|34|lens.driver.jdbc.statement.cancel.supported|true|Flag to indicate Whether cancel on JDBC statement is supported. If not supported, framework wont call cancel on JDBC statement.|
+|36|lens.driver.jdbc.statement.cancel.supported|true|Flag to indicate Whether cancel on JDBC statement is supported. If not supported, framework wont call cancel on JDBC statement.|
 *--+--+---+--+
-|35|lens.driver.jdbc.validate.through.prepare|true|Flag to enable query syntactic and semantic validation using prepared statement.|
+|37|lens.driver.jdbc.validate.through.prepare|true|Flag to enable query syntactic and semantic validation using prepared statement.|
 *--+--+---+--+
-|36|lens.driver.jdbc.waiting.queries.selection.policy.factories|org.apache.lens.server.api.query.collect.DriverSpecificWaitingQueriesSelectionPolicyFactory|Factories used to instantiate driver specific waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
+|38|lens.driver.jdbc.waiting.queries.selection.policy.factories|org.apache.lens.server.api.query.collect.DriverSpecificWaitingQueriesSelectionPolicyFactory|Factories used to instantiate driver specific waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
 *--+--+---+--+
-|37|lens.driver.query.cost|0.0|Jdbc driver static cost value|
+|39|lens.driver.query.cost|0.0|Jdbc driver static cost value|
 *--+--+---+--+
-|38|lens.query.timeout.millis|3600000|The runtime(millis) of the query after which query will be timedout and cancelled. Default is 1 hour for jdbc queries.|
+|40|lens.query.timeout.millis|3600000|The runtime(millis) of the query after which query will be timedout and cancelled. Default is 1 hour for jdbc queries.|
 *--+--+---+--+
-|39|query.retry.policy.classes|org.apache.lens.server.api.retry.SubstringMessagePolicyDecider|List of classes to decide policies|
+|41|query.retry.policy.classes|org.apache.lens.server.api.retry.SubstringMessagePolicyDecider|List of classes to decide policies|
 *--+--+---+--+
-|40|retry.messages.contains.map|Query not found=org.apache.lens.server.api.retry.ImmediateRetryHandler(2)|Comma separated error messages and retry policy|
+|42|retry.messages.contains.map|Query not found=org.apache.lens.server.api.retry.ImmediateRetryHandler(2)|Comma separated error messages and retry policy|
 *--+--+---+--+
 The configuration parameters and their default values