LENS-750 : Add Hive error codes for Semantic and Authorization exceptions
Project: http://git-wip-us.apache.org/repos/asf/lens/repo Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/bf1053b4 Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/bf1053b4 Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/bf1053b4 Branch: refs/heads/LENS-581 Commit: bf1053b4a1081bd3f07d6b26337e68586404e530 Parents: c179081 Author: Deepak Barr <deepakb...@apache.org> Authored: Fri Dec 18 12:58:13 2015 +0530 Committer: Deepak Kumar Barr <deepakb...@apache.org> Committed: Fri Dec 18 12:58:13 2015 +0530 ---------------------------------------------------------------------- lens-api/src/main/resources/lens-errors.conf | 16 +++++++- .../org/apache/lens/driver/hive/HiveDriver.java | 17 +++++++-- .../lens/driver/hive/LensHiveErrorCode.java | 36 ++++++++++++++++++ .../server/query/QueryAPIErrorResponseTest.java | 5 ++- .../lens/server/query/TestQueryService.java | 40 ++++++++++++++++++-- 5 files changed, 103 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lens/blob/bf1053b4/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 c880543..06960a0 100644 --- a/lens-api/src/main/resources/lens-errors.conf +++ b/lens-api/src/main/resources/lens-errors.conf @@ -317,6 +317,20 @@ lensCubeErrorsForMetastore = [ ] +lensHiveErrors = [ + { + errorCode = 4001 + httpStatusCode = ${BAD_REQUEST} + errorMsg = "Semantic Error : %s" + } + + { + errorCode = 4002 + httpStatusCode = ${INTERNAL_SERVER_ERROR} + errorMsg = "Hive Error : %s" + } +] + lensCubeErrors = ${lensCubeErrorsForQuery}${lensCubeErrorsForMetastore} # Overriding errors in lens-errors.conf via lens-errors-override.conf: @@ -350,4 +364,4 @@ lensCubeErrors = ${lensCubeErrorsForQuery}${lensCubeErrorsForMetastore} # Lens server and Lens client are only aware of errors array. They are not aware of any other array defined in # error configuration files. Hence an errors array is prepared which is a concatenation of all other error arrays. -errors = ${lensCommonErrors}${lensServerErrors}${lensCubeErrors} +errors = ${lensCommonErrors}${lensServerErrors}${lensCubeErrors}${lensHiveErrors} http://git-wip-us.apache.org/repos/asf/lens/blob/bf1053b4/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java ---------------------------------------------------------------------- diff --git a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java index 7391f47..c7ef8f1 100644 --- a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java +++ b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java @@ -18,6 +18,7 @@ */ package org.apache.lens.driver.hive; +import static org.apache.lens.driver.hive.LensHiveErrorCode.*; import static org.apache.lens.server.api.util.LensUtil.getImplementations; import java.io.ByteArrayInputStream; @@ -508,6 +509,7 @@ public class HiveDriver extends AbstractLensDriver { // assuming this is only called for executing explain/insert/set/delete/etc... queries which don't ask to fetch data. public LensResultSet execute(QueryContext ctx) throws LensException { OperationHandle op = null; + LensResultSet result = null; try { addPersistentPath(ctx); Configuration qdconf = ctx.getDriverConf(this); @@ -525,24 +527,24 @@ public class HiveDriver extends AbstractLensDriver { if (status.getState() == OperationState.ERROR) { throw new LensException("Unknown error while running query " + ctx.getUserQuery()); } - LensResultSet result = createResultSet(ctx, true); + result = createResultSet(ctx, true); // close the query immediately if the result is not inmemory result set if (result == null || !(result instanceof HiveInMemoryResultSet)) { closeQuery(ctx.getQueryHandle()); } // remove query handle from hiveHandles even in case of inmemory result set hiveHandles.remove(ctx.getQueryHandle()); - return result; } catch (IOException e) { throw new LensException("Error adding persistent path", e); } catch (HiveSQLException hiveErr) { handleHiveServerError(ctx, hiveErr); - throw new LensException("Error executing query", hiveErr); + handleHiveSQLException(hiveErr); } finally { if (null != op) { opHandleToSession.remove(op); } } + return result; } /* @@ -569,10 +571,17 @@ public class HiveDriver extends AbstractLensDriver { throw new LensException("Error adding persistent path", e); } catch (HiveSQLException e) { handleHiveServerError(ctx, e); - throw new LensException("Error executing async query", e); + handleHiveSQLException(e); } } + private LensException handleHiveSQLException(HiveSQLException ex) throws LensException { + if (ex.getMessage().contains("SemanticException")) { + throw new LensException(SEMANTIC_ERROR.getLensErrorInfo(), ex, ex.getMessage()); + } + throw new LensException(HIVE_ERROR.getLensErrorInfo(), ex, ex.getMessage()); + } + /* * (non-Javadoc) * http://git-wip-us.apache.org/repos/asf/lens/blob/bf1053b4/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/LensHiveErrorCode.java ---------------------------------------------------------------------- diff --git a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/LensHiveErrorCode.java b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/LensHiveErrorCode.java new file mode 100644 index 0000000..3bac9e7 --- /dev/null +++ b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/LensHiveErrorCode.java @@ -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.driver.hive; + +import org.apache.lens.server.api.LensErrorInfo; + +public enum LensHiveErrorCode { + + SEMANTIC_ERROR(4001, 10000), HIVE_ERROR(4002, 10000); + + public LensErrorInfo getLensErrorInfo() { + return this.errorInfo; + } + + LensHiveErrorCode(final int code, final int weight) { + this.errorInfo = new LensErrorInfo(code, weight, name()); + } + + private final LensErrorInfo errorInfo; +} http://git-wip-us.apache.org/repos/asf/lens/blob/bf1053b4/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 18a8c8d..69c3f46 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 @@ -160,7 +160,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest { final String testQuery = "select * from non_existing_table"; Response response = estimate(target(), Optional.of(sessionId), Optional.of(testQuery)); - final String expectedErrMsg = "Internal Server Error."; + final String expectedErrMsg = "Semantic Error : Error while compiling statement: " + + "FAILED: SemanticException [Error 10001]: Line 1:31 Table not found 'non_existing_table'"; LensErrorTO childError1 = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(), expectedErrMsg, MOCK_STACK_TRACE); @@ -170,7 +171,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest { LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(), expectedErrMsg, MOCK_STACK_TRACE, Arrays.asList(childError1, childError2)); - ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(Status.INTERNAL_SERVER_ERROR, + ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(Status.BAD_REQUEST, expectedLensErrorTO); expectedData.verify(response); http://git-wip-us.apache.org/repos/asf/lens/blob/bf1053b4/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java ---------------------------------------------------------------------- diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java index efef358..82afcdc 100644 --- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java +++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java @@ -49,6 +49,7 @@ import org.apache.lens.api.result.LensErrorTO; import org.apache.lens.api.result.QueryCostTO; import org.apache.lens.cube.error.LensCubeErrorCode; import org.apache.lens.driver.hive.HiveDriver; +import org.apache.lens.driver.hive.LensHiveErrorCode; import org.apache.lens.server.LensJerseyTest; import org.apache.lens.server.LensServerTestUtil; import org.apache.lens.server.LensServices; @@ -252,7 +253,7 @@ public class TestQueryService extends LensJerseyTest { mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), conf, MediaType.APPLICATION_XML_TYPE)); final Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE)); - assertEquals(response.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode()); + assertEquals(response.getStatus(), BAD_REQUEST.getStatusCode()); } /** @@ -416,7 +417,7 @@ public class TestQueryService extends LensJerseyTest { final Response responseExplain = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE)); - assertEquals(responseExplain.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode()); + assertEquals(responseExplain.getStatus(), BAD_REQUEST.getStatusCode()); // Test explain and prepare final WebTarget ptarget = target().path("queryapi/preparedqueries"); @@ -433,7 +434,38 @@ public class TestQueryService extends LensJerseyTest { final Response responseExplainAndPrepare = target.request().post( Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE)); - assertEquals(responseExplainAndPrepare.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode()); + assertEquals(responseExplainAndPrepare.getStatus(), BAD_REQUEST.getStatusCode()); + } + + /** + * Test semantic error for hive query on non-existent table. + * + * @throws IOException Signals that an I/O exception has occurred. + * @throws InterruptedException the interrupted exception + */ + @Test + public void testHiveSemanticFailure() throws InterruptedException, IOException { + final WebTarget target = target().path("queryapi/queries"); + + final FormDataMultiPart mp = new FormDataMultiPart(); + mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId, + MediaType.APPLICATION_XML_TYPE)); + mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), " select ID from NOT_EXISTS")); + mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "execute")); + mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(), + MediaType.APPLICATION_XML_TYPE)); + + Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE)); + LensAPIResult result = response.readEntity(LensAPIResult.class); + List<LensErrorTO> childErrors = result.getLensErrorTO().getChildErrors(); + boolean hiveSemanticErrorExists=false; + for (LensErrorTO error : childErrors) { + if (error.getCode() == LensHiveErrorCode.SEMANTIC_ERROR.getLensErrorInfo().getErrorCode()) { + hiveSemanticErrorExists = true; + break; + } + } + assertTrue(hiveSemanticErrorExists); } // post to preparedqueries @@ -1154,7 +1186,7 @@ public class TestQueryService extends LensJerseyTest { MediaType.APPLICATION_XML_TYPE)); Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE)); - assertEquals(response.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode()); + assertEquals(response.getStatus(), BAD_REQUEST.getStatusCode()); } /**