You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by am...@apache.org on 2016/03/02 13:49:13 UTC
[2/2] lens git commit: LENS-833 : Limit number of open sessions per
user on session service
LENS-833 : Limit number of open sessions per user on session service
Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/0ba17ef5
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/0ba17ef5
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/0ba17ef5
Branch: refs/heads/master
Commit: 0ba17ef5c78bccf6699d696529b303879e27535b
Parents: 935647c
Author: Raju Bairishetti <ra...@apache.org>
Authored: Wed Mar 2 18:18:45 2016 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Wed Mar 2 18:18:45 2016 +0530
----------------------------------------------------------------------
.../lens/api/error/ErrorCollectionFactory.java | 8 +-
.../org/apache/lens/api/error/LensError.java | 8 +-
.../apache/lens/api/error/LensHttpStatus.java | 64 ++++++++
.../apache/lens/api/result/LensAPIResult.java | 13 +-
lens-api/src/main/resources/lens-errors.conf | 6 +
.../lens/cli/TestLensConnectionCliCommands.java | 12 +-
.../apache/lens/cli/TestLensCubeCommands.java | 60 ++++----
.../lens/cli/TestLensDatabaseCommands.java | 18 ++-
.../lens/cli/TestLensDimensionCommands.java | 8 +
.../cli/TestLensDimensionTableCommands.java | 10 ++
.../apache/lens/cli/TestLensFactCommands.java | 11 ++
.../TestLensFactCommandsWithMissingWeight.java | 11 ++
.../lens/cli/TestLensLogResourceCommands.java | 7 +
.../lens/cli/TestLensNativeTableCommands.java | 4 +-
.../lens/cli/TestLensStorageCommands.java | 8 +
.../lens/server/api/LensConfConstants.java | 4 +
.../lens/server/api/error/LensException.java | 1 +
.../org/apache/lens/server/BaseLensService.java | 149 ++++++++++++++-----
.../lens/server/error/LensServerErrorCode.java | 3 +-
.../lens/server/session/SessionResource.java | 12 +-
.../src/main/resources/lensserver-default.xml | 9 +-
.../org/apache/lens/server/TestServerMode.java | 3 +
.../auth/FooBarAuthenticationProvider.java | 3 +-
.../common/ErrorResponseExpectedData.java | 4 +-
.../server/metastore/TestMetastoreService.java | 1 +
.../server/query/QueryAPIErrorResponseTest.java | 7 +-
.../apache/lens/server/query/TestLensDAO.java | 1 +
.../server/session/TestSessionResource.java | 85 ++++++++++-
.../lens/server/ui/TestSessionUIResource.java | 11 +-
lens-server/src/test/resources/lens-site.xml | 5 +
src/site/apt/admin/config.apt | 148 +++++++++---------
31 files changed, 513 insertions(+), 181 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-api/src/main/java/org/apache/lens/api/error/ErrorCollectionFactory.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/error/ErrorCollectionFactory.java b/lens-api/src/main/java/org/apache/lens/api/error/ErrorCollectionFactory.java
index 741630b..28ea6c0 100644
--- a/lens-api/src/main/java/org/apache/lens/api/error/ErrorCollectionFactory.java
+++ b/lens-api/src/main/java/org/apache/lens/api/error/ErrorCollectionFactory.java
@@ -18,12 +18,12 @@
*/
package org.apache.lens.api.error;
-import static javax.ws.rs.core.Response.Status;
-
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.ws.rs.core.Response;
+
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.typesafe.config.Config;
@@ -61,7 +61,9 @@ public class ErrorCollectionFactory {
int errorCode = config.getInt(ERROR_CODE_KEY);
int httpStatusCodeInt = config.getInt(HTTP_STATUS_CODE_KEY);
- Status httpStatusCode = Status.fromStatusCode(httpStatusCodeInt);
+
+
+ Response.StatusType httpStatusCode = LensHttpStatus.fromStatusCode(httpStatusCodeInt);
String errorMsg = config.getString(ERROR_MSG_KEY);
Class payloadClass = null;
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-api/src/main/java/org/apache/lens/api/error/LensError.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/error/LensError.java b/lens-api/src/main/java/org/apache/lens/api/error/LensError.java
index 1cb7409..f49f104 100644
--- a/lens-api/src/main/java/org/apache/lens/api/error/LensError.java
+++ b/lens-api/src/main/java/org/apache/lens/api/error/LensError.java
@@ -19,10 +19,10 @@
package org.apache.lens.api.error;
-import static javax.ws.rs.core.Response.Status;
-
import static com.google.common.base.Preconditions.checkArgument;
+import javax.ws.rs.core.Response;
+
import org.apache.commons.lang.StringUtils;
import com.google.common.base.Optional;
@@ -41,11 +41,11 @@ import lombok.NonNull;
public final class LensError {
private final int errorCode;
- private final Status httpStatusCode;
+ private final Response.StatusType httpStatusCode;
private final String errorMsg;
private final Optional<Class> payloadClass;
- public LensError(final int errorCode, final Status httpStatusCode, final String errorMsg,
+ public LensError(final int errorCode, final Response.StatusType httpStatusCode, final String errorMsg,
@NonNull final Optional<Class> payloadClass) {
checkArgument(errorCode > 0);
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-api/src/main/java/org/apache/lens/api/error/LensHttpStatus.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/error/LensHttpStatus.java b/lens-api/src/main/java/org/apache/lens/api/error/LensHttpStatus.java
new file mode 100644
index 0000000..6da8e22
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/error/LensHttpStatus.java
@@ -0,0 +1,64 @@
+/**
+ * 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.api.error;
+
+import javax.ws.rs.core.Response;
+
+import lombok.Getter;
+
+public enum LensHttpStatus implements Response.StatusType {
+ TOO_MANY_REQUESTS(429, "Too many requests");
+
+ @Getter private final int statusCode;
+ @Getter private final String reasonPhrase;
+ @Getter private final Response.Status.Family family;
+
+ private LensHttpStatus(int statusCode, String reasonPhrase) {
+ this.statusCode = statusCode;
+ this.reasonPhrase = reasonPhrase;
+ this.family = LensHttpStatus.familyOf(statusCode);
+ }
+
+ public String toString() {
+ return this.reasonPhrase;
+ }
+
+ public static Response.StatusType fromStatusCode(int statusCode) {
+ // Delegate all status code calls to Response.Status.
+ // Compute status code from LensHttpStatus only if it does not get status code from Status.
+ Response.StatusType httpStatusCode = Response.Status.fromStatusCode(statusCode);
+ if (httpStatusCode == null) {
+ LensHttpStatus[] arr = values();
+ int len = arr.length;
+
+ for (int i = 0; i < len; ++i) {
+ LensHttpStatus lensHttpStatus = arr[i];
+ if (lensHttpStatus.statusCode == statusCode) {
+ return lensHttpStatus;
+ }
+ }
+ }
+
+ return httpStatusCode;
+ }
+
+ public static Response.Status.Family familyOf(int statusCode) {
+ return Response.Status.Family.familyOf(statusCode);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-api/src/main/java/org/apache/lens/api/result/LensAPIResult.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/result/LensAPIResult.java b/lens-api/src/main/java/org/apache/lens/api/result/LensAPIResult.java
index 238f9e6..a1664d6 100644
--- a/lens-api/src/main/java/org/apache/lens/api/result/LensAPIResult.java
+++ b/lens-api/src/main/java/org/apache/lens/api/result/LensAPIResult.java
@@ -21,6 +21,7 @@ package org.apache.lens.api.result;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.annotation.*;
@@ -59,7 +60,7 @@ public class LensAPIResult<DATA> {
private LensErrorTO lensErrorTO;
@XmlTransient
- private Status httpStatusCode;
+ private Response.StatusType httpStatusCode;
public static <DATA> LensAPIResult<DATA> composedOf(final String apiVersion,
final String id, @NonNull final DATA data) {
@@ -67,20 +68,18 @@ public class LensAPIResult<DATA> {
}
public static <DATA> LensAPIResult<DATA> composedOf(final String apiVersion,
- final String id, @NonNull final DATA data, @NonNull final Status httpStatusCode) {
-
+ final String id, @NonNull final DATA data, @NonNull final Response.StatusType httpStatusCode) {
return new LensAPIResult<>(apiVersion, id, data, null, httpStatusCode);
}
public static LensAPIResult<NoResultData> composedOf(
final String apiVersion, final String id, @NonNull final LensErrorTO lensErrorTO,
- @NonNull final Status httpStatusCode) {
-
+ @NonNull final Response.StatusType httpStatusCode) {
return new LensAPIResult<>(apiVersion, id, null, lensErrorTO, httpStatusCode);
}
private LensAPIResult(final String apiVersion, final String id, final DATA data, final LensErrorTO lensErrorTO,
- @NonNull final Status httpStatusCode) {
+ @NonNull final Response.StatusType httpStatusCode) {
/* The check commented below should be enabled in future, once story of apiVersion is clear. Right now there could
be REST APIs throwing LensException without initializing apiVersion
@@ -100,7 +99,7 @@ public class LensAPIResult<DATA> {
return (lensErrorTO != null) && lensErrorTO.areValidStackTracesPresent();
}
- public Status getHttpStatusCode() {
+ public Response.StatusType getHttpStatusCode() {
return this.httpStatusCode;
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-api/src/main/resources/lens-errors.conf
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/lens-errors.conf b/lens-api/src/main/resources/lens-errors.conf
index 09b221f..395d63b 100644
--- a/lens-api/src/main/resources/lens-errors.conf
+++ b/lens-api/src/main/resources/lens-errors.conf
@@ -26,6 +26,7 @@
BAD_REQUEST = 400
NOT_FOUND = 404
UNAUTHORIZED = 401
+TOO_MANY_REQUESTS = 429
INTERNAL_SERVER_ERROR = 500
# Define all module specific errors
@@ -95,6 +96,11 @@ lensServerErrors = [
payloadClass = org.apache.lens.api.query.SupportedQuerySubmitOperations
}
+ {
+ errorCode = 2004
+ httpStatusCode = ${TOO_MANY_REQUESTS}
+ errorMsg = "Too many opened sessions for [%s] user. Session limit [%d] is already reached"
+ }
]
# lensCubeErrors: Defined for lens-cube module
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensConnectionCliCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensConnectionCliCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensConnectionCliCommands.java
index 558e97f..3c4d320 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensConnectionCliCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensConnectionCliCommands.java
@@ -337,9 +337,13 @@ public class TestLensConnectionCliCommands extends LensCliApplicationTest {
LensClient client = new LensClient();
LensConnectionCommands commands = new LensConnectionCommands();
commands.setClient(client);
- LensSessionHandle sessionHandle = client.getConnection().getSessionHandle();
- Assert.assertNotNull(sessionHandle);
- String output = commands.getSessionHandle();
- Assert.assertTrue(output.contains(sessionHandle.getPublicId().toString()), "session handle output: " + output);
+ try {
+ LensSessionHandle sessionHandle = client.getConnection().getSessionHandle();
+ Assert.assertNotNull(sessionHandle);
+ String output = commands.getSessionHandle();
+ Assert.assertTrue(output.contains(sessionHandle.getPublicId().toString()), "session handle output: " + output);
+ } finally {
+ commands.quitShell();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
index 97ca2c8..5a353df 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
@@ -52,36 +52,40 @@ public class TestLensCubeCommands extends LensCliApplicationTest {
@Test
public void testCubeCommands() throws Exception {
LensClient client = new LensClient();
- LensDimensionCommands dimensionCommand = new LensDimensionCommands();
- dimensionCommand.setClient(client);
- dimensionCommand.createDimension(new File(
- TestLensCubeCommands.class.getClassLoader().getResource("test-detail.xml").toURI()));
- dimensionCommand.createDimension(new File(
- TestLensCubeCommands.class.getClassLoader().getResource("test-dimension.xml").toURI()));
- LensCubeCommands command = new LensCubeCommands();
- command.setClient(client);
- LOG.debug("Starting to test cube commands");
- URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("sample-cube.xml");
- String cubeList = command.showCubes();
- assertFalse(cubeList.contains("sample_cube"));
- command.createCube(new File(cubeSpec.toURI()));
- cubeList = command.showCubes();
- assertEquals(command.getLatest("sample_cube", "dt"), "No Data Available");
- assertTrue(cubeList.contains("sample_cube"));
- testJoinChains(command);
- testFields(command);
- testUpdateCommand(new File(cubeSpec.toURI()), command);
- command.dropCube("sample_cube");
try {
- command.getLatest("sample_cube", "dt");
- fail("should have failed as cube doesn't exist");
- } catch (Exception e) {
- //pass
+ LensDimensionCommands dimensionCommand = new LensDimensionCommands();
+ dimensionCommand.setClient(client);
+ dimensionCommand.createDimension(new File(
+ TestLensCubeCommands.class.getClassLoader().getResource("test-detail.xml").toURI()));
+ dimensionCommand.createDimension(new File(
+ TestLensCubeCommands.class.getClassLoader().getResource("test-dimension.xml").toURI()));
+ LensCubeCommands command = new LensCubeCommands();
+ command.setClient(client);
+ LOG.debug("Starting to test cube commands");
+ URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("sample-cube.xml");
+ String cubeList = command.showCubes();
+ assertFalse(cubeList.contains("sample_cube"));
+ command.createCube(new File(cubeSpec.toURI()));
+ cubeList = command.showCubes();
+ assertEquals(command.getLatest("sample_cube", "dt"), "No Data Available");
+ assertTrue(cubeList.contains("sample_cube"));
+ testJoinChains(command);
+ testFields(command);
+ testUpdateCommand(new File(cubeSpec.toURI()), command);
+ command.dropCube("sample_cube");
+ try {
+ command.getLatest("sample_cube", "dt");
+ fail("should have failed as cube doesn't exist");
+ } catch (Exception e) {
+ //pass
+ }
+ cubeList = command.showCubes();
+ assertFalse(cubeList.contains("sample_cube"));
+ dimensionCommand.dropDimension("test_detail");
+ dimensionCommand.dropDimension("test_dim");
+ } finally {
+ client.closeConnection();
}
- cubeList = command.showCubes();
- assertFalse(cubeList.contains("sample_cube"));
- dimensionCommand.dropDimension("test_detail");
- dimensionCommand.dropDimension("test_dim");
}
private void testJoinChains(LensCubeCommands command) {
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
index 32ed7b0..705aace 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
@@ -45,13 +45,17 @@ public class TestLensDatabaseCommands extends LensCliApplicationTest {
@Test
public void testDatabaseCommands() throws URISyntaxException {
LensClient client = new LensClient();
- LensDatabaseCommands command = new LensDatabaseCommands();
- LensCubeCommands cubeCommand = new LensCubeCommands();
- command.setClient(client);
- cubeCommand.setClient(client);
- boolean cascade = true;
- for(int i = 0; i < 4; i++, cascade = !cascade) {
- testDrop(command, cubeCommand, cascade);
+ try {
+ LensDatabaseCommands command = new LensDatabaseCommands();
+ LensCubeCommands cubeCommand = new LensCubeCommands();
+ command.setClient(client);
+ cubeCommand.setClient(client);
+ boolean cascade = true;
+ for (int i = 0; i < 4; i++, cascade = !cascade) {
+ testDrop(command, cubeCommand, cascade);
+ }
+ } finally {
+ client.closeConnection();
}
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
index 955d4c7..a3f01c3 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
@@ -33,6 +33,7 @@ import org.apache.lens.cli.table.XJoinChainTable;
import org.apache.lens.client.LensClient;
import org.testng.Assert;
+import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;
import lombok.extern.slf4j.Slf4j;
@@ -55,6 +56,13 @@ public class TestLensDimensionCommands extends LensCliApplicationTest {
return command;
}
+ @AfterTest
+ public void cleanUp() {
+ if (command != null) {
+ command.getClient().closeConnection();
+ }
+ }
+
/**
* Creates the dimension.
*
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
index bea128b..5d6d768 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
@@ -30,6 +30,7 @@ import org.apache.lens.cli.commands.LensDimensionCommands;
import org.apache.lens.cli.commands.LensDimensionTableCommands;
import org.apache.lens.client.LensClient;
+import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;
import lombok.extern.slf4j.Slf4j;
@@ -65,6 +66,15 @@ public class TestLensDimensionTableCommands extends LensCliApplicationTest {
return dimensionCommand;
}
+ @AfterTest
+ public void cleanUp() {
+ if (command != null) {
+ command.getClient().closeConnection();
+ }
+ if (dimensionCommand != null) {
+ dimensionCommand.getClient().closeConnection();
+ }
+ }
/**
* Test dim table commands.
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
index 1454e5f..9670d8f 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
@@ -31,6 +31,7 @@ import org.apache.lens.cli.commands.LensCubeCommands;
import org.apache.lens.cli.commands.LensFactCommands;
import org.apache.lens.client.LensClient;
+import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;
import lombok.extern.slf4j.Slf4j;
@@ -95,6 +96,16 @@ public class TestLensFactCommands extends LensCliApplicationTest {
return cubeCommands;
}
+ @AfterTest
+ public void cleanUp() {
+ if (command != null) {
+ command.getClient().closeConnection();
+ }
+ if (cubeCommands != null) {
+ cubeCommands.getClient().closeConnection();
+ }
+ }
+
/**
* Adds the fact1 table.
*
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
index 9fce233..24f9279 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
@@ -31,6 +31,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
+import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;
@@ -108,6 +109,16 @@ public class TestLensFactCommandsWithMissingWeight extends LensCliApplicationTes
return cubeCommands;
}
+ @AfterTest
+ public void cleanUp() {
+ if (command != null) {
+ command.getClient().closeConnection();
+ }
+ if (cubeCommands != null) {
+ cubeCommands.getClient().closeConnection();
+ }
+ }
+
/**
* Adds the fact_without_wt table.
*
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensLogResourceCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensLogResourceCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensLogResourceCommands.java
index f4b043e..72a5d9d 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensLogResourceCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensLogResourceCommands.java
@@ -29,6 +29,7 @@ import org.apache.lens.client.LensClient;
import org.apache.commons.io.FileUtils;
import org.testng.Assert;
+import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
@@ -44,6 +45,12 @@ public class TestLensLogResourceCommands extends LensCliApplicationTest {
commands.setClient(client);
}
+ @AfterTest
+ public void cleanup() {
+ if (client != null) {
+ client.closeConnection();
+ }
+ }
@Test
public void testLogResourceFileDoesNotExist() throws IOException {
// check for 404 response
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensNativeTableCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensNativeTableCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensNativeTableCommands.java
index e5f11f2..80dd0d1 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensNativeTableCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensNativeTableCommands.java
@@ -45,8 +45,8 @@ public class TestLensNativeTableCommands extends LensCliApplicationTest {
*/
@Test
public void testNativeTableCommands() throws Exception {
+ LensClient client = new LensClient();
try {
- LensClient client = new LensClient();
LensNativeTableCommands command = new LensNativeTableCommands();
command.setClient(client);
LOG.debug("Starting to test nativetable commands");
@@ -64,7 +64,7 @@ public class TestLensNativeTableCommands extends LensCliApplicationTest {
Assert.assertTrue(desc.contains("test.hive.table.prop"));
} finally {
LensServerTestUtil.dropHiveTable("test_native_table_command");
-
+ client.closeConnection();
}
}
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
index a178296..c4ab614 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
@@ -27,6 +27,7 @@ import org.apache.lens.client.LensClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
+import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;
/**
@@ -61,6 +62,13 @@ public class TestLensStorageCommands extends LensCliApplicationTest {
return command;
}
+ @AfterTest
+ public void cleanup() {
+ if (command != null) {
+ command.getClient().closeConnection();
+ }
+ }
+
/**
* Drop storage.
*
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
index 1b7d0f9..52a7ccc 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
@@ -89,6 +89,10 @@ public final class LensConfConstants {
*/
public static final String WS_FEATURE_NAMES = SERVER_PFX + "ws.featurenames";
+ public static final String MAX_SESSIONS_PER_USER = SERVER_PFX + "max.sessions.per.user";
+
+ public static final Integer DEFAULT_MAX_SESSIONS_PER_USER = 10;
+
/**
* The Constant SERVICE_IMPL_SFX.
*/
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
index a1ffeb6..6f8b175 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
@@ -185,6 +185,7 @@ public class LensException extends Exception implements Comparable<LensException
final String apiVersion, final String id) {
final LensError lensError = errorCollection.getLensError(getErrorCode());
+
final LensErrorTO lensErrorTO = buildLensErrorTO(errorCollection, lensError);
lensAPIResult = LensAPIResult.composedOf(apiVersion, id, lensErrorTO, lensError.getHttpStatusCode());
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/main/java/org/apache/lens/server/BaseLensService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/BaseLensService.java b/lens-server/src/main/java/org/apache/lens/server/BaseLensService.java
index 0821fe7..be31cd8 100644
--- a/lens-server/src/main/java/org/apache/lens/server/BaseLensService.java
+++ b/lens-server/src/main/java/org/apache/lens/server/BaseLensService.java
@@ -41,6 +41,7 @@ import org.apache.lens.server.api.error.LensException;
import org.apache.lens.server.api.events.LensEvent;
import org.apache.lens.server.api.events.LensEventService;
import org.apache.lens.server.api.health.HealthStatus;
+import org.apache.lens.server.error.LensServerErrorCode;
import org.apache.lens.server.session.LensSessionImpl;
import org.apache.lens.server.user.UserConfigLoaderFactory;
import org.apache.lens.server.util.UtilityMethods;
@@ -49,7 +50,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
-
import org.apache.hive.service.CompositeService;
import org.apache.hive.service.auth.AuthenticationProviderFactory;
import org.apache.hive.service.auth.HiveAuthFactory;
@@ -82,7 +82,22 @@ public abstract class BaseLensService extends CompositeService implements Extern
// lens session before submitting a query to hive server
/** The session map. */
protected static final ConcurrentHashMap<String, LensSessionHandle> SESSION_MAP
- = new ConcurrentHashMap<String, LensSessionHandle>();
+ = new ConcurrentHashMap<>();
+
+ /**
+ * This map maintains active session count for each user
+ * Key: userName
+ * Value: number of sessions opened
+ */
+ private static final Map<String, Integer> SESSIONS_PER_USER = new ConcurrentHashMap<>();
+
+ /**
+ * Maintains a map with user to SessionUser instance.
+ * This map is used for acquiring a lock on specific user for while opening & closing sessions
+ */
+ private static final Map<String, SessionUser> SESSION_USER_INSTANCE_MAP = new HashMap<>();
+
+ private final int maxNumSessionsPerUser;
/**
* Instantiates a new lens service.
@@ -93,6 +108,15 @@ public abstract class BaseLensService extends CompositeService implements Extern
protected BaseLensService(String name, CLIService cliService) {
super(name);
this.cliService = cliService;
+ maxNumSessionsPerUser = getMaximumNumberOfSessionsPerUser();
+ }
+
+ private static class SessionUser {
+ private String sessionUser;
+
+ public SessionUser(String user) {
+ this.sessionUser = user;
+ }
}
/**
@@ -110,6 +134,16 @@ public abstract class BaseLensService extends CompositeService implements Extern
return BaseLensService.SESSION_MAP.size();
}
+ private static int getMaximumNumberOfSessionsPerUser() {
+ return LensServerConf.getHiveConf().getInt(LensConfConstants.MAX_SESSIONS_PER_USER,
+ LensConfConstants.DEFAULT_MAX_SESSIONS_PER_USER);
+ }
+
+ private boolean isMaxSessionsLimitReachedPerUser(String userName) {
+ Integer numSessions = SESSIONS_PER_USER.get(userName);
+ return numSessions != null && numSessions >= maxNumSessionsPerUser;
+ }
+
/**
* Open session.
*
@@ -127,42 +161,66 @@ public abstract class BaseLensService extends CompositeService implements Extern
SessionHandle sessionHandle;
username = UtilityMethods.removeDomain(username);
doPasswdAuth(username, password);
- try {
- Map<String, String> sessionConf = new HashMap<String, String>();
- sessionConf.putAll(LensSessionImpl.DEFAULT_HIVE_SESSION_CONF);
- if (configuration != null) {
- sessionConf.putAll(configuration);
- }
- Map<String, String> userConfig = UserConfigLoaderFactory.getUserConfig(username);
- log.info("Got user config: {}", userConfig);
- UtilityMethods.mergeMaps(sessionConf, userConfig, false);
- sessionConf.put(LensConfConstants.SESSION_LOGGEDIN_USER, username);
- 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);
+ SessionUser sessionUser = SESSION_USER_INSTANCE_MAP.get(username);
+ if (sessionUser == null) {
+ sessionUser = new SessionUser(username);
+ SESSION_USER_INSTANCE_MAP.put(username, sessionUser);
+ }
+ synchronized (sessionUser) {
+ if (isMaxSessionsLimitReachedPerUser(username)) {
+ log.error("Can not open new session as session limit {} is reached already for {} user",
+ maxNumSessionsPerUser, username);
+ throw new LensException(LensServerErrorCode.TOO_MANY_OPEN_SESSIONS.getLensErrorInfo(), username,
+ maxNumSessionsPerUser);
}
- String clusterUser = sessionConf.get(LensConfConstants.SESSION_CLUSTER_USER);
- password = "useless";
- if (cliService.getHiveConf().getVar(ConfVars.HIVE_SERVER2_AUTHENTICATION)
- .equals(HiveAuthFactory.AuthTypes.KERBEROS.toString())
- && cliService.getHiveConf().getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS)) {
- String delegationTokenStr = null;
- try {
- delegationTokenStr = cliService.getDelegationTokenFromMetaStore(username);
- } catch (UnsupportedOperationException e) {
- // The delegation token is not applicable in the given deployment mode
+ try {
+ Map<String, String> sessionConf = new HashMap<String, String>();
+ sessionConf.putAll(LensSessionImpl.DEFAULT_HIVE_SESSION_CONF);
+ if (configuration != null) {
+ sessionConf.putAll(configuration);
}
- sessionHandle = cliService.openSessionWithImpersonation(clusterUser, password, sessionConf, delegationTokenStr);
- } else {
- sessionHandle = cliService.openSession(clusterUser, password, sessionConf);
+ Map<String, String> userConfig = UserConfigLoaderFactory.getUserConfig(username);
+ log.info("Got user config: {}", userConfig);
+ UtilityMethods.mergeMaps(sessionConf, userConfig, false);
+ sessionConf.put(LensConfConstants.SESSION_LOGGEDIN_USER, username);
+ 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);
+ }
+ String clusterUser = sessionConf.get(LensConfConstants.SESSION_CLUSTER_USER);
+ password = "useless";
+ if (cliService.getHiveConf().getVar(ConfVars.HIVE_SERVER2_AUTHENTICATION)
+ .equals(HiveAuthFactory.AuthTypes.KERBEROS.toString())
+ && cliService.getHiveConf().getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS)) {
+ String delegationTokenStr = null;
+ try {
+ delegationTokenStr = cliService.getDelegationTokenFromMetaStore(username);
+ } catch (UnsupportedOperationException e) {
+ // The delegation token is not applicable in the given deployment mode
+ }
+ sessionHandle = cliService.openSessionWithImpersonation(clusterUser, password, sessionConf,
+ delegationTokenStr);
+ } else {
+ sessionHandle = cliService.openSession(clusterUser, password, sessionConf);
+ }
+ } catch (Exception e) {
+ throw new LensException(e);
}
- } catch (Exception e) {
- throw new LensException(e);
+ LensSessionHandle lensSessionHandle = new LensSessionHandle(sessionHandle.getHandleIdentifier().getPublicId(),
+ sessionHandle.getHandleIdentifier().getSecretId());
+ SESSION_MAP.put(lensSessionHandle.getPublicId().toString(), lensSessionHandle);
+ updateSessionsPerUser(username);
+ return lensSessionHandle;
+ }
+ }
+
+ 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);
}
- LensSessionHandle lensSession = new LensSessionHandle(sessionHandle.getHandleIdentifier().getPublicId(),
- sessionHandle.getHandleIdentifier().getSecretId());
- SESSION_MAP.put(lensSession.getPublicId().toString(), lensSession);
- return lensSession;
}
protected LensEventService getEventService() {
@@ -194,6 +252,7 @@ public abstract class BaseLensService extends CompositeService implements Extern
LensSessionHandle restoredSession = new LensSessionHandle(restoredHandle.getHandleIdentifier().getPublicId(),
restoredHandle.getHandleIdentifier().getSecretId());
SESSION_MAP.put(restoredSession.getPublicId().toString(), restoredSession);
+ updateSessionsPerUser(userName);
} catch (HiveSQLException e) {
throw new LensException("Error restoring session " + sessionHandle, e);
}
@@ -236,13 +295,33 @@ public abstract class BaseLensService extends CompositeService implements Extern
*/
public void closeSession(LensSessionHandle sessionHandle) throws LensException {
try {
+ String userName = getSession(sessionHandle).getLoggedInUser();
cliService.closeSession(getHiveSessionHandle(sessionHandle));
- SESSION_MAP.remove(sessionHandle.getPublicId().toString());
+ String publicId = sessionHandle.getPublicId().toString();
+ SESSION_MAP.remove(publicId);
+ decrementSessionCountForUser(sessionHandle, userName);
} catch (Exception e) {
throw new LensException(e);
}
}
+ private void decrementSessionCountForUser(LensSessionHandle sessionHandle, String userName) {
+ SessionUser sessionUser = SESSION_USER_INSTANCE_MAP.get(userName);
+ if (sessionUser == null) {
+ log.info("Trying to close invalid session {} for user {}", sessionHandle, userName);
+ return;
+ }
+ synchronized (sessionUser) {
+ Integer sessionCount = SESSIONS_PER_USER.get(userName);
+ log.info("Closed session {} for {} user", sessionHandle, userName);
+ if (sessionCount == 1) {
+ SESSIONS_PER_USER.remove(userName);
+ } else {
+ SESSIONS_PER_USER.put(userName, --sessionCount);
+ }
+ }
+ }
+
public SessionManager getSessionManager() {
return cliService.getSessionManager();
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
index dc20f0f..2443fec 100644
--- a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
+++ b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
@@ -24,7 +24,8 @@ public enum LensServerErrorCode {
SESSION_ID_NOT_PROVIDED(2001, 0),
NULL_OR_EMPTY_OR_BLANK_QUERY(2002, 0),
- UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003, 0);
+ UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003, 0),
+ TOO_MANY_OPEN_SESSIONS(2004, 0);
public LensErrorInfo getLensErrorInfo() {
return this.errorInfo;
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/main/java/org/apache/lens/server/session/SessionResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/session/SessionResource.java b/lens-server/src/main/java/org/apache/lens/server/session/SessionResource.java
index ac77418..0daa286 100644
--- a/lens-server/src/main/java/org/apache/lens/server/session/SessionResource.java
+++ b/lens-server/src/main/java/org/apache/lens/server/session/SessionResource.java
@@ -24,12 +24,14 @@ import java.util.Map;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
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.StringList;
+import org.apache.lens.api.error.ErrorCollection;
import org.apache.lens.server.BaseLensService;
import org.apache.lens.server.LensServices;
import org.apache.lens.server.api.error.LensException;
@@ -52,6 +54,8 @@ public class SessionResource {
/** The session service. */
private SessionService sessionService;
+ private final ErrorCollection errorCollection;
+
/**
* API to know if session service is up and running
*
@@ -70,6 +74,7 @@ public class SessionResource {
*/
public SessionResource() throws LensException {
sessionService = LensServices.get().getService(SessionService.NAME);
+ errorCollection = LensServices.get().getErrorCollection();
}
/**
@@ -87,7 +92,7 @@ public class SessionResource {
public LensSessionHandle openSession(@FormDataParam("username") String username,
@FormDataParam("password") String password,
@FormDataParam("database") @DefaultValue("") String database,
- @FormDataParam("sessionconf") LensConf sessionconf) {
+ @FormDataParam("sessionconf") LensConf sessionconf) throws LensException {
try {
Map<String, String> conf;
if (sessionconf != null) {
@@ -97,7 +102,10 @@ public class SessionResource {
}
return sessionService.openSession(username, password, database, conf);
} catch (LensException e) {
- throw new WebApplicationException(e);
+ e.buildLensErrorResponse(errorCollection, null,
+ LensServices.get().getLogSegregationContext().getLogSegragationId());
+ Response response = Response.status(e.getLensAPIResult().getHttpStatusCode()).build();
+ throw new WebApplicationException(response);
}
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/main/resources/lensserver-default.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/main/resources/lensserver-default.xml b/lens-server/src/main/resources/lensserver-default.xml
index a711d03..6bb66d9 100644
--- a/lens-server/src/main/resources/lensserver-default.xml
+++ b/lens-server/src/main/resources/lensserver-default.xml
@@ -826,5 +826,12 @@
<value>20</value>
<description>Key denoting the default fetch value of saved query list api.</description>
</property>
-
+ <property>
+ <name>lens.server.max.sessions.per.user</name>
+ <value>10</value>
+ <description>Number of sessions can be allowed for each user.
+ User has to close one of the active sessions to open a new session once limit is reached. Otherwise Server throws
+ an exception by saying that opened session limit has been already reached for user.
+ </description>
+ </property>
</configuration>
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/TestServerMode.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/TestServerMode.java b/lens-server/src/test/java/org/apache/lens/server/TestServerMode.java
index caf968a..fce6e5f 100644
--- a/lens-server/src/test/java/org/apache/lens/server/TestServerMode.java
+++ b/lens-server/src/test/java/org/apache/lens/server/TestServerMode.java
@@ -53,6 +53,8 @@ import org.testng.annotations.Test;
@Test(alwaysRun = true, groups = "filter-test", dependsOnGroups = "restart-test")
public class TestServerMode extends LensAllApplicationJerseyTest {
+ private LensSessionHandle lensSessionHandle;
+
/*
* (non-Javadoc)
*
@@ -72,6 +74,7 @@ public class TestServerMode extends LensAllApplicationJerseyTest {
*/
@AfterTest
public void tearDown() throws Exception {
+ RestAPITestUtil.closeSession(target(), lensSessionHandle, defaultMT);
super.tearDown();
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/auth/FooBarAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/auth/FooBarAuthenticationProvider.java b/lens-server/src/test/java/org/apache/lens/server/auth/FooBarAuthenticationProvider.java
index 8e22837..d4c3a83 100644
--- a/lens-server/src/test/java/org/apache/lens/server/auth/FooBarAuthenticationProvider.java
+++ b/lens-server/src/test/java/org/apache/lens/server/auth/FooBarAuthenticationProvider.java
@@ -31,7 +31,8 @@ public class FooBarAuthenticationProvider implements PasswdAuthenticationProvide
public static final String MSG = "<username,password>!=<foo@localhost,bar>";
/** The allowed combinations. */
- private final String[][] allowedCombinations = new String[][]{{"foo", "bar"}, {"anonymous", ""}};
+ private final String[][] allowedCombinations
+ = new String[][]{{"foo", "bar"}, {"anonymous", ""}, {"test", "test"}, {"UITest", "UITest"}};
/*
* (non-Javadoc)
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
index 4d4f137..3ede853 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
@@ -30,10 +30,10 @@ import org.apache.lens.api.result.LensErrorTO;
public class ErrorResponseExpectedData {
- private final Response.Status expectedStatus;
+ private final Response.StatusType expectedStatus;
private final LensErrorTO expectedLensErrorTO;
- public ErrorResponseExpectedData(final Response.Status expectedStatus,
+ public ErrorResponseExpectedData(final Response.StatusType expectedStatus,
final LensErrorTO expectedLensErrorTO) {
this.expectedStatus = expectedStatus;
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
index a541e9b..3b091f5 100644
--- a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
@@ -61,6 +61,7 @@ import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.hadoop.mapred.SequenceFileInputFormat;
import org.glassfish.jersey.test.TestProperties;
+
import org.testng.Assert;
import org.testng.annotations.*;
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
index 30f7aff..29fcd6d 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
@@ -121,6 +121,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
expectedData.verify(response);
+ closeSession(target(), sessionId, mt);
}
@Test(dataProvider = "mediaTypeData")
@@ -140,6 +141,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
expectedData.verify(response);
+ closeSession(target(), sessionId, mt);
}
@Test(dataProvider = "mediaTypeData")
@@ -164,7 +166,9 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
assertTrue(expectedLensErrorTO1.getMessage().equals(responseLensErrorTO.getMessage())
|| expectedLensErrorTO2.getMessage().equals(responseLensErrorTO.getMessage()),
- "Message is " + responseLensErrorTO.getMessage());
+ "Message is " + responseLensErrorTO.getMessage());
+ closeSession(target(), sessionId, mt);
+
}
@Test(dataProvider = "mediaTypeData")
@@ -180,6 +184,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
expectedData.verify(response);
+ closeSession(target(), sessionId, mt);
}
@Test(dataProvider = "mediaTypeData")
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/query/TestLensDAO.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestLensDAO.java b/lens-server/src/test/java/org/apache/lens/server/query/TestLensDAO.java
index a5ee5cc..760e306 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestLensDAO.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestLensDAO.java
@@ -142,5 +142,6 @@ public class TestLensDAO {
Long.MAX_VALUE);
Assert.assertEquals(daoTestQueryHandles.size(), 1);
Assert.assertEquals(daoTestQueryHandles.get(0).getHandleId().toString(), finishedHandle);
+ service.closeSession(session);
}
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java b/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
index bde7b9b..e54f0af 100644
--- a/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
+++ b/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
@@ -22,7 +22,9 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.NotFoundException;
@@ -38,6 +40,7 @@ import org.apache.lens.api.LensConf;
import org.apache.lens.api.LensSessionHandle;
import org.apache.lens.api.StringList;
import org.apache.lens.server.LensJerseyTest;
+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.error.LensException;
@@ -45,6 +48,7 @@ import org.apache.lens.server.api.metrics.MetricsService;
import org.apache.lens.server.api.session.SessionService;
import org.apache.lens.server.common.LenServerTestException;
import org.apache.lens.server.common.LensServerTestFileUtils;
+import org.apache.lens.server.common.RestAPITestUtil;
import org.apache.lens.server.common.TestResourceFile;
import org.apache.commons.io.FileUtils;
@@ -80,6 +84,7 @@ public class TestSessionResource extends LensJerseyTest {
@BeforeTest
public void setUp() throws Exception {
metricsSvc = LensServices.get().getService(MetricsService.NAME);
+ LensServices.get().getLogSegregationContext().setLogSegregationId("logid");
super.setUp();
}
@@ -177,7 +182,7 @@ public class TestSessionResource extends LensJerseyTest {
// Create another session
final LensSessionHandle handle2 = target.request(mt).post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
LensSessionHandle.class);
- Assert.assertNotNull(handle);
+ Assert.assertNotNull(handle2);
// get myvar session params on handle2
try {
@@ -342,7 +347,7 @@ public class TestSessionResource extends LensJerseyTest {
@Test(dataProvider = "mediaTypeData")
public void testServerMustRestartOnManualDeletionOfAddedResources(MediaType mt)
- throws IOException, LenServerTestException {
+ throws IOException, LensException, LenServerTestException {
/* Begin: Setup */
@@ -361,6 +366,8 @@ public class TestSessionResource extends LensJerseyTest {
/* Verification Steps: server should restart without exceptions */
restartLensServer();
+ HiveSessionService service = LensServices.get().getService(SessionService.NAME);
+ service.closeSession(sessionHandle);
}
private LensSessionHandle openSession(final String userName, final String passwd, final LensConf conf, MediaType mt) {
@@ -371,7 +378,7 @@ public class TestSessionResource extends LensJerseyTest {
mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("username").build(), userName));
mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("password").build(), passwd));
mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionconf").fileName("sessionconf").build(),
- conf, mt));
+ conf, mt));
return target.request(mt).post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
LensSessionHandle.class);
@@ -422,7 +429,8 @@ public class TestSessionResource extends LensJerseyTest {
HiveSessionService service = LensServices.get().getService(SessionService.NAME);
LensSessionImpl session = service.getSession(handle);
Assert.assertEquals(session.getCurrentDatabase(), testDbName, "Expected current DB to be set to " + testDbName);
-
+ APIResult result = target.queryParam("sessionid", handle).request().delete(APIResult.class);
+ Assert.assertEquals(result.getStatus(), APIResult.Status.SUCCEEDED);
// TEST 2 - Try set database with invalid db name
final String invalidDB = testDbName + "_invalid_db";
@@ -433,7 +441,6 @@ public class TestSessionResource extends LensJerseyTest {
form2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("database").build(), invalidDB));
form2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionconf").fileName("sessionconf").build(),
new LensConf(), mt));
-
try {
final LensSessionHandle handle2 = target.request(mt).post(Entity.entity(form2,
MediaType.MULTIPART_FORM_DATA_TYPE), LensSessionHandle.class);
@@ -486,6 +493,74 @@ public class TestSessionResource extends LensJerseyTest {
return mp;
}
+ @Test
+ public void testMaxSessionsPerUser() throws Exception {
+ HiveSessionService sessionService = LensServices.get().getService(SessionService.NAME);
+ HiveConf conf = LensServerConf.getHiveConf();
+ Integer maxSessionsLimitPerUser = conf.getInt(LensConfConstants.MAX_SESSIONS_PER_USER,
+ LensConfConstants.DEFAULT_MAX_SESSIONS_PER_USER);
+ List<LensSessionHandle> sessions = new ArrayList<>();
+ try {
+ for (int i = 0; i < maxSessionsLimitPerUser; i++) {
+ LensSessionHandle sessionHandle = sessionService.openSession("test@localhost", "test",
+ new HashMap<String, String>());
+ sessions.add(sessionHandle);
+ Assert.assertNotNull(sessionHandle);
+ }
+ try {
+ sessionService.openSession("test@localhost", "test", new HashMap<String, String>());
+ Assert.fail("Session should not be created as session limit is already reached");
+ } catch (LensException le) {
+ // Exception expected as max session limit is reached for user
+ Assert.assertEquals(le.getErrorCode(), 2004);
+ }
+ // User should be able to open a new session by closing the one of the existing opened sessions
+ sessionService.closeSession(sessions.remove(0));
+ LensSessionHandle sessionHandle = sessionService.openSession("test@localhost", "test",
+ new HashMap<String, String>());
+ sessions.add(sessionHandle);
+ Assert.assertNotNull(sessionHandle);
+ } finally {
+ for (LensSessionHandle sessionHandle : sessions) {
+ sessionService.closeSession(sessionHandle);
+ }
+ }
+ }
+
+ @Test(dataProvider = "mediaTypeData")
+ public void testSessionLimit(MediaType mt) {
+ HiveConf conf = LensServerConf.getHiveConf();
+ Integer maxSessionsLimitPerUser = conf.getInt(LensConfConstants.MAX_SESSIONS_PER_USER,
+ LensConfConstants.DEFAULT_MAX_SESSIONS_PER_USER);
+
+ List<LensSessionHandle> sessionHandleList = new ArrayList<>();
+ try {
+ for (int i = 0; i < maxSessionsLimitPerUser; i++) {
+ final LensSessionHandle handle = RestAPITestUtil.openSession(target(), "test", "test", mt);
+ Assert.assertNotNull(handle);
+ sessionHandleList.add(handle);
+ }
+ try {
+ RestAPITestUtil.openSession(target(), "test", "test", mt);
+
+ Assert.fail("Should not open a new session for user: 'test' as user has already "
+ + maxSessionsLimitPerUser + "active sessions");
+ } catch (ClientErrorException e) {
+ Assert.assertEquals(e.getResponse().getStatus(), 429);
+ }
+ // User should be able to open a new session by closing the one of the existing opened sessions
+ RestAPITestUtil.closeSession(target(), sessionHandleList.remove(0), mt);
+
+ LensSessionHandle lensSessionHandle = RestAPITestUtil.openSession(target(), "test", "test", mt);
+ Assert.assertNotNull(lensSessionHandle);
+ sessionHandleList.add(lensSessionHandle);
+ } finally {
+ for (LensSessionHandle sessionHandle : sessionHandleList) {
+ RestAPITestUtil.closeSession(target(), sessionHandle, mt);
+ }
+ }
+ }
+
@Test(dataProvider = "mediaTypeData")
public void testSessionEvents(MediaType mt) {
final WebTarget target = target().path("session");
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/java/org/apache/lens/server/ui/TestSessionUIResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/ui/TestSessionUIResource.java b/lens-server/src/test/java/org/apache/lens/server/ui/TestSessionUIResource.java
index be87e65..aa28747 100644
--- a/lens-server/src/test/java/org/apache/lens/server/ui/TestSessionUIResource.java
+++ b/lens-server/src/test/java/org/apache/lens/server/ui/TestSessionUIResource.java
@@ -27,10 +27,12 @@ import javax.ws.rs.core.Response;
import org.apache.lens.api.LensConf;
import org.apache.lens.api.LensSessionHandle;
import org.apache.lens.server.LensJerseyTest;
+import org.apache.lens.server.api.error.LensException;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
+
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
@@ -86,9 +88,9 @@ public class TestSessionUIResource extends LensJerseyTest {
* Test ui session
*/
@Test
- public void testUISession() {
+ public void testUISession() throws LensException {
final WebTarget target = target().path("uisession");
- FormDataMultiPart mp = getMultiFormData("foo", "bar");
+ FormDataMultiPart mp = getMultiFormData("UITest", "UITest");
LensSessionHandle lensSessionHandle = target.request().post(
Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), LensSessionHandle.class);
@@ -101,7 +103,7 @@ public class TestSessionUIResource extends LensJerseyTest {
@Test
public void testJsonResponsesFromServer() {
final WebTarget target = target().path("uisession");
- FormDataMultiPart mp = getMultiFormData("foo", "bar");
+ FormDataMultiPart mp = getMultiFormData("UITest", "UITest");
Response response = target.request().accept(MediaType.APPLICATION_JSON).
post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
@@ -112,12 +114,11 @@ public class TestSessionUIResource extends LensJerseyTest {
@Test
public void testXMLResponsesFromServer() {
final WebTarget target = target().path("uisession");
- FormDataMultiPart mp = getMultiFormData("foo", "bar");
+ FormDataMultiPart mp = getMultiFormData("UITest", "UITest");
Response response = target.request().accept(MediaType.APPLICATION_XML).
post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
Assert.assertEquals(response.getStatus(), 200);
Assert.assertEquals(response.getMediaType().toString(), "application/xml");
}
-
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0ba17ef5/lens-server/src/test/resources/lens-site.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/test/resources/lens-site.xml b/lens-server/src/test/resources/lens-site.xml
index c3187a8..b5b3220 100644
--- a/lens-server/src/test/resources/lens-site.xml
+++ b/lens-server/src/test/resources/lens-site.xml
@@ -187,4 +187,9 @@
<name>lens.server.estimate.timeout.millis</name>
<value>120000</value>
</property>
+ <property>
+ <name>lens.server.max.sessions.per.user</name>
+ <value>20</value>
+ <description>Number of sessions can be allowed for each user.</description>
+ </property>
</configuration>