def reserveAbort(self, header, connection_id): log.msg('ReserveAbort request from %s. Connection ID: %s' % (header.requester_nsa, connection_id), system=self.log_system) try: log.msg('ReserveAbort request. Connection ID: %s' % connection_id, system=self.log_system) conn = yield self._getConnection(connection_id, header.requester_nsa) if conn.lifecycle_state in (state.TERMINATING, state.TERMINATED): raise error.ConnectionGoneError( 'Connection %s has been terminated') yield self._doReserveRollback(conn) header = nsa.NSIHeader( conn.requester_nsa, conn.requester_nsa ) # The NSA is both requester and provider in the backend, but this might be problematic without aggregator self.parent_requester.reserveAbortConfirmed( header, conn.connection_id) except Exception, e: log.msg('Error in reserveAbort: %s: %s' % (type(e), e), system=self.log_system)
def reserveCommit(self, header, connection_id): log.msg('ReserveCommit request from %s. Connection ID: %s' % (header.requester_nsa, connection_id), system=self.log_system) conn = yield self._getConnection(connection_id, header.requester_nsa) if conn.lifecycle_state in (state.TERMINATING, state.TERMINATED): raise error.ConnectionGoneError( 'Connection %s has been terminated') # the switch to reserve start and allocated must be in same transaction state.reserveMultiSwitch(conn, state.RESERVE_COMMITTING, state.RESERVE_START) conn.allocated = True yield conn.save() self.logStateUpdate(conn, 'COMMIT/RESERVED') # cancel abort and schedule end time call self.scheduler.cancelCall(connection_id) self.scheduler.scheduleCall(conn.connection_id, conn.end_time, self._doEndtime, conn) td = conn.end_time - datetime.datetime.utcnow() log.msg( 'Connection %s: End and teardown scheduled for %s UTC (%i seconds)' % (conn.connection_id, conn.end_time.replace(microsecond=0), td.total_seconds()), system=self.log_system) yield self.parent_requester.reserveCommitConfirmed( header, connection_id) defer.returnValue(connection_id)
def provision(self, header, connection_id, request_info=None): log.msg('Provision request from %s. Connection ID: %s' % (header.requester_nsa, connection_id), system=self.log_system) conn = yield self._getConnection(connection_id, header.requester_nsa) self._authorize(conn.source_port, conn.dest_port, header, request_info) if not conn.allocated: raise error.ConnectionError( 'No resource allocated to the connection, cannot provision') if conn.lifecycle_state in (state.TERMINATING, state.TERMINATED): raise error.ConnectionGoneError( 'Connection %s has been terminated') if conn.reservation_state != state.RESERVE_START: raise error.InvalidTransitionError( 'Cannot provision connection in a non-reserved state') now = datetime.datetime.utcnow() if conn.end_time is not None and conn.end_time <= now: raise error.ConnectionGoneError( 'Cannot provision connection after end time (end time: %s, current time: %s).' % (conn.end_time, now)) yield state.provisioning(conn) self.logStateUpdate(conn, 'PROVISIONING') self.scheduler.cancelCall(connection_id) if conn.start_time is None or conn.start_time <= now: self._doActivate(conn) # returns a deferred, but it isn't used else: self.scheduler.scheduleCall(connection_id, conn.start_time, self._doActivate, conn) td = conn.start_time - now log.msg('Connection %s: activate scheduled for %s UTC (%i seconds) (provision)' % \ (conn.connection_id, conn.start_time.replace(microsecond=0), td.total_seconds()), system=self.log_system) yield state.provisioned(conn) self.logStateUpdate(conn, 'PROVISIONED') self.parent_requester.provisionConfirmed(header, connection_id) defer.returnValue(conn.connection_id)
def reserveAbort(self, header, connection_id, request_info=None): log.msg('ReserveAbort request from %s. Connection ID: %s' % (header.requester_nsa, connection_id), system=self.log_system) conn = yield self._getConnection(connection_id, header.requester_nsa) self._authorize(conn.source_port, conn.dest_port, header, request_info) if conn.lifecycle_state in (state.TERMINATING, state.TERMINATED): raise error.ConnectionGoneError( 'Connection %s has been terminated') yield self._doReserveRollback(conn) header = nsa.NSIHeader( conn.requester_nsa, conn.requester_nsa ) # The NSA is both requester and provider in the backend, but this might be problematic without aggregator self.parent_requester.reserveAbortConfirmed(header, conn.connection_id)
def release(self, header, connection_id): log.msg('Release request from %s. Connection ID: %s' % (header.requester_nsa, connection_id), system=self.log_system) try: conn = yield self._getConnection(connection_id, header.requester_nsa) if conn.lifecycle_state in (state.TERMINATING, state.TERMINATED): raise error.ConnectionGoneError( 'Connection %s has been terminated') yield state.releasing(conn) self.logStateUpdate(conn, 'RELEASING') self.scheduler.cancelCall(connection_id) if conn.data_plane_active: try: yield self._doTeardown(conn) # we don't have to block here except Exception as e: log.msg('Connection %s: Error tearing down link: %s' % (conn.connection_id, e)) self.scheduler.scheduleCall(connection_id, conn.end_time, self._doEndtime, conn) td = conn.start_time - datetime.datetime.utcnow() log.msg( 'Connection %s: terminating scheduled for %s UTC (%i seconds)' % (conn.connection_id, conn.end_time.replace(microsecond=0), td.total_seconds()), system=self.log_system) yield state.released(conn) self.logStateUpdate(conn, 'RELEASED') self.parent_requester.releaseConfirmed(header, connection_id) defer.returnValue(conn.connection_id) except Exception, e: log.msg('Error in release: %s: %s' % (type(e), e), system=self.log_system)