def negotiate_incoming_edge(self, edge_req):
        """ Role B1 """
        self._top.log("LOG_DEBUG", "Rcvd EdgeRequest=%s", str(edge_req))
        edge_resp = None
        peer_id = edge_req.initiator_id
        if peer_id in self._current_adj_list:
            edge_resp = self._resolve_request_collision(edge_req)
        elif edge_req.edge_type == "CETypeSuccessor":
            edge_resp = EdgeResponse(is_accepted=True,
                                     data="Successor edge permitted")
        elif edge_req.edge_type == "CETypeEnforced":
            edge_resp = EdgeResponse(is_accepted=True,
                                     data="Enforced edge permitted")
        elif edge_req.edge_type == "CETypeOnDemand":
            edge_resp = EdgeResponse(is_accepted=True,
                                     data="On-demand edge permitted")
        elif not self._current_adj_list.is_threshold_ildl():
            edge_resp = EdgeResponse(is_accepted=True,
                                     data="Any edge permitted")
        else:
            edge_resp = EdgeResponse(is_accepted=False,
                                     data="E5 - Too many existing edges.")

        if edge_resp.is_accepted and edge_resp.data[:2] != "E0":
            et = ng.transpose_edge_type(edge_req.edge_type)
            ce = ConnectionEdge(peer_id=peer_id,
                                edge_id=edge_req.edge_id,
                                edge_type=et)
            ce.edge_state = "CEStatePreAuth"
            self._negotiated_edges[peer_id] = ce
            self._top.log("LOG_DEBUG",
                          "New CE=%s added to negotiated_edges=%s", str(ce),
                          str(self._negotiated_edges))
        return edge_resp
 def on_connection_update(self, connection_event):
     """
     Updates the connection edge's current state based on the provided event. This is the
     completion for a create or remove connection request to Link Manager.
     """
     peer_id = connection_event["PeerId"]
     link_id = connection_event["LinkId"]
     overlay_id = connection_event["OverlayId"]
     with self._lock:
         if connection_event["UpdateType"] == "CREATING":
             conn_edge = self._current_adj_list.conn_edges.get(
                 peer_id, None)
             if not conn_edge:
                 # this happens when the neighboring peer initiates the connection bootstrap
                 self._refresh_in_progress += 1
                 conn_edge = ConnectionEdge(peer_id, "CETypePredecessor")
                 self._current_adj_list.conn_edges[peer_id] = conn_edge
             conn_edge.edge_state = "CEStateCreated"
             conn_edge.link_id = link_id
         elif connection_event["UpdateType"] == "REMOVED":
             self._current_adj_list.conn_edges.pop(peer_id, None)
             self._refresh_in_progress -= 1
         elif connection_event["UpdateType"] == "CONNECTED":
             self._current_adj_list.conn_edges[
                 peer_id].edge_state = "CEStateConnected"
             self._current_adj_list.conn_edges[peer_id].connected_time = \
                 connection_event["ConnectedTimestamp"]
             self._refresh_in_progress -= 1
         elif connection_event["UpdateType"] == "DISCONNECTED":
             # the local topology did not request removal of the connection
             self._top.top_log(
                 "CEStateDisconnected event recvd peer_id: {0}, link_id: {1}"
                 .format(peer_id, link_id))
             self._current_adj_list.conn_edges[
                 peer_id].edge_state = "CEStateDisconnected"
             self._refresh_in_progress += 1
             self._top.top_remove_edge(overlay_id, peer_id)
         elif connection_event["UpdateType"] == "RemoveEdgeFailed":
             # leave the node in the adj list and marked for removal to be retried.
             self._refresh_in_progress -= 1
         else:
             self._top.top_log(
                 "Logger", "LOG_WARNING",
                 "Invalid UpdateType specified for connection update")