[ASTERIXDB-3343][API] Add servlet to get completed requests
- user model changes: no
- storage format changes: no
- interface changes: yes
Details:
- Add new servlet 'CompletedRequestsServlet' to retrieve
the completed requests similar to what completed_requests() returns.
- Make CcQueryCancellationServlet implement GET to retrieve
the active requests similar to what active_requests() returns.
- Rename CcQueryCancellationServlet to ActiveRequestsServlet.
Change-Id: I9bd395a75970abe01a4fab0a88abcae4df881564
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18138
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
(cherry picked from commit 88c25279458badf088ae36ecef2bf50a66d9638c)
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18109
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/BaseClientRequest.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/BaseClientRequest.java
index 99cda09..db633e6 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/BaseClientRequest.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/BaseClientRequest.java
@@ -93,7 +93,8 @@
return JSONUtil.convertNodeUnchecked(asJson());
}
- protected ObjectNode asJson() {
+ @Override
+ public ObjectNode asJson() {
ObjectNode json = JSONUtil.createObject();
json.put("uuid", requestReference.getUuid());
json.put("requestTime", new ADateTime(requestReference.getTime()).toSimpleString());
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/ClientRequest.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/ClientRequest.java
index c19bb02..4f19366 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/ClientRequest.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/ClientRequest.java
@@ -76,7 +76,7 @@
}
@Override
- protected ObjectNode asJson() {
+ public ObjectNode asJson() {
ObjectNode json = super.asJson();
json.put("jobId", jobId != null ? jobId.toString() : null);
json.put("statement", statement);
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractRequestsServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractRequestsServlet.java
new file mode 100644
index 0000000..285c4c8
--- /dev/null
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractRequestsServlet.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.asterix.api.http.server;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.asterix.common.api.IClientRequest;
+import org.apache.asterix.common.dataflow.ICcApplicationContext;
+import org.apache.hyracks.http.api.IServletRequest;
+import org.apache.hyracks.http.api.IServletResponse;
+import org.apache.hyracks.http.server.AbstractServlet;
+import org.apache.hyracks.http.server.utils.HttpUtil;
+import org.apache.hyracks.util.JSONUtil;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+
+public abstract class AbstractRequestsServlet extends AbstractServlet {
+
+ protected final ICcApplicationContext appCtx;
+
+ public AbstractRequestsServlet(ConcurrentMap<String, Object> ctx, ICcApplicationContext appCtx, String... paths) {
+ super(ctx, paths);
+ this.appCtx = appCtx;
+ }
+
+ @Override
+ protected void get(IServletRequest request, IServletResponse response) throws Exception {
+ ArrayNode requestsJson = JSONUtil.createArray();
+ Collection<IClientRequest> requests = getRequests();
+ for (IClientRequest req : requests) {
+ requestsJson.add(req.asJson());
+ }
+ HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, request);
+ response.setStatus(HttpResponseStatus.OK);
+ JSONUtil.writeNode(response.writer(), requestsJson);
+ response.writer().flush();
+ }
+
+ abstract Collection<IClientRequest> getRequests();
+
+}
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/CcQueryCancellationServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ActiveRequestsServlet.java
similarity index 83%
rename from asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/CcQueryCancellationServlet.java
rename to asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ActiveRequestsServlet.java
index 7ba2867..7e00e9a 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/CcQueryCancellationServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ActiveRequestsServlet.java
@@ -19,6 +19,7 @@
package org.apache.asterix.api.http.server;
import java.io.IOException;
+import java.util.Collection;
import java.util.concurrent.ConcurrentMap;
import org.apache.asterix.api.http.server.QueryServiceRequestParameters.Parameter;
@@ -27,7 +28,6 @@
import org.apache.asterix.common.dataflow.ICcApplicationContext;
import org.apache.hyracks.http.api.IServletRequest;
import org.apache.hyracks.http.api.IServletResponse;
-import org.apache.hyracks.http.server.AbstractServlet;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -35,24 +35,27 @@
import io.netty.handler.codec.http.HttpResponseStatus;
/**
- * The servlet provides a REST API for cancelling an on-going query.
+ * The servlet provides a REST API for getting the running queries or cancelling an on-going one.
*/
-public class CcQueryCancellationServlet extends AbstractServlet {
+public class ActiveRequestsServlet extends AbstractRequestsServlet {
public static final String REQUEST_UUID_PARAM_NAME = "request_id";
private static final Logger LOGGER = LogManager.getLogger();
- private final ICcApplicationContext appCtx;
- public CcQueryCancellationServlet(ConcurrentMap<String, Object> ctx, ICcApplicationContext appCtx,
- String... paths) {
- super(ctx, paths);
- this.appCtx = appCtx;
+ public ActiveRequestsServlet(ConcurrentMap<String, Object> ctx, ICcApplicationContext appCtx, String... paths) {
+ super(ctx, appCtx, paths);
+ }
+
+ @Override
+ public Collection<IClientRequest> getRequests() {
+ return appCtx.getRequestTracker().getRunningRequests();
}
@Override
protected void delete(IServletRequest request, IServletResponse response) throws IOException {
String uuid = request.getParameter(REQUEST_UUID_PARAM_NAME);
String clientCtxId = request.getParameter(Parameter.CLIENT_ID.str());
+ LOGGER.debug("received cancel request, uuid={}, clientCtxId={}", uuid, clientCtxId);
if (uuid == null && clientCtxId == null) {
response.setStatus(HttpResponseStatus.BAD_REQUEST);
return;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/CompletedRequestsServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/CompletedRequestsServlet.java
new file mode 100644
index 0000000..92eacbb
--- /dev/null
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/CompletedRequestsServlet.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.api.http.server;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.asterix.common.api.IClientRequest;
+import org.apache.asterix.common.dataflow.ICcApplicationContext;
+
+public class CompletedRequestsServlet extends AbstractRequestsServlet {
+
+ public CompletedRequestsServlet(ConcurrentMap<String, Object> ctx, ICcApplicationContext appCtx, String... paths) {
+ super(ctx, appCtx, paths);
+ }
+
+ @Override
+ public Collection<IClientRequest> getRequests() {
+ return appCtx.getRequestTracker().getCompletedRequests();
+ }
+
+}
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryCancellationServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryCancellationServlet.java
index b2134dc..5dd9430 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryCancellationServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryCancellationServlet.java
@@ -18,7 +18,7 @@
*/
package org.apache.asterix.api.http.server;
-import static org.apache.asterix.api.http.server.CcQueryCancellationServlet.REQUEST_UUID_PARAM_NAME;
+import static org.apache.asterix.api.http.server.ActiveRequestsServlet.REQUEST_UUID_PARAM_NAME;
import static org.apache.asterix.app.message.ExecuteStatementRequestMessage.DEFAULT_NC_TIMEOUT_MILLIS;
import java.util.concurrent.ConcurrentMap;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
index bc67823..1b011ae 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
@@ -37,9 +37,9 @@
import java.util.concurrent.ConcurrentMap;
import org.apache.asterix.api.http.IQueryWebServerRegistrant;
+import org.apache.asterix.api.http.server.ActiveRequestsServlet;
import org.apache.asterix.api.http.server.ActiveStatsApiServlet;
import org.apache.asterix.api.http.server.ApiServlet;
-import org.apache.asterix.api.http.server.CcQueryCancellationServlet;
import org.apache.asterix.api.http.server.ClusterApiServlet;
import org.apache.asterix.api.http.server.ClusterControllerDetailsApiServlet;
import org.apache.asterix.api.http.server.ConnectorApiServlet;
@@ -315,7 +315,7 @@
ConcurrentMap<String, Object> ctx = server.ctx();
switch (key) {
case Servlets.RUNNING_REQUESTS:
- return new CcQueryCancellationServlet(ctx, appCtx, paths);
+ return new ActiveRequestsServlet(ctx, appCtx, paths);
case Servlets.QUERY_STATUS:
return new QueryStatusApiServlet(ctx, appCtx, paths);
case Servlets.QUERY_RESULT:
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
index 68fb9a8..b38c366 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
@@ -27,7 +27,7 @@
import java.util.concurrent.ConcurrentHashMap;
-import org.apache.asterix.api.http.server.CcQueryCancellationServlet;
+import org.apache.asterix.api.http.server.ActiveRequestsServlet;
import org.apache.asterix.api.http.server.ServletConstants;
import org.apache.asterix.app.translator.RequestParameters;
import org.apache.asterix.common.api.RequestReference;
@@ -57,8 +57,8 @@
RequestTracker tracker = new RequestTracker(appCtx);
Mockito.when(appCtx.getRequestTracker()).thenReturn(tracker);
// Creates a query cancellation servlet.
- CcQueryCancellationServlet cancellationServlet =
- new CcQueryCancellationServlet(new ConcurrentHashMap<>(), appCtx, new String[] { "/" });
+ ActiveRequestsServlet cancellationServlet =
+ new ActiveRequestsServlet(new ConcurrentHashMap<>(), appCtx, new String[] { "/" });
// Adds mocked Hyracks client connection into the servlet context.
IHyracksClientConnection mockHcc = mock(IHyracksClientConnection.class);
cancellationServlet.ctx().put(ServletConstants.HYRACKS_CONNECTION_ATTR, mockHcc);
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IClientRequest.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IClientRequest.java
index 921fb64..3157c64 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IClientRequest.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IClientRequest.java
@@ -21,6 +21,8 @@
import org.apache.asterix.common.dataflow.ICcApplicationContext;
import org.apache.hyracks.api.exceptions.HyracksDataException;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
public interface IClientRequest {
enum State {
@@ -86,7 +88,13 @@
void cancel(ICcApplicationContext appCtx) throws HyracksDataException;
/**
- * @return A json representation of this request
+ * @return A json string representation of this request
*/
String toJson();
+
+ /**
+ * @return A json node representation of this request
+ */
+ ObjectNode asJson();
+
}