summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Rudyy <orudyy@apache.org>2014-02-17 09:55:06 +0000
committerAlex Rudyy <orudyy@apache.org>2014-02-17 09:55:06 +0000
commitcb14ed57053dde009d289e6a230496ca8f00ab59 (patch)
treefda13f0dce5434a9c94a215efe19f313d91aed4f
parent1f14596bfab437c64dcb5ccebb285263a66b6b5a (diff)
downloadqpid-python-cb14ed57053dde009d289e6a230496ca8f00ab59.tar.gz
QPID-5409: Add UI for editing node attributes
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-broker-bdb-ha@1568923 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java7
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/LocalReplicationNode.java4
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java20
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js210
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js84
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html167
6 files changed, 477 insertions, 15 deletions
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java
index d36f9539dd..a137e38baf 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java
@@ -28,6 +28,7 @@ import org.apache.log4j.Logger;
import org.apache.qpid.server.store.StoreFuture;
import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Environment;
import com.sleepycat.je.Transaction;
public class CoalescingCommiter implements Committer
@@ -226,7 +227,11 @@ public class CoalescingCommiter implements Committer
startTime = System.currentTimeMillis();
}
- _environmentFacade.getEnvironment().flushLog(true);
+ Environment environment = _environmentFacade.getEnvironment();
+ if (environment != null && environment.isValid())
+ {
+ environment.flushLog(true);
+ }
if(LOGGER.isDebugEnabled())
{
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/LocalReplicationNode.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/LocalReplicationNode.java
index f87949065a..721acf758a 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/LocalReplicationNode.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/LocalReplicationNode.java
@@ -28,6 +28,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.model.ConfiguredObject;
@@ -50,6 +51,7 @@ import com.sleepycat.je.rep.ReplicatedEnvironment;
public class LocalReplicationNode extends AbstractAdapter implements ReplicationNode, ReplicatedEnvironmentConfiguration
{
+ private static final Logger LOGGER = Logger.getLogger(LocalReplicationNode.class);
private static final Durability DEFAULT_DURABILITY = new Durability(SyncPolicy.NO_SYNC, SyncPolicy.NO_SYNC,
ReplicaAckPolicy.SIMPLE_MAJORITY);
@@ -266,10 +268,12 @@ public class LocalReplicationNode extends AbstractAdapter implements Replication
catch(IllegalStateException e)
{
// ignore, as attribute value will be returned from actual/default attribute maps if present
+ LOGGER.debug("Exception on retrieving attribute from environment", e);
}
catch(DatabaseException e)
{
// ignore, as attribute value will be returned from actual/default attribute maps if present
+ LOGGER.debug("Exception on retrieving attribute from environment", e);
}
}
return super.getAttribute(attributeName);
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
index 123a157513..722a0bca31 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
@@ -419,6 +419,10 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
public String getNodeState()
{
+ if (_state.get() != State.OPEN)
+ {
+ return ReplicatedEnvironment.State.UNKNOWN.name();
+ }
ReplicatedEnvironment.State state = _environment.getState();
return state.toString();
}
@@ -430,6 +434,10 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
public boolean isDesignatedPrimary()
{
+ if (_state.get() != State.OPEN)
+ {
+ throw new IllegalStateException("Environment facade is not opened");
+ }
return _environment.getRepMutableConfig().getDesignatedPrimary();
}
@@ -472,6 +480,10 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
int getPriority()
{
+ if (_state.get() != State.OPEN)
+ {
+ throw new IllegalStateException("Environment facade is not opened");
+ }
ReplicationMutableConfig repConfig = _environment.getRepMutableConfig();
return repConfig.getNodePriority();
}
@@ -515,6 +527,10 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
int getElectableGroupSizeOverride()
{
+ if (_state.get() != State.OPEN)
+ {
+ throw new IllegalStateException("Environment facade is not opened");
+ }
ReplicationMutableConfig repConfig = _environment.getRepMutableConfig();
return repConfig.getElectableGroupSizeOverride();
}
@@ -943,6 +959,10 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
// For testing only
int getNumberOfElectableGroupMembers()
{
+ if (_state.get() != State.OPEN)
+ {
+ throw new IllegalStateException("Environment facade is not opened");
+ }
return _environment.getGroup().getElectableNodes().size();
}
diff --git a/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js
new file mode 100644
index 0000000000..038cdda4d6
--- /dev/null
+++ b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js
@@ -0,0 +1,210 @@
+/*
+ *
+ * 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.
+ *
+ */
+define(["dojo/_base/xhr",
+ "dojo/_base/array",
+ "dojo/_base/event",
+ "dojo/_base/lang",
+ "dojo/_base/window",
+ "dojo/dom",
+ "dojo/dom-construct",
+ "dijit/registry",
+ "dojo/parser",
+ 'dojo/json',
+ "dojo/query",
+ "dojo/text!virtualhost/bdb_ha/edit.html",
+ "dijit/Dialog",
+ "dijit/form/CheckBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/ValidationTextBox",
+ "dijit/form/Button",
+ "dijit/form/Form",
+ "dojox/validate/us",
+ "dojox/validate/web",
+ "dojo/domReady!"],
+ function (xhr, array, event, lang, win, dom, domConstruct, registry, parser, json, query, template)
+ {
+ var widgets = [{
+ name: "storePath",
+ defaultValue: "",
+ editable: false
+ },
+ {
+ name: "name",
+ defaultValue: "",
+ editable: false
+ },
+ {
+ name: "groupName",
+ defaultValue: "",
+ editable: false
+ },
+ {
+ name: "hostPort",
+ defaultValue: "",
+ editable: false
+ },
+ {
+ name: "helperHostPort",
+ defaultValue: "",
+ editable: false
+ },
+ {
+ name: "durability",
+ defaultValue: "",
+ editable: false
+ },
+ {
+ name: "coalescingSync",
+ defaultValue: true,
+ defaultChecked: true,
+ editable: false
+ },
+ {
+ name: "designatedPrimary",
+ defaultValue: true,
+ defaultChecked: true,
+ editable: true
+ },
+ {
+ name: "priority",
+ defaultValue: 1,
+ editable: true
+ },
+ {
+ name: "quorumOverride",
+ defaultValue: 0,
+ editable: true
+ }];
+
+ var bdbHaNodeEditor =
+ {
+ _init: function()
+ {
+ this.containerNode = domConstruct.create("div", {innerHTML: template});
+ parser.parse(this.containerNode);
+ this.dialog = registry.byId("editNodeDialog")
+ this.saveButton = registry.byId("editNode.saveButton");
+ this.cancelButton = registry.byId("editNode.cancelButton");
+ this.cancelButton.on("click", function(e){bdbHaNodeEditor._cancel(e);});
+ this.saveButton.on("click", function(e){bdbHaNodeEditor._save(e);});
+ for(var i = 0; i < widgets.length; i++)
+ {
+ var widgetItem = widgets[i];
+ this[widgetItem.name] = registry.byNode(query(".editNode-" + widgetItem.name, this.dialog.containerNode)[0]);
+ }
+ this.form = registry.byId("editNodeForm");
+ },
+ show: function(virtualHost, nodeName)
+ {
+ this.query = "rest/replicationnode/" + encodeURIComponent(virtualHost) + "/" + encodeURIComponent(nodeName);
+ if (virtualHost && nodeName)
+ {
+ xhr.get({url: this.query,
+ sync: true,
+ handleAs: "json",
+ load: function(data) {
+ var node = data[0];
+ for(var i = 0; i < widgets.length; i++)
+ {
+ var widgetItem = widgets[i];
+ bdbHaNodeEditor[widgetItem.name].set("value", node[widgetItem.name]);
+ bdbHaNodeEditor[widgetItem.name].set("disabled", !widgetItem.editable);
+ }
+ }});
+ }
+ else
+ {
+ for(var i = 0; i < nonEditableWidgetNumber; i++)
+ {
+ var widgetItem = widgets[i];
+ bdbHaNodeEditor[widgetItem.name].set("value", widgetItem.defaultValue);
+ bdbHaNodeEditor[widgetItem.name].set("disabled", false);
+ if (widgetItem.hasOwnProperty("defaultChecked"))
+ {
+ bdbHaNodeEditor[widgetName].set("checked", widgetItem.defaultChecked);
+ }
+ }
+ }
+ this.dialog.show();
+ },
+ destroy: function()
+ {
+ if (this.dialog)
+ {
+ this.dialog.destroyRecursive();
+ this.dialog = null;
+ }
+
+ if (this.containerNode)
+ {
+ domConstruct.destroy(this.containerNode);
+ this.containerNode = null;
+ }
+ },
+ _cancel: function(e)
+ {
+ this.dialog.hide();
+ },
+ _save: function(e)
+ {
+ event.stop(e);
+ if(this.form.validate())
+ {
+ var data = {};
+ for(var i = 0; i < widgets.length; i++)
+ {
+ var widgetItem = widgets[i];
+ var widget = this[widgetItem.name];
+ if (!widget.get("disabled"))
+ {
+ data[widgetItem.name] = widgetItem.hasOwnProperty("defaultChecked")? widget.get("checked"):widget.get("value");
+ }
+ }
+ xhr.put({
+ url: this.query,
+ sync: true,
+ handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.stringify(data),
+ load: function(x) {bdbHaNodeEditor.success = true; },
+ error: function(error) {bdbHaNodeEditor.success = false; bdbHaNodeEditor.failureReason = error;}
+ });
+
+ if(this.success === true)
+ {
+ this.dialog.hide();
+ }
+ else
+ {
+ alert("Error:" + this.failureReason);
+ }
+ }
+ else
+ {
+ alert('Form contains invalid data. Please correct first');
+ }
+ }
+ };
+
+ bdbHaNodeEditor._init();
+
+ return bdbHaNodeEditor;
+ }); \ No newline at end of file
diff --git a/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
index 72d36d57d2..c27cdcfc90 100644
--- a/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
+++ b/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
@@ -19,16 +19,20 @@
*
*/
define(["dojo/_base/xhr",
+ "dojo/_base/lang",
+ "dojo/_base/connect",
"dojo/parser",
"dojo/string",
"dojox/html/entities",
"dojo/query",
+ "dojo/json",
"dijit/registry",
"dojox/grid/EnhancedGrid",
"qpid/common/UpdatableStore",
"qpid/management/UserPreferences",
+ "qpid/management/virtualhost/bdb_ha/edit",
"dojo/domReady!"],
- function (xhr, parser, json, entities, query, registry, EnhancedGrid, UpdatableStore, UserPreferences) {
+ function (xhr, lang, connect, parser, json, entities, query, json, registry, EnhancedGrid, UpdatableStore, UserPreferences, nodeEditor) {
var hostFields = ["desiredState", "quiesceOnMasterChange"];
@@ -36,8 +40,7 @@ define(["dojo/_base/xhr",
"coalescingSync", "designatedPrimary", "durability", "priority", "quorumOverride"];
var buttons = ["activateVirtualHostButton", "quiesceVirtualHostButton", "stopVirtualHostButton",
- "editVirtualHostButton", "activateNodeButton", "stopNodeButton","editNodeButton",
- "removeNodeButton", "transferMasterButton"];
+ "editVirtualHostButton", "removeNodeButton"];
function findNode(nodeClass, containerNode)
{
@@ -73,6 +76,7 @@ define(["dojo/_base/xhr",
BDBHA.prototype.update=function(data)
{
+ this.data = data
for(var i = 0; i < hostFields.length; i++)
{
var name = hostFields[i];
@@ -82,6 +86,8 @@ define(["dojo/_base/xhr",
if (nodes && nodes.length>0)
{
var localNode = nodes[0];
+ this.stopNodeButton.set("disabled", localNode.state == "STOPPED");
+ this.activateNodeButton.set("disabled", localNode.state == "ACTIVE");
for(var i = 0; i < nodeFields.length; i++)
{
var name = nodeFields[i];
@@ -115,6 +121,7 @@ define(["dojo/_base/xhr",
this._initFields(hostFields, containerNode);
this._initFields(nodeFields, containerNode);
+ var that = this;
for(var i = 0; i < buttons.length; i++)
{
var buttonName = buttons[i];
@@ -124,22 +131,63 @@ define(["dojo/_base/xhr",
var buttonWidget = registry.byNode(buttonNode);
if (buttonWidget)
{
- this[buttonName] = buttonWidget;
- var handler = this["_onClick_" + buttonName];
- if (handler)
- {
- buttonWidget.on("click", function(evt){
- handler(evt);
- });
- }
- else
- {
buttonWidget.set("disabled", true);
- }
}
}
}
+ this.editNodeButton = registry.byNode(findNode("editNodeButton", containerNode));
+ this.editNodeButton.on("click", function(e){
+ var nodeName = null;
+ if (that.data.replicationnodes && that.data.replicationnodes.length > 0)
+ {
+ nodeName = that.data.replicationnodes[0].name;
+ }
+ nodeEditor.show(that.data.name, nodeName);
+ });
+
+ function changeNodeAttributes(nodeName, data)
+ {
+ var success = false;
+ var failureReason = "";
+ xhr.put({
+ url: "rest/replicationnode/" + encodeURIComponent(that.data.name) + "/" + encodeURIComponent(nodeName),
+ sync: true,
+ handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.stringify(data),
+ load: function(x) {success = true; },
+ error: function(error) {success = false; failureReason = error;}
+ });
+ if (!success)
+ {
+ alert("Error:" + failureReason);
+ }
+ }
+
+ function changeStatus(newState)
+ {
+ if (confirm("Are you sure you would like to change node state to '" + newState + "'?"))
+ {
+ changeNodeAttributes(that.data.replicationnodes[0].name, {desiredState: newState});
+ }
+ }
+
+ this.stopNodeButton = registry.byNode(findNode("stopNodeButton", containerNode));
+ this.stopNodeButton.on("click", function(e){changeStatus("STOPPED");});
+ this.activateNodeButton = registry.byNode(findNode("activateNodeButton", containerNode));
+ this.activateNodeButton.on("click", function(e){changeStatus("ACTIVE");});
+ this.transferMasterButton = registry.byNode(findNode("transferMasterButton", containerNode));
+ this.transferMasterButton.on("click", function(e){
+ var data = that.membersGrid.grid.selection.getSelected();
+ if (data.length == 1 && confirm("Are you sure you would like to transfer mastership to node '" + data[0].name + "'?"))
+ {
+ changeNodeAttributes(data[0].name, {role: "MASTER"});
+ that.membersGrid.grid.selection.clear();
+ }
+ });
+ this.transferMasterButton.set("disabled", true);
+
this.membersGrid = new UpdatableStore([],
findNode("cluserNodes", containerNode),
[
@@ -158,6 +206,14 @@ define(["dojo/_base/xhr",
},
EnhancedGrid, true );
+ var transferMasterToggler = function(rowIndex){
+ var data = that.membersGrid.grid.selection.getSelected();
+ var isButtonDisabled = data.length != 1 || data[0].role != "REPLICA";
+ that.transferMasterButton.set("disabled", isButtonDisabled);
+ };
+ connect.connect(this.membersGrid.grid.selection, 'onSelected', transferMasterToggler);
+ connect.connect(this.membersGrid.grid.selection, 'onDeselected', transferMasterToggler);
+
this.parametersGrid = new UpdatableStore([],
findNode("parameters", containerNode),
[
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html b/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html
new file mode 100644
index 0000000000..f7cdac81fa
--- /dev/null
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html
@@ -0,0 +1,167 @@
+<!--
+ ~ 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.
+ -->
+<div class="dijitHidden">
+ <div data-dojo-type="dijit/Dialog" data-dojo-props="title:'Edit Node'" id="editNodeDialog">
+ <form id="editNodeForm" method="post" data-dojo-type="dijit/form/Form">
+ <table class="tableContainer-table tableContainer-table-horiz">
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Path to store location*: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="text" class="editNode-storePath"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'storePath',
+ placeHolder: '/path/to/message/store',
+ required: true,
+ missingMessage: 'A store path must be supplied',
+ title: 'Enter path to the store folder'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Node Name*: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="text" class="editNode-name"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'nodeName',
+ placeHolder: 'Node Name',
+ required: true,
+ missingMessage: 'A name must be supplied',
+ title: 'Enter node name',
+ pattern: '^[\x20-\x2e\x30-\x7F]{1,255}$'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Replication Group*: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="text" class="editNode-groupName"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'groupName',
+ placeHolder: 'Group Name',
+ required: true,
+ missingMessage: 'A group name must be supplied',
+ title: 'Enter group name',
+ pattern: '^[\x20-\x2e\x30-\x7F]{1,255}$'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Node Address*: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="text" class="editNode-hostPort"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'hostPort',
+ placeHolder: 'host:port',
+ required: true,
+ missingMessage: 'A Host and Port must be supplied',
+ invalidMessage: 'Must be of the form host:port',
+ title: 'Enter Host and Port name',
+ pattern: '^([0-9a-zA-Z.-_]|::)+:[0-9]{1,5}$'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Helper Address*: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="text" class="editNode-helperHostPort"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'helperHostPort',
+ placeHolder: 'host:port',
+ required: true,
+ missingMessage: 'A Host and Port must be supplied',
+ invalidMessage: 'Must be of the form host:port',
+ title: 'Enter Helper Host and Port name',
+ pattern: '^([0-9a-zA-Z.-_]|::)+:[0-9]{1,5}$'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Durability: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="text" class="editNode-durability"
+ data-dojo-type="dijit/form/ValidationTextBox"
+ data-dojo-props="
+ name: 'durability',
+ placeHolder: 'NO_SYNC,NO_SYNC,SIMPLE_MAJORITY',
+ required: false,
+ missingMessage: 'A Host and Port must be supplied',
+ title: 'Enter Helper Host and Port name',
+ pattern: '^(SYN|NO_SYNC|WRITE_NO_SYNC),(SYN|NO_SYNC|WRITE_NO_SYNC),(SIMPLE_MAJORITY|ALL|NONE)*$'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Coalesce local sync: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="checkbox" class="editNode-coalescingSync" checked="checked"
+ data-dojo-type="dijit/form/CheckBox"
+ data-dojo-props="
+ name: 'coalescingSync',
+ required: false,
+ title: 'Enable coalescing sync mode for a better performance: when many transactions are synced to disk at the same time'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Designated Primary: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="checkbox" class="editNode-designatedPrimary" checked="checked"
+ data-dojo-type="dijit/form/CheckBox"
+ data-dojo-props="
+ name: 'designatedPrimary',
+ required: false,
+ title: 'Designate node as primary. It is applicable only to 2-nodes cluster'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Priority of electing as a Master: </strong></td>
+ <td class="tableContainer-valueCell">
+ <div data-dojo-type="dojo/store/Memory" data-dojo-id="priorityStore"
+ data-dojo-props="data: [
+ {id: '0', name: 'Never'},
+ {id: '1', name: 'Default', selected: '1'},
+ {id: '2', name: 'Middle'},
+ {id: '3', name: 'High'}
+ ]"></div>
+ <input class="editNode-priority" data-dojo-type="dijit/form/FilteringSelect" value="1"
+ data-dojo-props="
+ name: 'priority',
+ required: false,
+ title: 'Select node priority for election as a Master',
+ store: priorityStore,
+ searchAttr: 'name'" />
+ </td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 200px;"><strong>Quorum override: </strong></td>
+ <td class="tableContainer-valueCell">
+ <input type="text" class="editNode-quorumOverride"
+ data-dojo-type="dijit/form/NumberSpinner" value="0"
+ data-dojo-props="
+ name: 'quorumOverride',
+ required: false,
+ title: 'Enter quorum override. 0 signifies simple majority',
+ smallDelta:1,
+ constraints:{min:0,max:10,places:0}" />
+ </td>
+ </tr>
+ </table>
+ <div class="dijitDialogPaneActionBar">
+ <button data-dojo-type="dijit/form/Button" id="editNode.saveButton" data-dojo-props="label: 'Save'" type="submit">Save</button>
+ <button data-dojo-type="dijit/form/Button" id="editNode.cancelButton" data-dojo-props="label: 'Cancel'" ></button>
+ </div>
+ </form>
+ </div>
+</div>