diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadRequest.java b/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadRequest.java index 6c0ba30094..a22464ad4f 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadRequest.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadRequest.java @@ -1,5 +1,7 @@ package org.onlab.onos.store.service; +import com.google.common.base.MoreObjects; + /** * Database read request. */ @@ -31,6 +33,9 @@ public class ReadRequest { @Override public String toString() { - return "ReadRequest [tableName=" + tableName + ", key=" + key + "]"; + return MoreObjects.toStringHelper(getClass()) + .add("tableName", tableName) + .add("key", key) + .toString(); } } \ No newline at end of file diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadResult.java b/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadResult.java index 33b57d2447..6d28fc256f 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadResult.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/service/ReadResult.java @@ -1,5 +1,7 @@ package org.onlab.onos.store.service; +import com.google.common.base.MoreObjects; + /** * Database read result. @@ -18,7 +20,7 @@ public class ReadResult { /** * Returns database table name. - * @return table name. + * @return table name */ public String tableName() { return tableName; @@ -26,7 +28,7 @@ public class ReadResult { /** * Returns database table key. - * @return key. + * @return key */ public String key() { return key; @@ -39,4 +41,13 @@ public class ReadResult { public VersionedValue value() { return value; } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("tableName", tableName) + .add("key", key) + .add("value", value) + .toString(); + } } diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/service/VersionedValue.java b/core/store/dist/src/main/java/org/onlab/onos/store/service/VersionedValue.java index d88d35ec7a..852fb07055 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/service/VersionedValue.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/service/VersionedValue.java @@ -2,6 +2,8 @@ package org.onlab.onos.store.service; import java.util.Arrays; +import com.google.common.base.MoreObjects; + /** * Wrapper object that holds the object (as byte array) and its version. */ @@ -38,7 +40,9 @@ public class VersionedValue { @Override public String toString() { - return "VersionedValue [value=" + Arrays.toString(value) + ", version=" - + version + "]"; + return MoreObjects.toStringHelper(getClass()) + .add("version", version) + .add("value", Arrays.toString(value)) + .toString(); } } diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteRequest.java b/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteRequest.java index 1561c2d5e9..99f73c11d8 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteRequest.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteRequest.java @@ -4,6 +4,8 @@ import static com.google.common.base.Preconditions.checkArgument; import java.util.Objects; +import com.google.common.base.MoreObjects; + /** * Database write request. */ @@ -67,10 +69,13 @@ public class WriteRequest { @Override public String toString() { - return "WriteRequest [tableName=" + tableName + ", key=" + key - + ", newValue=" + newValue - + ", previousVersion=" + previousVersion - + ", oldValue=" + oldValue; + return MoreObjects.toStringHelper(getClass()) + .add("tableName", tableName) + .add("key", key) + .add("newValue", newValue) + .add("previousVersion", previousVersion) + .add("oldValue", oldValue) + .toString(); } @Override diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteResult.java b/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteResult.java index fa20a04430..aec30469b7 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteResult.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/service/WriteResult.java @@ -1,5 +1,7 @@ package org.onlab.onos.store.service; +import com.google.common.base.MoreObjects; + /** * Database write result. @@ -27,4 +29,13 @@ public class WriteResult { public VersionedValue previousValue() { return previousValue; } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("tableName", tableName) + .add("key", key) + .add("previousValue", previousValue) + .toString(); + } } diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocol.java b/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocol.java index d88a214cb5..6de66bc642 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocol.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocol.java @@ -69,10 +69,10 @@ public class ClusterMessagingProtocol implements Protocol { private final Logger log = getLogger(getClass()); @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - ClusterService clusterService; + protected ClusterService clusterService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - ClusterCommunicationService clusterCommunicator; + protected ClusterCommunicationService clusterCommunicator; public static final MessageSubject COPYCAT_PING = new MessageSubject("copycat-raft-consensus-ping"); diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/DatabaseManager.java b/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/DatabaseManager.java index c42f74e4d7..7db4bc7f94 100644 --- a/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/DatabaseManager.java +++ b/core/store/dist/src/main/java/org/onlab/onos/store/service/impl/DatabaseManager.java @@ -49,10 +49,10 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { private final Logger log = getLogger(getClass()); @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - ClusterService clusterService; + protected ClusterService clusterService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - ClusterMessagingProtocol copycatMessagingProtocol; + protected ClusterMessagingProtocol copycatMessagingProtocol; public static final String LOG_FILE_PREFIX = "onos-copy-cat-log"; diff --git a/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java b/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java index e0eea96698..db52454b68 100644 --- a/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java +++ b/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java @@ -82,7 +82,7 @@ public class LinkDiscovery implements TimerTask { private final PacketService pktService; private final MastershipService mastershipService; private Timeout timeout; - private boolean isStopped; + private volatile boolean isStopped; /** * Instantiates discovery manager for the given physical switch. Creates a @@ -243,8 +243,10 @@ public class LinkDiscovery implements TimerTask { public void run(final Timeout t) { boolean isMaster = mastershipService.getLocalRole(device.id()) == MASTER; if (!isMaster) { - // reschedule timer - timeout = Timer.getTimer().newTimeout(this, this.probeRate, MILLISECONDS); + if (!isStopped()) { + // reschedule timer + timeout = Timer.getTimer().newTimeout(this, this.probeRate, MILLISECONDS); + } return; } @@ -280,16 +282,18 @@ public class LinkDiscovery implements TimerTask { } } - // reschedule timer - timeout = Timer.getTimer().newTimeout(this, this.probeRate, MILLISECONDS); + if (!isStopped()) { + // reschedule timer + timeout = Timer.getTimer().newTimeout(this, this.probeRate, MILLISECONDS); + } } - public void stop() { + public synchronized void stop() { timeout.cancel(); isStopped = true; } - public void start() { + public synchronized void start() { if (isStopped) { timeout = Timer.getTimer().newTimeout(this, 0, MILLISECONDS); isStopped = false; diff --git a/web/gui/src/main/webapp/index2.html b/web/gui/src/main/webapp/index2.html index 703a2402a5..1ddc3183f9 100644 --- a/web/gui/src/main/webapp/index2.html +++ b/web/gui/src/main/webapp/index2.html @@ -71,6 +71,7 @@ var ONOS = $.onos({ comment: "configuration options", startVid: 'topo', +// startVid: 'sampleKeys', trace: false }); @@ -82,6 +83,7 @@ + diff --git a/web/gui/src/main/webapp/network.js b/web/gui/src/main/webapp/network.js index b249c09654..01e4acdeff 100644 --- a/web/gui/src/main/webapp/network.js +++ b/web/gui/src/main/webapp/network.js @@ -28,7 +28,7 @@ // configuration data var config = { - useLiveData: true, + useLiveData: false, debugOn: false, debug: { showNodeXY: false, diff --git a/web/gui/src/main/webapp/onos2.js b/web/gui/src/main/webapp/onos2.js index 6353a6e105..f509757068 100644 --- a/web/gui/src/main/webapp/onos2.js +++ b/web/gui/src/main/webapp/onos2.js @@ -49,13 +49,40 @@ ctx: '' }, built = false, - errorCount = 0; + errorCount = 0, + keyHandler = {}; // DOM elements etc. var $view, $mastRadio; + function whatKey(code) { + switch (code) { + case 13: return 'enter'; + case 16: return 'shift'; + case 17: return 'ctrl'; + case 18: return 'alt'; + case 27: return 'esc'; + case 32: return 'space'; + case 37: return 'leftArrow'; + case 38: return 'upArrow'; + case 39: return 'rightArrow'; + case 40: return 'downArrow'; + case 91: return 'cmdLeft'; + case 93: return 'cmdRight'; + default: + if ((code >= 48 && code <= 57) || + (code >= 65 && code <= 90)) { + return String.fromCharCode(code); + } else if (code >= 112 && code <= 123) { + return 'F' + (code - 111); + } + return '.'; + } + } + + // .......................................................... // Internal functions @@ -206,9 +233,11 @@ // the incoming view, then unload it... if (current.view && (current.view.vid !== view.vid)) { current.view.unload(); - // detach radio buttons, if they were there.. - $('#mastRadio').children().detach(); + // detach radio buttons, key handlers, etc. + $('#mastRadio').children().detach(); + keyHandler.fn = null; + keyHandler.map = {}; } // cache new view and context @@ -283,6 +312,27 @@ $mastRadio.node().appendChild(btnG.node()); } + function setKeyBindings(keyArg) { + if ($.isFunction(keyArg)) { + // set general key handler callback + keyHandler.fn = keyArg; + } else { + // set specific key filter map + keyHandler.map = keyArg; + } + } + + function keyIn() { + var event = d3.event, + keyCode = event.keyCode, + key = whatKey(keyCode), + cb = isF(keyHandler.map[key]) || isF(keyHandler.fn); + + if (cb) { + cb(current.view.token(), key, keyCode, event); + } + } + function resize(e) { d3.selectAll('.onosView').call(setViewDimensions); // allow current view to react to resize event... @@ -320,7 +370,6 @@ this.radioButtons = null; // no radio buttons yet this.ok = true; // valid view } - } function validateViewArgs(vid) { @@ -348,7 +397,8 @@ width: this.width, height: this.height, uid: this.uid, - setRadio: this.setRadio + setRadio: this.setRadio, + setKeys: this.setKeys } }, @@ -433,6 +483,10 @@ setRadioButtons(this.vid, btnSet, cb); }, + setKeys: function (keyArg) { + setKeyBindings(keyArg); + }, + uid: function (id) { return uid(this, id); } @@ -536,6 +590,8 @@ $(window).on('hashchange', hash); $(window).on('resize', resize); + d3.select('body').on('keydown', keyIn); + // Invoke hashchange callback to navigate to content // indicated by the window location hash. hash(); @@ -544,7 +600,6 @@ reportBuildErrors(); } - // export the api and build-UI function return { ui: uiApi, diff --git a/web/gui/src/main/webapp/sampleKeys.js b/web/gui/src/main/webapp/sampleKeys.js new file mode 100644 index 0000000000..350f46e422 --- /dev/null +++ b/web/gui/src/main/webapp/sampleKeys.js @@ -0,0 +1,90 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * 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. + */ + +/* + Sample view to illustrate key bindings. + + @author Simon Hunt + */ + +(function (onos) { + 'use strict'; + + var keyDispatch = { + Z: keyUndo, + X: keyCut, + C: keyCopy, + V: keyPaste, + space: keySpace + }; + + function keyUndo(view) { + note(view, 'Z = UNDO'); + } + + function keyCut(view) { + note(view, 'X = CUT'); + } + + function keyCopy(view) { + note(view, 'C = COPY'); + } + + function keyPaste(view) { + note(view, 'V = PASTE'); + } + + function keySpace(view) { + note(view, 'The SpaceBar'); + } + + function note(view, msg) { + view.$div.append('p') + .text(msg) + .style({ + 'font-size': '10pt', + color: 'darkorange', + padding: '0 20px', + margin: 0 + }); + } + + function keyCallback(view, key, keyCode, event) { + note(view, 'Key = ' + key + ' KeyCode = ' + keyCode); + } + + // Keys using a keyset to target specific keys only + function load(view, ctx) { + // this maps specific keys to specific functions (1) + view.setKeys(keyDispatch); + // whereas, this installs a general key handler function (2) + view.setKeys(keyCallback); + + // Note that (1) takes precedence over (2) + + view.$div.append('p') + .text('Press a key or two (try Z,X,C,V and others) ...') + .style('padding', '2px 8px'); + } + + // == register the view here, with links to lifecycle callbacks + + onos.ui.addView('sampleKeys', { + reset: true, // empty the div on reset + load: load + }); + +}(ONOS));