LENS-487: Implementation for consistent error response display for Lens Client
Project: http://git-wip-us.apache.org/repos/asf/incubator-lens/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-lens/commit/d1d99708 Tree: http://git-wip-us.apache.org/repos/asf/incubator-lens/tree/d1d99708 Diff: http://git-wip-us.apache.org/repos/asf/incubator-lens/diff/d1d99708 Branch: refs/heads/current-release-line Commit: d1d99708026d17d43f3f9ea4f9ae088cb151fbd2 Parents: 5d20751 Author: Himanshu Gahlaut <[email protected]> Authored: Thu Jun 11 11:49:37 2015 +0530 Committer: Himanshu Gahlaut <[email protected]> Committed: Sat Jun 20 14:23:53 2015 +0530 ---------------------------------------------------------------------- .../org/apache/lens/api/query/LensQuery.java | 11 ++ .../org/apache/lens/api/query/QueryStatus.java | 12 ++ .../query/SupportedQuerySubmitOperations.java | 59 +++++++++ .../apache/lens/api/response/LensErrorTO.java | 119 ------------------ .../api/response/LensJAXBContextResolver.java | 77 ------------ .../apache/lens/api/response/LensResponse.java | 110 ---------------- .../lens/api/response/NoErrorPayload.java | 33 ----- .../api/response/NoSuccessResponseData.java | 30 ----- .../apache/lens/api/result/LensAPIResult.java | 125 +++++++++++++++++++ .../org/apache/lens/api/result/LensErrorTO.java | 122 ++++++++++++++++++ .../api/result/LensJAXBContextResolver.java | 77 ++++++++++++ .../apache/lens/api/result/NoErrorPayload.java | 33 +++++ .../apache/lens/api/result/NoResultData.java | 30 +++++ .../apache/lens/api/result/PrettyPrintable.java | 32 +++++ lens-api/src/main/resources/lens-errors.conf | 2 +- .../lens/cli/commands/LensQueryCommands.java | 33 +++-- .../apache/lens/cli/ExecuteQueryCommandIT.java | 42 +++++++ .../apache/lens/cli/TestLensQueryCommands.java | 3 +- lens-client/pom.xml | 20 +++ .../java/org/apache/lens/client/LensClient.java | 19 ++- .../org/apache/lens/client/LensStatement.java | 64 ++++++---- .../client/exceptions/LensAPIException.java | 48 +++++++ .../exceptions/LensBriefErrorException.java | 34 +++++ .../client/exceptions/LensClientException.java | 24 +--- .../lens/client/jdbc/LensJdbcStatement.java | 10 +- .../apache/lens/client/model/BriefError.java | 47 +++++++ .../lens/client/model/IdBriefErrorTemplate.java | 53 ++++++++ .../client/model/IdBriefErrorTemplateKey.java | 35 ++++++ .../lens/client/model/BriefErrorTest.java | 60 +++++++++ .../client/model/IdBriefErrorTemplateTest.java | 74 +++++++++++ .../ColUnAvailableInTimeRangeException.java | 2 +- .../FieldsCannotBeQueriedTogetherException.java | 2 +- .../org/apache/lens/examples/SampleQueries.java | 7 +- .../org/apache/lens/ml/impl/LensMLImpl.java | 5 +- .../java/org/apache/lens/rdd/LensRDDClient.java | 7 +- .../regression/core/helpers/QueryHelper.java | 12 +- .../server/api/driver/DriverQueryStatus.java | 4 +- .../lens/server/api/error/LensException.java | 8 +- .../api/error/LensMultiCauseException.java | 2 +- .../server/api/query/FinishedLensQuery.java | 2 +- .../lens/server/api/query/QueryContext.java | 2 +- .../java/org/apache/lens/server/LensServer.java | 2 +- .../lens/server/error/LensExceptionMapper.java | 6 +- .../UnSupportedQuerySubmitOpException.java | 4 +- .../server/query/QueryExecutionServiceImpl.java | 43 +++++-- .../lens/server/query/QueryServiceResource.java | 9 +- .../lens/server/query/ResultFormatter.java | 2 +- .../query/SupportedQuerySubmitOperations.java | 61 --------- .../org/apache/lens/server/LensTestUtil.java | 9 +- .../org/apache/lens/server/TestServerMode.java | 5 +- .../apache/lens/server/TestServerRestart.java | 9 +- .../common/ErrorResponseExpectedData.java | 11 +- .../lens/server/common/TestDataUtils.java | 15 +-- .../metrics/TestResourceMethodMetrics.java | 5 +- .../server/query/QueryAPIErrorResponseTest.java | 9 +- .../server/query/TestQueryEndEmailNotifier.java | 5 +- .../lens/server/query/TestQueryService.java | 39 +++--- .../lens/server/query/TestResultFormatting.java | 5 +- pom.xml | 2 +- 59 files changed, 1131 insertions(+), 601 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java b/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java index c22d39a..f594133 100644 --- a/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java +++ b/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java @@ -209,4 +209,15 @@ public class LensQuery { @Getter private String queryName; + public Integer getErrorCode() { + return (this.status != null) ? this.status.getErrorCode() : null; + } + + public String getErrorMessage() { + return (this.status!=null) ? this.status.getLensErrorTOErrorMsg() : null; + } + + public String getQueryHandleString() { + return (this.queryHandle != null) ? this.queryHandle.getHandleIdString() : null; + } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java index f927375..539f0b0 100644 --- a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java +++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java @@ -26,6 +26,8 @@ import java.io.Serializable; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import org.apache.lens.api.result.LensErrorTO; + import lombok.*; /** @@ -153,6 +155,9 @@ public class QueryStatus implements Serializable { @Setter private String errorMessage; + @XmlElement + private LensErrorTO lensErrorTO; + /* * (non-Javadoc) * @@ -253,4 +258,11 @@ public class QueryStatus implements Serializable { return isValidTransition(this.status, newState); } + public Integer getErrorCode() { + return (this.lensErrorTO != null) ? this.lensErrorTO.getCode() : null; + } + + public String getLensErrorTOErrorMsg() { + return (this.lensErrorTO != null) ? this.lensErrorTO.getMessage() : null; + } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/query/SupportedQuerySubmitOperations.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/query/SupportedQuerySubmitOperations.java b/lens-api/src/main/java/org/apache/lens/api/query/SupportedQuerySubmitOperations.java new file mode 100644 index 0000000..5f246e5 --- /dev/null +++ b/lens-api/src/main/java/org/apache/lens/api/query/SupportedQuerySubmitOperations.java @@ -0,0 +1,59 @@ +/** + * 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.query; + +import static org.apache.lens.api.query.SubmitOp.*; + +import java.util.LinkedList; +import java.util.List; + +import javax.xml.bind.annotation.*; + +import org.apache.commons.lang.StringUtils; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@XmlRootElement +@EqualsAndHashCode +@ToString +@XmlAccessorType(XmlAccessType.FIELD) +public class SupportedQuerySubmitOperations { + + private static final String SEP = ", "; + + @XmlElementWrapper(name = "supportedOperations") + @XmlElement(name = "operation") + private List<String> supportedOps = new LinkedList<String>(); + + public SupportedQuerySubmitOperations() { + ImmutableSet<SubmitOp> supportedOps = Sets.immutableEnumSet(ESTIMATE, EXECUTE, EXPLAIN, EXECUTE_WITH_TIMEOUT); + + for (SubmitOp supportedOp : supportedOps) { + this.supportedOps.add(supportedOp.toString().toLowerCase()); + } + } + + public String getSupportedOperationsAsString() { + return StringUtils.join(supportedOps, SEP); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/response/LensErrorTO.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/response/LensErrorTO.java b/lens-api/src/main/java/org/apache/lens/api/response/LensErrorTO.java deleted file mode 100644 index 313566c..0000000 --- a/lens-api/src/main/java/org/apache/lens/api/response/LensErrorTO.java +++ /dev/null @@ -1,119 +0,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. - */ -package org.apache.lens.api.response; - -import static com.google.common.base.Preconditions.checkArgument; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; - -import org.apache.commons.lang.StringUtils; - -import lombok.*; - -/** - * - * Transport object for lens error information. - * - * @param <PAYLOAD> represents type of error payload transferred in failure lens response - */ -@EqualsAndHashCode(exclude = { "stackTrace" }) -@ToString -@NoArgsConstructor(access = AccessLevel.PACKAGE) -@XmlAccessorType(XmlAccessType.FIELD) -public class LensErrorTO<PAYLOAD> { - - @XmlElement - private int code; - - @XmlElement - private String message; - - @XmlElement - private String stackTrace; - - @XmlElement - @Getter - private PAYLOAD payload; - - @Getter - @XmlElementWrapper(name = "childErrors") - @XmlElement(name = "error") - private List<LensErrorTO> childErrors; - - public static <PAYLOAD> LensErrorTO<PAYLOAD> composedOf(final int code, final String message, - final String stackTrace, final PAYLOAD payload, final List<LensErrorTO> childErrors) { - - return new LensErrorTO<PAYLOAD>(code, message, stackTrace, payload, childErrors); - } - - public static <PAYLOAD> LensErrorTO<PAYLOAD> composedOf(final int code, final String message, - final String stackTrace, final PAYLOAD payload) { - - return new LensErrorTO<PAYLOAD>(code, message, stackTrace, payload, null); - } - - public static LensErrorTO<NoErrorPayload> composedOf(final int code, final String message, - final String stackTrace) { - - return new LensErrorTO<NoErrorPayload>(code, message, stackTrace, null, null); - } - - public static LensErrorTO<NoErrorPayload> composedOf(final int code, final String message, - final String stackTrace, final List<LensErrorTO> childErrors) { - - return new LensErrorTO<NoErrorPayload>(code, message, stackTrace, null, childErrors); - } - - private LensErrorTO(final int code, final String message, final String stackTrace, final PAYLOAD errorPayload, - final List<LensErrorTO> childErrors) { - - checkArgument(code > 0); - checkArgument(StringUtils.isNotBlank(message)); - checkArgument(StringUtils.isNotBlank(stackTrace)); - - this.code = code; - this.message = message; - this.stackTrace = stackTrace; - this.payload = errorPayload; - this.childErrors = childErrors; - } - - public boolean areValidStackTracesPresent() { - - /* if stack trace of first level error is not valid, then return false */ - if (StringUtils.isBlank(stackTrace)) { - return false; - } - - /* validate stack traces of child Errors */ - if (childErrors != null) { - for (LensErrorTO childError : childErrors) { - if (!childError.areValidStackTracesPresent()) { - return false; - } - } - } - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/response/LensJAXBContextResolver.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/response/LensJAXBContextResolver.java b/lens-api/src/main/java/org/apache/lens/api/response/LensJAXBContextResolver.java deleted file mode 100644 index a401b53..0000000 --- a/lens-api/src/main/java/org/apache/lens/api/response/LensJAXBContextResolver.java +++ /dev/null @@ -1,77 +0,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. - */ -package org.apache.lens.api.response; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; - -import org.apache.lens.api.error.ErrorCollection; -import org.apache.lens.api.error.ErrorCollectionFactory; - -import com.google.common.collect.Sets; -import lombok.extern.slf4j.Slf4j; - -/** - * @see javax.ws.rs.ext.ContextResolver - */ -@Provider -@Slf4j -public class LensJAXBContextResolver implements ContextResolver<JAXBContext> { - - private Map<Class, JAXBContext> jaxbContextCache = new ConcurrentHashMap<Class, JAXBContext>(); - - @Override - public JAXBContext getContext(Class<?> type) { - - JAXBContext jaxbContext = jaxbContextCache.get(type); - - if (jaxbContext == null) { - - log.debug("JAXB instance to be created for {}", type); - try { - if (type.equals(LensResponse.class)) { - - ErrorCollection errorCollection = new ErrorCollectionFactory().createErrorCollection(); - Set<Class> classesToBeBound = Sets.newHashSet(errorCollection.getErrorPayloadClasses()); - log.debug("classesToBeBound:{}", classesToBeBound); - classesToBeBound.add(type); - - Class[] classesToBeBoundArray = classesToBeBound.toArray(new Class[classesToBeBound.size()]); - jaxbContext = JAXBContext.newInstance(classesToBeBoundArray); - } else { - - jaxbContext = JAXBContext.newInstance(type); - } - jaxbContextCache.put(type, jaxbContext); - - } catch (JAXBException e) { - log.error("JAXBContext not initialized for "+type, e); - } catch (ClassNotFoundException e) { - log.error("JAXBContext not initialized for "+type, e); - } - } - return jaxbContext; - } -} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/response/LensResponse.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/response/LensResponse.java b/lens-api/src/main/java/org/apache/lens/api/response/LensResponse.java deleted file mode 100644 index 818ae40..0000000 --- a/lens-api/src/main/java/org/apache/lens/api/response/LensResponse.java +++ /dev/null @@ -1,110 +0,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. - */ -package org.apache.lens.api.response; - -import static com.google.common.base.Preconditions.checkArgument; - -import javax.ws.rs.core.Response.Status; -import javax.xml.bind.annotation.*; - -import org.apache.lens.api.query.QuerySubmitResult; - -import org.apache.commons.lang.StringUtils; - -import lombok.*; - -/** - * Transport object for LensResponse - * - * DATA represents type of data transferred in success response. - * PAYLOAD represents type of error payload transferred in error response. - * - */ -@XmlRootElement -@XmlSeeAlso({NoSuccessResponseData.class, NoErrorPayload.class, QuerySubmitResult.class}) -@NoArgsConstructor(access=AccessLevel.PACKAGE) -@ToString -@XmlAccessorType(XmlAccessType.FIELD) -public class LensResponse<DATA, PAYLOAD> { - - @XmlElement - private String apiVersion; - - @XmlElement - private String id; - - @XmlElement(name = "data") - @Getter - private DATA data; - - @XmlElement(name = "error") - @Getter - private LensErrorTO<PAYLOAD> lensErrorTO; - - @XmlTransient - private Status httpStatusCode; - - public static <DATA> LensResponse<DATA, NoErrorPayload> composedOf(final String apiVersion, - final String id, @NonNull final DATA data) { - - return new LensResponse<DATA, NoErrorPayload>(apiVersion, id, data, null, Status.OK); - } - - public static <DATA> LensResponse<DATA, NoErrorPayload> composedOf(final String apiVersion, - final String id, @NonNull final DATA data, @NonNull final Status httpStatusCode) { - - return new LensResponse<DATA, NoErrorPayload>(apiVersion, id, data, null, httpStatusCode); - } - - public static <PAYLOAD> LensResponse<NoSuccessResponseData, PAYLOAD> composedOf( - final String apiVersion, final String id, @NonNull final LensErrorTO<PAYLOAD> lensErrorTO, - @NonNull final Status httpStatusCode) { - - return new LensResponse<NoSuccessResponseData, PAYLOAD>(apiVersion, id, null, lensErrorTO, httpStatusCode); - } - - private LensResponse(final String apiVersion, final String id, final DATA data, - final LensErrorTO lensErrorTO, @NonNull final Status 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 - - checkArgument(StringUtils.isNotBlank(apiVersion)); */ - - checkArgument(StringUtils.isNotBlank(id)); - - this.apiVersion = apiVersion; - this.id = id; - this.data = data; - this.lensErrorTO = lensErrorTO; - this.httpStatusCode = httpStatusCode; - } - - public boolean areValidStackTracesPresent() { - return (lensErrorTO == null) ? false : lensErrorTO.areValidStackTracesPresent(); - } - - public Status getHttpStatusCode() { - return this.httpStatusCode; - } - - public boolean isSuccessResponse() { - return lensErrorTO == null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/response/NoErrorPayload.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/response/NoErrorPayload.java b/lens-api/src/main/java/org/apache/lens/api/response/NoErrorPayload.java deleted file mode 100644 index afc1a05..0000000 --- a/lens-api/src/main/java/org/apache/lens/api/response/NoErrorPayload.java +++ /dev/null @@ -1,33 +0,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. - */ -package org.apache.lens.api.response; - -import javax.xml.bind.annotation.XmlRootElement; - -import lombok.EqualsAndHashCode; - -/** - * NoErrorPayload type is to be used while creating LensResponse for success responses. - * Success Responses will not have any error payload. - * - */ -@XmlRootElement -@EqualsAndHashCode -public final class NoErrorPayload { -} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/response/NoSuccessResponseData.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/response/NoSuccessResponseData.java b/lens-api/src/main/java/org/apache/lens/api/response/NoSuccessResponseData.java deleted file mode 100644 index 1775584..0000000 --- a/lens-api/src/main/java/org/apache/lens/api/response/NoSuccessResponseData.java +++ /dev/null @@ -1,30 +0,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. - */ -package org.apache.lens.api.response; - -import javax.xml.bind.annotation.XmlRootElement; - -/** - * NoSuccessResponseData type is to be used while creating LensResponse for error responses. - * Error Responses will not have any data related to successful execution of API. - * - */ -@XmlRootElement -public final class NoSuccessResponseData { -} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/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 new file mode 100644 index 0000000..41805eb --- /dev/null +++ b/lens-api/src/main/java/org/apache/lens/api/result/LensAPIResult.java @@ -0,0 +1,125 @@ +/** + * 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.result; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import javax.ws.rs.core.Response.Status; +import javax.xml.bind.annotation.*; + +import org.apache.lens.api.query.QuerySubmitResult; + +import org.apache.commons.lang.StringUtils; + +import lombok.*; + +/** + * Transport object for results returned by Lens APIs + * + * DATA represents type of data in success result. + * + */ +@XmlRootElement +@XmlSeeAlso({NoResultData.class, NoErrorPayload.class, QuerySubmitResult.class}) +@NoArgsConstructor(access=AccessLevel.PACKAGE) +@ToString +@XmlAccessorType(XmlAccessType.FIELD) +public class LensAPIResult<DATA> { + + @XmlElement + private String apiVersion; + + @XmlElement + @Getter + private String id; + + @XmlElement(name = "data") + @Getter + private DATA data; + + @XmlElement(name = "error") + @Getter + private LensErrorTO lensErrorTO; + + @XmlTransient + private Status httpStatusCode; + + public static <DATA> LensAPIResult<DATA> composedOf(final String apiVersion, + final String id, @NonNull final DATA data) { + + return new LensAPIResult<DATA>(apiVersion, id, data, null, Status.OK); + } + + public static <DATA> LensAPIResult<DATA> composedOf(final String apiVersion, + final String id, @NonNull final DATA data, @NonNull final Status httpStatusCode) { + + return new LensAPIResult<DATA>(apiVersion, id, data, null, httpStatusCode); + } + + public static <PAYLOAD> LensAPIResult<NoResultData> composedOf( + final String apiVersion, final String id, @NonNull final LensErrorTO lensErrorTO, + @NonNull final Status httpStatusCode) { + + return new LensAPIResult<NoResultData>(apiVersion, id, null, lensErrorTO, httpStatusCode); + } + + private LensAPIResult(final String apiVersion, final String id, final DATA data, final LensErrorTO lensErrorTO, + @NonNull final Status 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 + + checkArgument(StringUtils.isNotBlank(apiVersion)); */ + + checkArgument(StringUtils.isNotBlank(id)); + + this.apiVersion = apiVersion; + this.id = id; + this.data = data; + this.lensErrorTO = lensErrorTO; + this.httpStatusCode = httpStatusCode; + } + + public boolean areValidStackTracesPresent() { + return (lensErrorTO == null) ? false : lensErrorTO.areValidStackTracesPresent(); + } + + public Status getHttpStatusCode() { + return this.httpStatusCode; + } + + public boolean isSuccessResult() { + return lensErrorTO == null; + } + + public boolean isErrorResult() { + return !isSuccessResult(); + } + + public int getErrorCode() { + checkState(isErrorResult()); + return lensErrorTO.getCode(); + } + + public String getErrorMessage() { + checkState(isErrorResult()); + return lensErrorTO.getMessage(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/result/LensErrorTO.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/result/LensErrorTO.java b/lens-api/src/main/java/org/apache/lens/api/result/LensErrorTO.java new file mode 100644 index 0000000..a2aca36 --- /dev/null +++ b/lens-api/src/main/java/org/apache/lens/api/result/LensErrorTO.java @@ -0,0 +1,122 @@ +/** + * 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.result; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.io.Serializable; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + +import org.apache.commons.lang.StringUtils; + +import lombok.*; + +/** + * + * Transport object for lens error information. + * + * @param <PAYLOAD> represents type of error payload transferred in failure lens response + */ +@EqualsAndHashCode(exclude = { "stackTrace" }) +@ToString +@NoArgsConstructor(access = AccessLevel.PACKAGE) +@XmlAccessorType(XmlAccessType.FIELD) +public class LensErrorTO<PAYLOAD> implements Serializable { + + @XmlElement + @Getter + private int code; + + @XmlElement + @Getter + private String message; + + @XmlElement + private String stackTrace; + + @XmlElement + @Getter + private PAYLOAD payload; + + @Getter + @XmlElementWrapper(name = "childErrors") + @XmlElement(name = "error") + private List<LensErrorTO> childErrors; + + public static <PAYLOAD> LensErrorTO<PAYLOAD> composedOf(final int code, final String message, + final String stackTrace, final PAYLOAD payload, final List<LensErrorTO> childErrors) { + + return new LensErrorTO<PAYLOAD>(code, message, stackTrace, payload, childErrors); + } + + public static <PAYLOAD> LensErrorTO<PAYLOAD> composedOf(final int code, final String message, + final String stackTrace, final PAYLOAD payload) { + + return new LensErrorTO<PAYLOAD>(code, message, stackTrace, payload, null); + } + + public static LensErrorTO<NoErrorPayload> composedOf(final int code, final String message, + final String stackTrace) { + + return new LensErrorTO<NoErrorPayload>(code, message, stackTrace, null, null); + } + + public static LensErrorTO<NoErrorPayload> composedOf(final int code, final String message, + final String stackTrace, final List<LensErrorTO> childErrors) { + + return new LensErrorTO<NoErrorPayload>(code, message, stackTrace, null, childErrors); + } + + private LensErrorTO(final int code, final String message, final String stackTrace, final PAYLOAD errorPayload, + final List<LensErrorTO> childErrors) { + + checkArgument(code > 0); + checkArgument(StringUtils.isNotBlank(message)); + checkArgument(StringUtils.isNotBlank(stackTrace)); + + this.code = code; + this.message = message; + this.stackTrace = stackTrace; + this.payload = errorPayload; + this.childErrors = childErrors; + } + + public boolean areValidStackTracesPresent() { + + /* if stack trace of first level error is not valid, then return false */ + if (StringUtils.isBlank(stackTrace)) { + return false; + } + + /* validate stack traces of child Errors */ + if (childErrors != null) { + for (LensErrorTO childError : childErrors) { + if (!childError.areValidStackTracesPresent()) { + return false; + } + } + } + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/result/LensJAXBContextResolver.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/result/LensJAXBContextResolver.java b/lens-api/src/main/java/org/apache/lens/api/result/LensJAXBContextResolver.java new file mode 100644 index 0000000..5b48578 --- /dev/null +++ b/lens-api/src/main/java/org/apache/lens/api/result/LensJAXBContextResolver.java @@ -0,0 +1,77 @@ +/** + * 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.result; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import javax.ws.rs.ext.ContextResolver; +import javax.ws.rs.ext.Provider; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import org.apache.lens.api.error.ErrorCollection; +import org.apache.lens.api.error.ErrorCollectionFactory; + +import com.google.common.collect.Sets; +import lombok.extern.slf4j.Slf4j; + +/** + * @see javax.ws.rs.ext.ContextResolver + */ +@Provider +@Slf4j +public class LensJAXBContextResolver implements ContextResolver<JAXBContext> { + + private Map<Class, JAXBContext> jaxbContextCache = new ConcurrentHashMap<Class, JAXBContext>(); + + @Override + public JAXBContext getContext(Class<?> type) { + + JAXBContext jaxbContext = jaxbContextCache.get(type); + + if (jaxbContext == null) { + + log.debug("JAXB instance to be created for {}", type); + try { + if (type.equals(LensAPIResult.class)) { + + ErrorCollection errorCollection = new ErrorCollectionFactory().createErrorCollection(); + Set<Class> classesToBeBound = Sets.newHashSet(errorCollection.getErrorPayloadClasses()); + log.debug("classesToBeBound:{}", classesToBeBound); + classesToBeBound.add(type); + + Class[] classesToBeBoundArray = classesToBeBound.toArray(new Class[classesToBeBound.size()]); + jaxbContext = JAXBContext.newInstance(classesToBeBoundArray); + } else { + + jaxbContext = JAXBContext.newInstance(type); + } + jaxbContextCache.put(type, jaxbContext); + + } catch (JAXBException e) { + log.error("JAXBContext not initialized for "+type, e); + } catch (ClassNotFoundException e) { + log.error("JAXBContext not initialized for "+type, e); + } + } + return jaxbContext; + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/result/NoErrorPayload.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/result/NoErrorPayload.java b/lens-api/src/main/java/org/apache/lens/api/result/NoErrorPayload.java new file mode 100644 index 0000000..77810d3 --- /dev/null +++ b/lens-api/src/main/java/org/apache/lens/api/result/NoErrorPayload.java @@ -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.api.result; + +import javax.xml.bind.annotation.XmlRootElement; + +import lombok.EqualsAndHashCode; + +/** + * NoErrorPayload type is to be used while creating LensResponse for success responses. + * Success Responses will not have any error payload. + * + */ +@XmlRootElement +@EqualsAndHashCode +public final class NoErrorPayload { +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/result/NoResultData.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/result/NoResultData.java b/lens-api/src/main/java/org/apache/lens/api/result/NoResultData.java new file mode 100644 index 0000000..1b47d02 --- /dev/null +++ b/lens-api/src/main/java/org/apache/lens/api/result/NoResultData.java @@ -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.api.result; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * NoResultData type is to be used while creating LensAPIResult for error scenarios. + * Error scenarios will not have any data related to successful execution of API. + * + */ +@XmlRootElement +public final class NoResultData { +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-api/src/main/java/org/apache/lens/api/result/PrettyPrintable.java ---------------------------------------------------------------------- diff --git a/lens-api/src/main/java/org/apache/lens/api/result/PrettyPrintable.java b/lens-api/src/main/java/org/apache/lens/api/result/PrettyPrintable.java new file mode 100644 index 0000000..e6152b8 --- /dev/null +++ b/lens-api/src/main/java/org/apache/lens/api/result/PrettyPrintable.java @@ -0,0 +1,32 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.lens.api.result; + +/** + * Contents of a class which implements this interface can be represented in a pretty formatted string. + */ +public interface PrettyPrintable { + + /** + * Returns the contents of this object in the form of a pretty formatted string. + * + * @return + */ + String toPrettyString(); +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/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 26bda1f..6130ad7 100644 --- a/lens-api/src/main/resources/lens-errors.conf +++ b/lens-api/src/main/resources/lens-errors.conf @@ -60,7 +60,7 @@ lensServerErrors = [ errorCode = 2003 httpStatusCode = ${BAD_REQUEST} errorMsg = "Provided Operation is not supported. Supported Operations are: [%s]" - payloadClass = org.apache.lens.server.query.SupportedQuerySubmitOperations + payloadClass = org.apache.lens.api.query.SupportedQuerySubmitOperations } ] http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java index 928531e..c48fabd 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java @@ -26,8 +26,14 @@ import java.util.UUID; import javax.ws.rs.core.Response; import org.apache.lens.api.query.*; +import org.apache.lens.api.result.PrettyPrintable; import org.apache.lens.cli.commands.annotations.UserDocumentation; import org.apache.lens.client.LensClient; +import org.apache.lens.client.exceptions.LensAPIException; +import org.apache.lens.client.exceptions.LensBriefErrorException; +import org.apache.lens.client.model.BriefError; +import org.apache.lens.client.model.IdBriefErrorTemplate; +import org.apache.lens.client.model.IdBriefErrorTemplateKey; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; @@ -74,17 +80,26 @@ public class LensQueryCommands extends BaseLensCommand { @CliOption(key = {"async"}, mandatory = false, unspecifiedDefaultValue = "false", specifiedDefaultValue = "true", help = "<async>") boolean async, @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName) { - if (async) { - QueryHandle handle = getClient().executeQueryAsynch(sql, queryName); - return handle.getHandleId().toString(); - } else { - try { - LensClient.LensClientResultSetWithStats result = getClient().getResults(sql, queryName); - return formatResultSet(result); - } catch (Throwable t) { - return t.getMessage(); + + PrettyPrintable cliOutput; + + try { + if (async) { + QueryHandle queryHandle = getClient().executeQueryAsynch(sql, queryName).getData(); + return queryHandle.getHandleIdString(); + } else { + return formatResultSet(getClient().getResults(sql, queryName)); } + } catch (final LensAPIException e) { + + BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage()); + cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError); + + } catch (final LensBriefErrorException e) { + cliOutput = e.getIdBriefErrorTemplate(); } + + return cliOutput.toPrettyString(); } /** http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java new file mode 100644 index 0000000..b3fcccb --- /dev/null +++ b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java @@ -0,0 +1,42 @@ +/** + * 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.cli; + +import static org.testng.Assert.assertTrue; + +import org.apache.lens.cli.commands.LensQueryCommands; +import org.apache.lens.client.LensClient; + +import org.testng.annotations.Test; + +public class ExecuteQueryCommandIT extends LensCliApplicationTest { + + @Test + public void testExecuteSyncQueryWithSyntaxError() { + + LensQueryCommands lensQueryCommands = new LensQueryCommands(); + lensQueryCommands.setClient(new LensClient()); + + final String actualResult = lensQueryCommands.executeQuery("mock-query", false, "testQuery"); + + assertTrue(actualResult.contains("Query Id: ")); + assertTrue(actualResult.contains("\n" + "Error Code: 3001\n" + + "Error Message: Syntax Error: line 1:0 cannot recognize input near 'mock' '-' 'query'")); + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java index 97f0cf0..46e28a9 100644 --- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java +++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java @@ -225,7 +225,8 @@ public class TestLensQueryCommands extends LensCliApplicationTest { String sql = "cube select id,name from test_dim"; long submitTime = System.currentTimeMillis(); String qh = qCom.executeQuery(sql, true, "testQuery1"); - String user = qCom.getClient().getLensStatement(new QueryHandle(UUID.fromString(qh))).getQuery().getSubmittedUser(); + String user = qCom.getClient().getLensStatement(new QueryHandle(UUID.fromString(qh))) + .getQuery().getSubmittedUser(); String result = qCom.getAllQueries("", "testQuery1", user, -1, Long.MAX_VALUE); // this is because previous query has run two query handle will be there assertTrue(result.contains(qh), result); http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/pom.xml ---------------------------------------------------------------------- diff --git a/lens-client/pom.xml b/lens-client/pom.xml index e27a6ce..540c203 100644 --- a/lens-client/pom.xml +++ b/lens-client/pom.xml @@ -123,5 +123,25 @@ <version>${project.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> </dependencies> </project> http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/LensClient.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/LensClient.java b/lens-client/src/main/java/org/apache/lens/client/LensClient.java index 7399d9e..51f586a 100644 --- a/lens-client/src/main/java/org/apache/lens/client/LensClient.java +++ b/lens-client/src/main/java/org/apache/lens/client/LensClient.java @@ -27,6 +27,12 @@ import javax.ws.rs.core.Response; import org.apache.lens.api.APIResult; import org.apache.lens.api.metastore.*; import org.apache.lens.api.query.*; +import org.apache.lens.api.result.LensAPIResult; +import org.apache.lens.client.exceptions.LensAPIException; +import org.apache.lens.client.exceptions.LensBriefErrorException; +import org.apache.lens.client.model.BriefError; +import org.apache.lens.client.model.IdBriefErrorTemplate; +import org.apache.lens.client.model.IdBriefErrorTemplateKey; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -86,13 +92,13 @@ public class LensClient { return mc; } - public QueryHandle executeQueryAsynch(String sql, String queryName) { + public LensAPIResult<QueryHandle> executeQueryAsynch(String sql, String queryName) throws LensAPIException { LOG.debug("Executing query " + sql); - statement.execute(sql, false, queryName); + LensAPIResult<QueryHandle> lensAPIResult = statement.execute(sql, false, queryName); LensQuery query = statement.getQuery(); LOG.debug("Adding query to statementMap " + query.getQueryHandle()); statementMap.put(query.getQueryHandle(), statement); - return query.getQueryHandle(); + return lensAPIResult; } public Date getLatestDateOfCube(String cubeName, String timePartition) { @@ -123,7 +129,7 @@ public class LensClient { } } - public LensClientResultSetWithStats getResults(String sql, String queryName) { + public LensClientResultSetWithStats getResults(String sql, String queryName) throws LensAPIException { LOG.debug("Executing query " + sql); statement.execute(sql, true, queryName); return getResultsFromStatement(statement); @@ -132,8 +138,9 @@ public class LensClient { private LensClientResultSetWithStats getResultsFromStatement(LensStatement statement) { QueryStatus.Status status = statement.getStatus().getStatus(); if (status != QueryStatus.Status.SUCCESSFUL) { - throw new IllegalStateException(statement.getStatus().getStatusMessage() - + " cause:" + statement.getStatus().getErrorMessage()); + IdBriefErrorTemplate errorResult = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.QUERY_ID, + statement.getQueryHandleString(), new BriefError(statement.getErrorCode(), statement.getErrorMessage())); + throw new LensBriefErrorException(errorResult); } LensClientResultSet result = null; if (statement.getStatus().isResultSetAvailable()) { http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/LensStatement.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java index 40e2b86..f7305fb 100644 --- a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java +++ b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java @@ -32,10 +32,8 @@ import org.apache.lens.api.APIResult; import org.apache.lens.api.query.*; import org.apache.lens.api.query.QueryStatus.Status; -import org.apache.lens.api.response.LensJAXBContextResolver; -import org.apache.lens.api.response.LensResponse; -import org.apache.lens.api.response.NoErrorPayload; - +import org.apache.lens.api.result.LensAPIResult; +import org.apache.lens.client.exceptions.LensAPIException; import org.apache.commons.lang.StringUtils; @@ -71,9 +69,11 @@ public class LensStatement { * @param waitForQueryToComplete the wait for query to complete * @param queryName the query name */ - public void execute(String sql, boolean waitForQueryToComplete, String queryName) { - QueryHandle handle = executeQuery(sql, waitForQueryToComplete, queryName); - this.query = getQuery(handle); + public LensAPIResult<QueryHandle> execute(String sql, boolean waitForQueryToComplete, + String queryName) throws LensAPIException { + LensAPIResult<QueryHandle> lensAPIResult = executeQuery(sql, waitForQueryToComplete, queryName); + this.query = getQuery(lensAPIResult.getData()); + return lensAPIResult; } /** @@ -82,8 +82,8 @@ public class LensStatement { * @param sql the sql * @param queryName the query name */ - public void execute(String sql, String queryName) { - QueryHandle handle = executeQuery(sql, true, queryName); + public void execute(String sql, String queryName) throws LensAPIException { + QueryHandle handle = executeQuery(sql, true, queryName).getData(); this.query = getQuery(handle); } @@ -95,13 +95,15 @@ public class LensStatement { * @param queryName the query name * @return the query handle */ - public QueryHandle executeQuery(String sql, boolean waitForQueryToComplete, String queryName) { - QueryHandle handle = executeQuery(sql, queryName); + public LensAPIResult<QueryHandle> executeQuery(String sql, boolean waitForQueryToComplete, + String queryName) throws LensAPIException { + + LensAPIResult<QueryHandle> lensAPIResult = executeQuery(sql, queryName); if (waitForQueryToComplete) { - waitForQueryToComplete(handle); + waitForQueryToComplete(lensAPIResult.getData()); } - return handle; + return lensAPIResult; } /** @@ -137,8 +139,8 @@ public class LensStatement { WebTarget target = getPreparedQueriesWebTarget(client); QueryPrepareHandle handle = target.request().post( - Entity.entity(prepareForm(sql, "PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE), - QueryPrepareHandle.class); + Entity.entity(prepareForm(sql, "PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE), + QueryPrepareHandle.class); getPreparedQuery(handle); return handle; } @@ -288,14 +290,12 @@ public class LensStatement { * @param queryName the query name * @return the query handle */ - private QueryHandle executeQuery(String sql, String queryName) { + private LensAPIResult<QueryHandle> executeQuery(String sql, String queryName) throws LensAPIException { if (!connection.isOpen()) { throw new IllegalStateException("Lens Connection has to be " + "established before querying"); } - Client client = ClientBuilder.newBuilder().register(MultiPartFeature.class).register(LensJAXBContextResolver.class) - .build(); - + Client client = ClientBuilder.newBuilder().register(MultiPartFeature.class).build(); FormDataMultiPart mp = new FormDataMultiPart(); mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), connection .getSessionHandle(), MediaType.APPLICATION_XML_TYPE)); @@ -306,8 +306,13 @@ public class LensStatement { WebTarget target = getQueryWebTarget(client); - return target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), - new GenericType<LensResponse<QueryHandle, NoErrorPayload>>() {}).getData(); + Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE)); + + if (response.getStatus() == Response.Status.OK.getStatusCode()) { + return response.readEntity(new GenericType<LensAPIResult<QueryHandle>>() {}); + } + + throw new LensAPIException(response.readEntity(LensAPIResult.class)); } /** @@ -358,7 +363,7 @@ public class LensStatement { WebTarget target = getQueryWebTarget(client); QueryPlan handle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), - new GenericType<LensResponse<QueryPlan, NoErrorPayload>>() {}).getData(); + new GenericType<LensAPIResult<QueryPlan>>() {}).getData(); return handle; } @@ -396,8 +401,7 @@ public class LensStatement { WebTarget target = getPreparedQueriesWebTarget(client); List<QueryPrepareHandle> handles = target.queryParam("sessionid", connection.getSessionHandle()) .queryParam("user", userName).queryParam("queryName", queryName).queryParam("fromDate", fromDate) - .queryParam("toDate", toDate).request().get(new GenericType<List<QueryPrepareHandle>>() { - }); + .queryParam("toDate", toDate).request().get(new GenericType<List<QueryPrepareHandle>>() {}); return handles; } @@ -561,4 +565,16 @@ public class LensStatement { public LensQuery getQuery() { return this.query; } + + public int getErrorCode() { + return this.query.getErrorCode(); + } + + public String getErrorMessage() { + return this.query.getErrorMessage(); + } + + public String getQueryHandleString() { + return this.query.getQueryHandleString(); + } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/exceptions/LensAPIException.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/exceptions/LensAPIException.java b/lens-client/src/main/java/org/apache/lens/client/exceptions/LensAPIException.java new file mode 100644 index 0000000..fcc53c5 --- /dev/null +++ b/lens-client/src/main/java/org/apache/lens/client/exceptions/LensAPIException.java @@ -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.client.exceptions; + +import static com.google.common.base.Preconditions.checkState; + +import org.apache.lens.api.result.LensAPIResult; + +import lombok.ToString; + +@ToString +public class LensAPIException extends Exception { + + private LensAPIResult errorResult; + + public LensAPIException(final LensAPIResult lensAPIErrorResult) { + checkState(lensAPIErrorResult.isErrorResult()); + this.errorResult = lensAPIErrorResult; + } + + public int getLensAPIErrorCode() { + return this.errorResult.getErrorCode(); + } + + public String getLensAPIErrorMessage() { + return this.errorResult.getErrorMessage(); + } + + public String getLensAPIRequestId() { + return this.errorResult.getId(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/exceptions/LensBriefErrorException.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/exceptions/LensBriefErrorException.java b/lens-client/src/main/java/org/apache/lens/client/exceptions/LensBriefErrorException.java new file mode 100644 index 0000000..ddfd777 --- /dev/null +++ b/lens-client/src/main/java/org/apache/lens/client/exceptions/LensBriefErrorException.java @@ -0,0 +1,34 @@ +/** + * 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.client.exceptions; + +import org.apache.lens.client.model.IdBriefErrorTemplate; + +import lombok.Getter; +import lombok.NonNull; + +public class LensBriefErrorException extends RuntimeException { + + @Getter + private final IdBriefErrorTemplate idBriefErrorTemplate; + + public LensBriefErrorException(@NonNull final IdBriefErrorTemplate idBriefErrorTemplate) { + this.idBriefErrorTemplate = idBriefErrorTemplate; + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/exceptions/LensClientException.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/exceptions/LensClientException.java b/lens-client/src/main/java/org/apache/lens/client/exceptions/LensClientException.java index 1150726..1c03be7 100644 --- a/lens-client/src/main/java/org/apache/lens/client/exceptions/LensClientException.java +++ b/lens-client/src/main/java/org/apache/lens/client/exceptions/LensClientException.java @@ -18,6 +18,8 @@ */ package org.apache.lens.client.exceptions; +import org.apache.lens.api.result.LensAPIResult; + /** * The Class LensClientException. */ @@ -26,12 +28,7 @@ public class LensClientException extends RuntimeException { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; - /** The message. */ - private final String message; - - /** The cause. */ - private Exception cause; - + private LensAPIResult lensAPIErrorResult; /** * Instantiates a new lens client exception. * @@ -39,8 +36,7 @@ public class LensClientException extends RuntimeException { * @param cause the cause */ public LensClientException(String message, Exception cause) { - this.message = message; - this.cause = cause; + super(message, cause); } /** @@ -49,16 +45,6 @@ public class LensClientException extends RuntimeException { * @param message the message */ public LensClientException(String message) { - this.message = message; - } - - @Override - public String getMessage() { - return message; - } - - @Override - public Exception getCause() { - return cause; + super(message); } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcStatement.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcStatement.java b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcStatement.java index 95d0ff7..10f7155 100644 --- a/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcStatement.java +++ b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcStatement.java @@ -21,10 +21,14 @@ package org.apache.lens.client.jdbc; import java.sql.*; import org.apache.lens.client.LensStatement; +import org.apache.lens.client.exceptions.LensAPIException; + +import lombok.extern.slf4j.Slf4j; /** * The Class LensJdbcStatement. */ +@Slf4j public class LensJdbcStatement implements Statement { /** The connection. */ @@ -53,7 +57,11 @@ public class LensJdbcStatement implements Statement { */ @Override public ResultSet executeQuery(String s) throws SQLException { - statement.execute(s, null); + try { + statement.execute(s, null); + } catch (LensAPIException e) { + log.error("Execution Failed for Statement:{}", s, e); + } return new LensJdbcResultSet(statement.getResultSet(), statement.getResultSetMetaData(), this); } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/model/BriefError.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/model/BriefError.java b/lens-client/src/main/java/org/apache/lens/client/model/BriefError.java new file mode 100644 index 0000000..f2b37ea --- /dev/null +++ b/lens-client/src/main/java/org/apache/lens/client/model/BriefError.java @@ -0,0 +1,47 @@ +/** + * 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.client.model; + +import static com.google.common.base.Preconditions.checkArgument; + +import org.apache.lens.api.result.PrettyPrintable; + +import org.apache.commons.lang.StringUtils; + +public class BriefError implements PrettyPrintable { + + private final int errorCode; + private final String errorMsg; + + public BriefError(final int errorCode, final String errorMsg) { + + checkArgument(errorCode > 0); + checkArgument(StringUtils.isNotBlank(errorMsg)); + this.errorCode = errorCode; + this.errorMsg = errorMsg; + } + + @Override + public String toPrettyString() { + + StringBuilder sb = new StringBuilder("Error Code: ").append(this.errorCode).append("\n").append("Error Message: ") + .append(this.errorMsg); + return sb.toString(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplate.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplate.java b/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplate.java new file mode 100644 index 0000000..8a485b5 --- /dev/null +++ b/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplate.java @@ -0,0 +1,53 @@ +/** + * 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.client.model; + +import static com.google.common.base.Preconditions.checkArgument; + +import org.apache.lens.api.result.PrettyPrintable; + +import org.apache.commons.lang.StringUtils; + +import lombok.NonNull; + +public class IdBriefErrorTemplate implements PrettyPrintable { + + private final IdBriefErrorTemplateKey idKey; + private final String idValue; + private final BriefError briefError; + + public IdBriefErrorTemplate(@NonNull final IdBriefErrorTemplateKey idKey, final String idValue, + @NonNull BriefError briefError) { + + checkArgument(StringUtils.isNotBlank(idValue)); + this.idKey = idKey; + this.idValue = idValue; + this.briefError = briefError; + } + + @Override + public String toPrettyString() { + + StringBuilder sb = new StringBuilder(idKey.getConstant()).append(": ").append(this.idValue).append("\n") + .append(this.briefError.toPrettyString()); + + return sb.toString(); + } +} + http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplateKey.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplateKey.java b/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplateKey.java new file mode 100644 index 0000000..41e7177 --- /dev/null +++ b/lens-client/src/main/java/org/apache/lens/client/model/IdBriefErrorTemplateKey.java @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.lens.client.model; + +public enum IdBriefErrorTemplateKey { + + REQUEST_ID("Request Id"), + QUERY_ID("Query Id"); + + IdBriefErrorTemplateKey(final String key) { + this.key = key; + } + + public String getConstant() { + return this.key; + } + + private final String key; +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/test/java/org/apache/lens/client/model/BriefErrorTest.java ---------------------------------------------------------------------- diff --git a/lens-client/src/test/java/org/apache/lens/client/model/BriefErrorTest.java b/lens-client/src/test/java/org/apache/lens/client/model/BriefErrorTest.java new file mode 100644 index 0000000..90e2fbe --- /dev/null +++ b/lens-client/src/test/java/org/apache/lens/client/model/BriefErrorTest.java @@ -0,0 +1,60 @@ +/** + * 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.client.model; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class BriefErrorTest { + + @Test + public void testToPrettyString() { + + final int testErrCode = 1001; + final String testErrorMsg = "Test Error Msg, adfg-asdfk $ %, \n"; + BriefError briefError = new BriefError(testErrCode, testErrorMsg); + + final String actualPrettyString = briefError.toPrettyString(); + final String expectedPrettyString = "Error Code: 1001\nError Message: Test Error Msg, adfg-asdfk $ %, \n"; + + assertEquals(actualPrettyString, expectedPrettyString); + } + + @DataProvider(name="dpInvalidErrorCodes") + public Object[][] dpInvalidErrorCodes() { + return new Object[][] {{-1}, {0}}; + } + + @Test(dataProvider = "dpInvalidStrings", expectedExceptions = IllegalArgumentException.class) + public void testBriefErrorMustNotAcceptInvalidErrorCodes(final int invalidErrCode) { + new BriefError(invalidErrCode, "Valid Error Message"); + } + + @DataProvider(name="dpInvalidStrings") + public Object[][] dpInvalidStrings() { + return new Object[][] {{null}, {""}, {" "}}; + } + + @Test(dataProvider = "dpInvalidStrings", expectedExceptions = IllegalArgumentException.class) + public void testBriefErrorMustNotAcceptInvalidErrorMsg(final String invalidErrMsg) { + new BriefError(1001, invalidErrMsg); + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-client/src/test/java/org/apache/lens/client/model/IdBriefErrorTemplateTest.java ---------------------------------------------------------------------- diff --git a/lens-client/src/test/java/org/apache/lens/client/model/IdBriefErrorTemplateTest.java b/lens-client/src/test/java/org/apache/lens/client/model/IdBriefErrorTemplateTest.java new file mode 100644 index 0000000..9d9ec0e --- /dev/null +++ b/lens-client/src/test/java/org/apache/lens/client/model/IdBriefErrorTemplateTest.java @@ -0,0 +1,74 @@ +/** + * 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.client.model; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class IdBriefErrorTemplateTest { + + @Test + public void testToPrettyString() { + + /* Setup Dependencies */ + final IdBriefErrorTemplateKey testQueryIdKey = IdBriefErrorTemplateKey.QUERY_ID; + final String testQueryIdValue = "TestQueryIdValue"; + final BriefError mockBriefError = mock(BriefError.class); + + /* Stubbing */ + final String testBriefErrorPrettyString = "TestLensBriefErrorPrettyString"; + when(mockBriefError.toPrettyString()).thenReturn(testBriefErrorPrettyString); + + /* Execution */ + IdBriefErrorTemplate template = new IdBriefErrorTemplate(testQueryIdKey, testQueryIdValue, mockBriefError); + final String actualPrettyString = template.toPrettyString(); + + /* Verfication */ + final String expectedPrettyString = "Query Id: TestQueryIdValue\nTestLensBriefErrorPrettyString"; + assertEquals(actualPrettyString, expectedPrettyString); + } + + @DataProvider(name="dpInvalidStrings") + public Object[][] dpInvalidStrings() { + return new Object[][] {{null}, {""}, {" "}}; + } + + @Test(expectedExceptions = NullPointerException.class) + public void testIdBriefErrorTemplateMustNotAcceptNullIdKey() { + + final BriefError mockBriefError = mock(BriefError.class); + new IdBriefErrorTemplate(null, "ValidIdValue", mockBriefError); + } + + @Test(dataProvider = "dpInvalidStrings", expectedExceptions = IllegalArgumentException.class) + public void testIdBriefErrorTemplateMustNotAcceptInvalidIdValue(final String invalidIdValue) { + + final BriefError mockBriefError = mock(BriefError.class); + new IdBriefErrorTemplate(IdBriefErrorTemplateKey.QUERY_ID, invalidIdValue, mockBriefError); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testIdBriefErrorTemplateMustNotAcceptNullBriefError() { + new IdBriefErrorTemplate(IdBriefErrorTemplateKey.QUERY_ID, "ValidIdValue", null); + } +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java ---------------------------------------------------------------------- diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java index 99a78f6..dd3bb72 100644 --- a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java +++ b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java @@ -22,7 +22,7 @@ import static org.apache.lens.cube.error.LensCubeErrorCode.COLUMN_UNAVAILABLE_IN import org.apache.lens.api.error.ErrorCollection; import org.apache.lens.api.error.LensError; -import org.apache.lens.api.response.LensErrorTO; +import org.apache.lens.api.result.LensErrorTO; import org.apache.lens.server.api.error.LensException; import lombok.EqualsAndHashCode; http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java ---------------------------------------------------------------------- diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java index f246246..65b96d7 100644 --- a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java +++ b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java @@ -22,7 +22,7 @@ import static org.apache.lens.cube.error.LensCubeErrorCode.FIELDS_CANNOT_BE_QUER import org.apache.lens.api.error.ErrorCollection; import org.apache.lens.api.error.LensError; -import org.apache.lens.api.response.LensErrorTO; +import org.apache.lens.api.result.LensErrorTO; import org.apache.lens.server.api.error.LensException; import lombok.EqualsAndHashCode; http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java ---------------------------------------------------------------------- diff --git a/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java b/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java index 6c820a4..6b662e7 100644 --- a/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java +++ b/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java @@ -29,6 +29,7 @@ import org.apache.lens.api.query.*; import org.apache.lens.client.LensClientSingletonWrapper; import org.apache.lens.client.LensMetadataClient; import org.apache.lens.client.LensStatement; +import org.apache.lens.client.exceptions.LensAPIException; import org.apache.commons.lang.StringUtils; @@ -99,7 +100,7 @@ public class SampleQueries { * * @throws IOException Signals that an I/O exception has occurred. */ - public void queryAll() throws IOException { + public void queryAll() throws IOException, LensAPIException { runQueries("dimension-queries.sql"); runQueries("cube-queries.sql"); System.out.println("Successful queries " + success + " out of " + total + "queries"); @@ -117,7 +118,7 @@ public class SampleQueries { * @param fileName the file name * @throws IOException Signals that an I/O exception has occurred. */ - public void runQueries(String fileName) throws IOException { + public void runQueries(String fileName) throws IOException, LensAPIException { InputStream file = SampleMetastore.class.getClassLoader().getResourceAsStream(fileName); BufferedReader reader = new BufferedReader(new InputStreamReader(file, "UTF-8")); String query; @@ -131,7 +132,7 @@ public class SampleQueries { } total++; System.out.println("Query:" + query); - QueryHandle handle = queryClient.executeQuery(query, true, null); + QueryHandle handle = queryClient.executeQuery(query, true, null).getData(); System.out.println("Status:" + queryClient.getQuery().getStatus()); System.out.println("Total time in millis:" + (queryClient.getQuery().getFinishTime() - queryClient.getQuery().getSubmissionTime())); http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-ml-lib/src/main/java/org/apache/lens/ml/impl/LensMLImpl.java ---------------------------------------------------------------------- diff --git a/lens-ml-lib/src/main/java/org/apache/lens/ml/impl/LensMLImpl.java b/lens-ml-lib/src/main/java/org/apache/lens/ml/impl/LensMLImpl.java index de76603..50c22f4 100644 --- a/lens-ml-lib/src/main/java/org/apache/lens/ml/impl/LensMLImpl.java +++ b/lens-ml-lib/src/main/java/org/apache/lens/ml/impl/LensMLImpl.java @@ -38,8 +38,7 @@ import org.apache.lens.api.LensSessionHandle; import org.apache.lens.api.query.LensQuery; import org.apache.lens.api.query.QueryHandle; import org.apache.lens.api.query.QueryStatus; -import org.apache.lens.api.response.LensResponse; -import org.apache.lens.api.response.NoErrorPayload; +import org.apache.lens.api.result.LensAPIResult; import org.apache.lens.ml.algo.api.MLAlgo; import org.apache.lens.ml.algo.api.MLDriver; import org.apache.lens.ml.algo.api.MLModel; @@ -647,7 +646,7 @@ public class LensMLImpl implements LensML { MediaType.APPLICATION_XML_TYPE)); final QueryHandle handle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), - new GenericType<LensResponse<QueryHandle, NoErrorPayload>>() {}).getData(); + new GenericType<LensAPIResult<QueryHandle>>() {}).getData(); LensQuery ctx = target.path(handle.toString()).queryParam("sessionid", sessionHandle).request() .get(LensQuery.class); http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/d1d99708/lens-ml-lib/src/main/java/org/apache/lens/rdd/LensRDDClient.java ---------------------------------------------------------------------- diff --git a/lens-ml-lib/src/main/java/org/apache/lens/rdd/LensRDDClient.java b/lens-ml-lib/src/main/java/org/apache/lens/rdd/LensRDDClient.java index fe4d926..0efa10d 100644 --- a/lens-ml-lib/src/main/java/org/apache/lens/rdd/LensRDDClient.java +++ b/lens-ml-lib/src/main/java/org/apache/lens/rdd/LensRDDClient.java @@ -28,6 +28,7 @@ import java.util.UUID; import org.apache.lens.api.query.*; import org.apache.lens.client.LensClient; import org.apache.lens.client.LensClientResultSet; +import org.apache.lens.client.exceptions.LensAPIException; import org.apache.lens.ml.algo.spark.HiveTableRDD; import org.apache.lens.server.api.error.LensException; @@ -169,8 +170,8 @@ public class LensRDDClient { * @return the query handle * @throws LensException the lens exception */ - public QueryHandle createLensRDDAsync(String query) throws LensException { - return getClient().executeQueryAsynch(query, ""); + public QueryHandle createLensRDDAsync(String query) throws LensAPIException { + return getClient().executeQueryAsynch(query, "").getData(); } /** @@ -305,7 +306,7 @@ public class LensRDDClient { * @return the lens rdd result * @throws LensException the lens exception */ - public LensRDDResult createLensRDD(String query) throws LensException { + public LensRDDResult createLensRDD(String query) throws LensAPIException, LensException { QueryHandle queryHandle = createLensRDDAsync(query); while (!isReadyForRDD(queryHandle)) { try {
