/*
* Copyright © 2014-2015 Cask Data, Inc.
*
* Licensed 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 co.cask.cdap.explore.executor;
import co.cask.cdap.common.conf.Constants;
import co.cask.cdap.explore.service.ExploreException;
import co.cask.cdap.explore.service.ExploreService;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.QueryInfo;
import co.cask.http.HttpResponder;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
/**
* Provides REST endpoints for {@link ExploreService} operations.
*/
@Path(Constants.Gateway.API_VERSION_3 + "/namespaces/{namespace-id}")
public class NamespacedQueryExecutorHttpHandler extends AbstractQueryExecutorHttpHandler {
private static final Logger LOG = LoggerFactory.getLogger(NamespacedQueryExecutorHttpHandler.class);
private final ExploreService exploreService;
@Inject
public NamespacedQueryExecutorHttpHandler(ExploreService exploreService) {
this.exploreService = exploreService;
}
@POST
@Path("data/explore/queries")
public void query(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespaceId) throws IOException, ExploreException {
try {
Map<String, String> args = decodeArguments(request);
String query = args.get("query");
LOG.trace("Received query: {}", query);
responder.sendJson(HttpResponseStatus.OK, exploreService.execute(Id.Namespace.from(namespaceId), query));
} catch (IllegalArgumentException e) {
LOG.debug("Got exception:", e);
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
} catch (SQLException e) {
LOG.debug("Got exception:", e);
responder.sendString(HttpResponseStatus.BAD_REQUEST, String.format("[SQLState %s] %s",
e.getSQLState(), e.getMessage()));
}
}
@GET
@Path("data/explore/queries")
public void getQueryLiveHandles(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespaceId,
@QueryParam("offset") @DefaultValue("9223372036854775807") long offset,
@QueryParam("cursor") @DefaultValue("next") String cursor,
@QueryParam("limit") @DefaultValue("50") int limit)
throws ExploreException, SQLException {
boolean isForward = "next".equals(cursor);
List<QueryInfo> queries = exploreService.getQueries(Id.Namespace.from(namespaceId));
// return the queries by after filtering (> offset) and limiting number of queries
responder.sendJson(HttpResponseStatus.OK, filterQueries(queries, offset, isForward, limit));
}
@GET
@Path("data/explore/queries/count")
public void getActiveQueryCount(HttpRequest request, HttpResponder responder,
@PathParam("namespace-id") String namespaceId) throws ExploreException {
int count = exploreService.getActiveQueryCount(Id.Namespace.from(namespaceId));
responder.sendJson(HttpResponseStatus.OK, ImmutableMap.of("count", count));
}
}