+ @Override
+ public void flowRemoved(Node node, Flow flow) {
+ log.trace("Received flow removed notification on {} for {}", node, flow);
+ // For flow entry identification, only match and priority matter
+ FlowEntry toFind = new FlowEntry("any", "any", flow, node);
+ FlowEntryInstall installedEntry = this.findMatch(toFind, false);
+ if (installedEntry == null) {
+ log.trace("Entry is not know to us");
+ return;
+ }
+
+ // Update Static flow status
+ for (Map.Entry<Integer, FlowConfig> entry : staticFlows.entrySet()) {
+ FlowConfig conf = entry.getValue();
+ if (conf.isByNameAndNodeIdEqual(installedEntry.getFlowName(), node)) {
+ // Update Configuration database
+ conf.toggleStatus();
+ break;
+ }
+ }
+ // Update software views
+ this.updateLocalDatabase(installedEntry, false);
+ }
+
+ @Override
+ public synchronized void flowErrorReported(Node node, long rid, Object err) {
+ log.trace("Got error {} for message rid {} from node {}",
+ new Object[] {err, rid, node });
+ /*
+ * If this was for a flow install, remove the corresponding entry
+ * from the software view. If it was a Looking for the rid going through the
+ * software database.
+ * TODO: A more efficient rid <-> FlowEntryInstall mapping will
+ * have to be added in future
+ */
+ Set<FlowEntryInstall> entries = nodeFlows.get(node);
+ if (entries != null) {
+ FlowEntryInstall target = null;
+ for (FlowEntryInstall entry : entries) {
+ if (entry.getRequestId() == rid) {
+ target = entry;
+ break;
+ }
+ }
+ if (target != null) {
+ // This was a flow install, update database
+ this.updateLocalDatabase(target, false);
+ }
+ }
+
+ // Notify listeners
+ if (frmAware != null) {
+ synchronized (frmAware) {
+ for (IForwardingRulesManagerAware frma : frmAware) {
+ try {
+ frma.requestFailed(rid, err.toString());
+ } catch (Exception e) {
+ log.warn("Failed to notify {}", frma);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public Status solicitStatusResponse(Node node, boolean blocking) {
+ Status rv = new Status(StatusCode.INTERNALERROR);
+
+ if (this.programmer != null) {
+ if (blocking) {
+ rv = programmer.syncSendBarrierMessage(node);
+ } else {
+ rv = programmer.asyncSendBarrierMessage(node);
+ }
+ }
+
+ return rv;
+ }