Пример #1
0
def to_p2p_service(reservation: model.Reservation) -> PointToPointService:
    """Create Protobuf ``PointToPointService`` out of DB stored reservation data.

    See Also: warning in :func:`to_header`

    Args:
        reservation: DB Model

    Returns:
        A ``PointToPointService`` object.
    """
    pb_ptps = PointToPointService()
    pb_ptps.capacity = reservation.bandwidth
    pb_ptps.symmetric_path = reservation.symmetric
    pb_ptps.source_stp = str(reservation.src_stp(selected=True))
    pb_ptps.dest_stp = str(reservation.dst_stp(selected=True))
    # The initial version didn't have to support Explicit Routing Objects.
    for param in reservation.parameters:
        pb_ptps.parameters[param.key] = param.value
    return pb_ptps
Пример #2
0
def to_header(reservation: model.Reservation, *, add_path_segment: bool = False) -> Header:
    """Create Protobuf ``Header`` out of DB stored reservation data.

    .. warning::

        Using a DB model can be tricky.
        This function should either be called within a active SQLAlchemy session.
        Or it should be called with a :class:`~supa.db.model.Reservation` model
        that has been detached for a session.
        In case of the latter
        one should make sure that all relations have been eagerly loaded,
        as a detached model has no ability to load unload attributes.

        See also: https://docs.sqlalchemy.org/en/13/orm/session_state_management.html#session-object-states

    Args:
        reservation: DB model
        add_path_segment: Should we add our own Segment to the PathTrace?

    Returns:
        A Protobuf ``Header`` object.
    """
    pb_header = Header()
    pb_header.protocol_version = reservation.protocol_version
    pb_header.correlation_id = reservation.correlation_id.urn
    pb_header.requester_nsa = reservation.requester_nsa
    pb_header.provider_nsa = reservation.provider_nsa
    if reservation.reply_to is not None:
        pb_header.reply_to = reservation.reply_to
    if reservation.session_security_attributes:
        pb_header.session_security_attributes = reservation.session_security_attributes
    if reservation.path_trace:
        pb_header.path_trace.id = reservation.path_trace.path_trace_id
        pb_header.path_trace.connection_id = reservation.path_trace.ag_connection_id
        path: model.Path

        # A PathTrace can have multiple Paths according to its (WSDL) schema definition.
        # This has been has been carried over to the Protobuf definition.
        # However all examples in the specification always have only one Path!
        # Nor does the specification explain what multiple Paths even mean
        # or how we should deal with them.
        # With the specification inconclusive we have to make decision.
        # In case of multiple Path we will add our Segment to the last one!
        num_paths = len(reservation.path_trace.paths)
        for cur_path_num, path in enumerate(reservation.path_trace.paths, start=1):
            pb_path = pb_header.path_trace.paths.add()
            segment: model.Segment
            for segment in path.segments:
                pb_segment = pb_path.segments.add()
                pb_segment.id = segment.segment.id
                pb_segment.connection_id = segment.upa_connection_id
                stp: model.Stp
                for stp in segment.stps:
                    pb_segment.stps.append(stp.stp_id)
            if add_path_segment and cur_path_num == num_paths:
                pb_segment = Segment()
                pb_segment.id = settings.nsa_id
                pb_segment.connection_id = str(reservation.connection_id)
                pb_segment.stps.extend([reservation.src_stp(selected=True), reservation.dst_stp(selected=True)])
                pb_path.append(pb_segment)
    return pb_header