Reorganize Replication Properties For HTTP API
Replication properties are available via separate cluster endpoint,
http://<host>:19002/admin/cluster/replication
Change-Id: I3cff78800afaa2f4271e8df192431a687263ca9d
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1319
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java
index 2b32c60..49730a0 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterAPIServlet.java
@@ -32,6 +32,7 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.asterix.common.config.AbstractAsterixProperties;
+import org.apache.asterix.common.config.AsterixReplicationProperties;
import org.apache.asterix.runtime.util.ClusterStateManager;
import org.json.JSONArray;
import org.json.JSONException;
@@ -41,15 +42,17 @@
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(ClusterAPIServlet.class.getName());
- public static final String NODE_ID_KEY = "node_id";
- public static final String CONFIG_URI_KEY = "configUri";
- public static final String STATS_URI_KEY = "statsUri";
- public static final String THREAD_DUMP_URI_KEY = "threadDumpUri";
- public static final String SHUTDOWN_URI_KEY = "shutdownUri";
- public static final String FULL_SHUTDOWN_URI_KEY = "fullShutdownUri";
- public static final String VERSION_URI_KEY = "versionUri";
- public static final String DIAGNOSTICS_URI_KEY = "diagnosticsUri";
- public static final Pattern PARENT_DIR = Pattern.compile("/[^./]+/\\.\\./");
+ protected static final String NODE_ID_KEY = "node_id";
+ protected static final String CONFIG_URI_KEY = "configUri";
+ protected static final String STATS_URI_KEY = "statsUri";
+ protected static final String THREAD_DUMP_URI_KEY = "threadDumpUri";
+ protected static final String SHUTDOWN_URI_KEY = "shutdownUri";
+ protected static final String FULL_SHUTDOWN_URI_KEY = "fullShutdownUri";
+ protected static final String VERSION_URI_KEY = "versionUri";
+ protected static final String DIAGNOSTICS_URI_KEY = "diagnosticsUri";
+ protected static final String REPLICATION_URI_KEY = "replicationUri";
+ private static final Pattern PARENT_DIR = Pattern.compile("/[^./]+/\\.\\./");
+ private static final Pattern REPLICATION_PROPERTY = Pattern.compile("^replication\\.");
@Override
public final void doGet(HttpServletRequest request, HttpServletResponse response) {
@@ -67,9 +70,21 @@
JSONObject json;
try {
- json = getClusterStateJSON(request, "");
+ switch (request.getPathInfo() == null ? "" : request.getPathInfo()) {
+ case "":
+ json = getClusterStateJSON(request, "");
+ break;
+ case "/replication":
+ json = getReplicationJSON();
+ break;
+ default:
+ throw new IllegalArgumentException();
+
+ }
response.setStatus(HttpServletResponse.SC_OK);
responseWriter.write(json.toString(4));
+ } catch (IllegalArgumentException e) { // NOSONAR - exception not logged or rethrown
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
} catch (Exception e) {
LOGGER.log(Level.INFO, "exception thrown for " + request, e);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
@@ -77,10 +92,23 @@
responseWriter.flush();
}
+ protected JSONObject getReplicationJSON() throws JSONException {
+ for (AbstractAsterixProperties props : getPropertiesInstances()) {
+ if (props instanceof AsterixReplicationProperties) {
+ JSONObject json = new JSONObject();
+ json.put("config", props.getProperties(key -> REPLICATION_PROPERTY.matcher(key).replaceFirst("")));
+ return json;
+ }
+ }
+ throw new IllegalStateException("ERROR: replication properties not found");
+ }
+
protected Map<String, Object> getAllClusterProperties() {
Map<String, Object> allProperties = new HashMap<>();
for (AbstractAsterixProperties properties : getPropertiesInstances()) {
- allProperties.putAll(properties.getProperties());
+ if (!(properties instanceof AsterixReplicationProperties)) {
+ allProperties.putAll(properties.getProperties());
+ }
}
return allProperties;
}
@@ -103,7 +131,7 @@
}
requestURL.append(pathToNode);
String clusterURL = canonicalize(requestURL);
- String analyticsURL = canonicalize(clusterURL + "../");
+ String adminURL = canonicalize(clusterURL + "../");
String nodeURL = clusterURL + "node/";
for (int i = 0; i < ncs.length(); i++) {
JSONObject nc = ncs.getJSONObject(i);
@@ -121,10 +149,11 @@
cc.put(CONFIG_URI_KEY, clusterURL + "cc/config");
cc.put(STATS_URI_KEY, clusterURL + "cc/stats");
cc.put(THREAD_DUMP_URI_KEY, clusterURL + "cc/threaddump");
- json.put(SHUTDOWN_URI_KEY, analyticsURL + "shutdown");
- json.put(FULL_SHUTDOWN_URI_KEY, analyticsURL + "shutdown?all=true");
- json.put(VERSION_URI_KEY, analyticsURL + "version");
- json.put(DIAGNOSTICS_URI_KEY, analyticsURL + "diagnostics");
+ json.put(REPLICATION_URI_KEY, clusterURL + "replication");
+ json.put(SHUTDOWN_URI_KEY, adminURL + "shutdown");
+ json.put(FULL_SHUTDOWN_URI_KEY, adminURL + "shutdown?all=true");
+ json.put(VERSION_URI_KEY, adminURL + "version");
+ json.put(DIAGNOSTICS_URI_KEY, adminURL + "diagnostics");
return json;
}
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
index b097244..aff6a75 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
@@ -223,8 +223,8 @@
addServlet(context, Servlets.SHUTDOWN);
addServlet(context, Servlets.VERSION);
addServlet(context, Servlets.CLUSTER_STATE);
- addServlet(context, Servlets.CLUSTER_STATE_NODE_DETAIL);
- addServlet(context, Servlets.CLUSTER_STATE_CC_DETAIL);
+ addServlet(context, Servlets.CLUSTER_STATE_NODE_DETAIL); // this must not precede add of CLUSTER_STATE
+ addServlet(context, Servlets.CLUSTER_STATE_CC_DETAIL); // this must not precede add of CLUSTER_STATE
addServlet(context, Servlets.DIAGNOSTICS);
return jsonAPIServer;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/APIQueries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/APIQueries.xml
index 67797b2..30dea93 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/APIQueries.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/APIQueries.xml
@@ -63,4 +63,9 @@
<output-dir compare="Text">diagnostics_1</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="api">
+ <compilation-unit name="replication">
+ <output-dir compare="Text">replication</output-dir>
+ </compilation-unit>
+ </test-case>
</test-group>
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/replication/replication.1.httpapi.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/replication/replication.1.httpapi.aql
new file mode 100644
index 0000000..5976b5d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/replication/replication.1.httpapi.aql
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+/*
+ * Test case Name : replication
+ * Description : Replication
+ * Expected Result : Positive
+ * Date : 28th October 2016
+ */
+/admin/cluster/replication
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm
index 9898b2c..649f1e8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm
@@ -53,13 +53,6 @@
]
},
"plot.activate": false,
- "replication.enabled": false,
- "replication.factor": 2,
- "replication.log.batchsize": 4096,
- "replication.log.buffer.numpages": 8,
- "replication.log.buffer.pagesize": 131072,
- "replication.max.remote.recovery.attempts": 5,
- "replication.timeout": 30,
"storage.buffercache.maxopenfiles": 2147483647,
"storage.buffercache.pagesize": 32768,
"storage.buffercache.size": 33554432,
@@ -128,6 +121,7 @@
"threadDumpUri": "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/threaddump"
}
],
+ "replicationUri": "http://127.0.0.1:19002/admin/cluster/replication",
"shutdownUri": "http://127.0.0.1:19002/admin/shutdown",
"state": "ACTIVE",
"versionUri": "http://127.0.0.1:19002/admin/version"
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/replication/replication.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/replication/replication.1.adm
new file mode 100644
index 0000000..8adc10c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/replication/replication.1.adm
@@ -0,0 +1,9 @@
+{"config": {
+ "enabled": false,
+ "factor": 2,
+ "log.batchsize": 4096,
+ "log.buffer.numpages": 8,
+ "log.buffer.pagesize": 131072,
+ "max.remote.recovery.attempts": 5,
+ "timeout": 30
+}}
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/AbstractAsterixProperties.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/AbstractAsterixProperties.java
index 845483e..a79fb89 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/AbstractAsterixProperties.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/AbstractAsterixProperties.java
@@ -26,6 +26,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.UnaryOperator;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -41,12 +42,16 @@
}
public Map<String, Object> getProperties() {
+ return getProperties(UnaryOperator.identity());
+ }
+
+ public Map<String, Object> getProperties(UnaryOperator<String> keyTransformer) {
Map<String, Object> properties = new HashMap<>();
for (Method m : getClass().getMethods()) {
PropertyKey key = m.getAnnotation(PropertyKey.class);
if (key != null) {
try {
- properties.put(key.value(), m.invoke(this));
+ properties.put(keyTransformer.apply(key.value()), m.invoke(this));
} catch (Exception e) {
LOGGER.log(Level.INFO, "Error accessing property: " + key.value(), e);
}
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java
index 45c9ed7..f0b124d 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/ServletUtil.java
@@ -35,7 +35,7 @@
CONNECTOR("/connector"),
SHUTDOWN("/admin/shutdown"),
VERSION("/admin/version"),
- CLUSTER_STATE("/admin/cluster"),
+ CLUSTER_STATE("/admin/cluster/*"),
CLUSTER_STATE_NODE_DETAIL("/admin/cluster/node/*"),
CLUSTER_STATE_CC_DETAIL("/admin/cluster/cc/*"),
DIAGNOSTICS("/admin/diagnostics");
diff --git a/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/aql/TestExecutor.java b/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/aql/TestExecutor.java
index 9c764e9..0a1ad14 100644
--- a/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/aql/TestExecutor.java
+++ b/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/aql/TestExecutor.java
@@ -1055,7 +1055,7 @@
}
protected String getEndpoint(Servlets servlet) {
- return "http://" + host + ":" + port + getPath(servlet);
+ return "http://" + host + ":" + port + getPath(servlet).replaceAll("/\\*$", "");
}
public static String stripJavaComments(String text) {