RFC 7878

Session Peering Provisioning (SPP) Protocol over SOAP

πŸ“… published August 2016, from ietf

RFC 7878: Session Peering Provisioning (SPP) Protocol over SOAP ✨

Part 1 of 13. More coming, bestie πŸ’–

Okay so this one is an Internet Standards Track document πŸŽ€, published in August 2016 and given the number RFC 7878. It's part of the IETF's stream of official Internet standards, and it's tagged with ISSN 2070-1721. The authors are K. Cartwright and V. Bhatia (both from TNS), J-F. Mule (from Apple Inc.), and A. Mayrhofer (from nic.at GmbH). The title block doesn't list any RFC that this one obsoletes or updates, so it's standing on its own πŸ¦‹.

Abstract ✨

Okay, so the Session Peering Provisioning Framework (SPPF) πŸ’… is the one that lays out the data model and the overall structure for provisioning Session Establishment Data (SED) into Session Data Registries and SIP Service Provider data stores. To actually use SPPF you need a substrate protocol, and since the Simple Object Access Protocol (SOAP) is already super popular for messaging between the parts of provisioning systems, this doc says SOAP (via HTTPS) is the substrate for SPPF 🫢. The payoff is that people can leverage the expertise they already have, and existing provisioning systems have a much better shot at migrating easily to an SPPF-based protocol 🌈.

Status of This Memo

This is an Internet Standards Track document.

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 7841.

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc7878. πŸ”—βœ¨

Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved. 🌸

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. πŸ’œ

Table of Contents 🧚

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   4
3.  SOAP Features and Protocol Layering . . . . . . . . . . . . .   4
4.  HTTP(S) Features and SPPP over SOAP . . . . . . . . . . . . .   7
5.  Authentication, Integrity, and Confidentiality  . . . . . . .   7
6.  Language Identification . . . . . . . . . . . . . . . . . . .   7
7.  SPPP SOAP Data Structures . . . . . . . . . . . . . . . . . .   7
  7.1.  Concrete Object Key Types . . . . . . . . . . . . . . . .   8
    7.1.1.  Generic Object Key  . . . . . . . . . . . . . . . . .   8
    7.1.2.  Public Identifier Object Key  . . . . . . . . . . . .   9
    7.1.3.  SED Group Offer Key . . . . . . . . . . . . . . . . .  10
  7.2.  Operation Request and Response Structures . . . . . . . .  10
    7.2.1.  Add Operation Structure . . . . . . . . . . . . . . .  10
    7.2.2.  Delete Operation Structure  . . . . . . . . . . . . .  13
    7.2.3.  Accept Operation Structure  . . . . . . . . . . . . .  16
    7.2.4.  Reject Operation Structure  . . . . . . . . . . . . .  19
    7.2.5.  Batch Operation Structure . . . . . . . . . . . . . .  22
    7.2.6.  Get Operation Structure . . . . . . . . . . . . . . .  25
    7.2.7.  Get SED Group Offers Operation Structure  . . . . . .  26
    7.2.8.  Generic Query Response  . . . . . . . . . . . . . . .  28
    7.2.9.  Get Server Details Operation Structure  . . . . . . .  29
  7.3.  Response Codes and Messages . . . . . . . . . . . . . . .  30
  7.4.  Minor Version Identifier  . . . . . . . . . . . . . . . .  32
8.  Protocol Operations . . . . . . . . . . . . . . . . . . . . .  32
9.  SPPP over SOAP WSDL Definition  . . . . . . . . . . . . . . .  32
10. SPPP over SOAP Examples . . . . . . . . . . . . . . . . . . .  44
  10.1.  Add Destination Group  . . . . . . . . . . . . . . . . .  44
  10.2.  Add SED Records  . . . . . . . . . . . . . . . . . . . .  46
  10.3.  Add SED Records -- URIType . . . . . . . . . . . . . . .  47
  10.4.  Add SED Group  . . . . . . . . . . . . . . . . . . . . .  49
  10.5.  Add Public Identifier -- Successful COR Claim  . . . . .  50
  10.6.  Add LRN  . . . . . . . . . . . . . . . . . . . . . . . .  52
  10.7.  Add TN Range . . . . . . . . . . . . . . . . . . . . . .  53
  10.8.  Add TN Prefix  . . . . . . . . . . . . . . . . . . . . .  54
  10.9.  Enable Peering -- SED Group Offer  . . . . . . . . . . .  56
  10.10. Enable Peering -- SED Group Offer Accept . . . . . . . .  58
  10.11. Add Egress Route . . . . . . . . . . . . . . . . . . . .  60
  10.12. Remove Peering -- SED Group Offer Reject . . . . . . . .  61
  10.13. Get Destination Group  . . . . . . . . . . . . . . . . .  62
  10.14. Get Public Identifier  . . . . . . . . . . . . . . . . .  64
  10.15. Get SED Group Request  . . . . . . . . . . . . . . . . .  66
  10.16. Get SED Group Offers Request . . . . . . . . . . . . . .  68
  10.17. Get Egress Route . . . . . . . . . . . . . . . . . . . .  70
  10.18. Delete Destination Group . . . . . . . . . . . . . . . .  72
  10.19. Delete Public Identifier . . . . . . . . . . . . . . . .  73
  10.20. Delete SED Group Request . . . . . . . . . . . . . . . .  74
  10.21. Delete SED Group Offers Request  . . . . . . . . . . . .  75
  10.22. Delete Egress Route  . . . . . . . . . . . . . . . . . .  76
  10.23. Batch Request  . . . . . . . . . . . . . . . . . . . . .  77
11. Security Considerations . . . . . . . . . . . . . . . . . . .  80
  11.1.  Vulnerabilities  . . . . . . . . . . . . . . . . . . . .  80
12. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  81
13. References  . . . . . . . . . . . . . . . . . . . . . . . . .  81
  13.1.  Normative References . . . . . . . . . . . . . . . . . .  81
  13.2.  Informative References . . . . . . . . . . . . . . . . .  82
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  82
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  83

1. Introduction

Okay so SPPF, which is defined in [RFC7877], works best with a transport and messaging setup that is connection oriented, request-response oriented, easily secured, supports propagation through firewalls in a standard fashion, and is easily integrated into back-office systems 🧠. Why? Because the client side of SPPF will probably be plugged into an organization's operational support systems, which handle transactional provisioning of user addresses and their associated SED πŸ’Ό. The server side is likely to live in a different organization's network 🌍, which means SPPF provisioning transactions travel across the Internet as they get propagated from the SPPF client to the SPPF server. Given where industry practice and technology are right now, SOAP and HTTP(S) are a really good fit for this kind of environment πŸ’…. This document describes how to transport SPPF XML structures using SOAP and HTTP(S) as substrates ✨.

The specification in this document is mainly made up of five subjects πŸŽ€: (1) a description of any applicable SOAP features, (2) any applicable HTTP features, (3) security considerations, (4) (perhaps most importantly) the Web Services Description Language (WSDL) definition for the SPP Protocol over SOAP, and (5) XML Schema Definition (XSD) types that are "substrate" specific πŸ‘‘.

2. Terminology

Here's the key word squad 🫢: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL". In this document, those words are to be interpreted as described in [RFC2119] πŸ“–πŸ’–.


3. SOAP Features and Protocol Layering ✨

okay bestie, so this is where SPPP over SOAP gets its layered structure πŸŽ€ and honestly? The list of SOAP features it actually needs is super short. Most SOAP features are not necessary for SPPF πŸ’… SPPP over SOAP mostly just uses SOAP as a standard message-envelope technology, no cap. The SOAP message envelope is made of the SOAP header and body πŸ¦‹ As the SOAP specification [SOAPREF] explains, the SOAP header can hold optional, application-specific information about the message. The SOAP body carries the SPPF message itself 🌸 Its structure comes from one of the WSDL operations defined in this document, plus the SPPF XML data structures defined in this document and the SPPF document. SPPF does not rely on any data elements in the SOAP header ✨ All the relevant data elements live in the SPPF XML Schema described in [RFC7877] and the SPPF WSDL types specification described in Section 9 of this document.

WSDL is a widely standardized, widely adopted technology for defining the top-level structures of messages carried inside the body of a SOAP message πŸ’– The WSDL definition for SPPF SOAP messages comes later in this document, and it imports by reference the XML data types from the SPPF schema. The IANA registry where the SPPF schema lives is described in "The IETF XML Registry" [RFC3688] 🧚

There are multiple structural styles WSDL allows πŸ“ The best practice for this kind of app is what people sometimes call the "document/literal wrapped style". It's generally seen as an optimal approach that boosts maintainability, comprehension, portability, and, to a certain extent, performance πŸ‘‘ You set the soapAction binding style to "document", the soapAction encoding style to "literal", and then each SOAP message just contains a single data element that "wraps" a data structure holding all the required input or output data elements. The figure below shows this high-level structure as conceptual layers 3 through 6 🌈

                             +-------------+
                         (1) |  Transport  |Example:
                             |  Protocol   |  TCP, TLS, BEEP, etc.
                             +-------------+
                                    |
                                    V
                             +-------------+
                         (2) |   Message   |Example:
                             |   Envelope  | HTTP, SOAP, None, etc.
                             +-------------+
                                    |
                                    V
                            +--------------+
                       +----|    SOAP      |---+
                       |(3) |  Operation   |   |
              Contains |    +--------------+   | Contains
                       |        Example:       |
                       V      submitAddRqst    V
              +--------------+           +-------------+
              | SOAP Request |           |SOAP Response|
   Example:   |   Message    |  (4)      |   Message   | Example:
   spppAdd    |  (Operation  |           |  (Operation | spppAdd
   RequestMsg |   Input)     |           |   Output)   | ResponseMsg
              +--------------+           +-------------+
                       |                       |
              Contains |                       | Contains
                       |                       |
                       V                       V
              +--------------+          +---------------+
   Example:   |   Wrapped    |  (5)     |    Wrapped    | Example:
   spppAdd    |Request Object|          |Response Object| spppAdd
   Request    +--------------+          +---------------+ Response
                       |                       |
              Contains |                       | Contains
                       |                       |
                       V                       V
              +--------------+          +---------------+
              |    SPPF      |          |     SPPF      |
              |  XML Types   |  (6)     |   XML Types   |
              +--------------+          +---------------+

Legend:

BEEP = Blocks Extensible Exchange Protocol
TLS = Transport Layer Security

Figure 1: Layering and Technical Structure of SPPP over SOAP Messages

The operations SPPP over SOAP supports are normatively defined later in this document πŸ”₯ Each SOAP operation defines a request/input message and a response/output message. Each request and response message then contains a single object that wraps the SPPF XML data types that make up the inputs and outputs, respectively, of the SOAP operation.

SOAP faults are not used by SPPP over SOAP πŸ™ˆ All success and error responses are specified in Section 7.3 of this document. However, if a SOAP fault were to occur, perhaps because of failures in the SOAP message handling layer of a SOAP library, the client application SHOULD capture and handle the fault.

Heads up: the original says the client application "should" capture and handle the fault, and it's lowercase there, so it's not a requirement keyword. I've kept it lowercase so nobody thinks I upgraded it. πŸ’€

Specifics on how to handle such SOAP faults, if they should occur, will be specific to the chosen SOAP implementation πŸ’œ

Implementations MUST use SOAP 1.2 [SOAPREF] or higher and MUST support SOAP 1.2. Implementations SHOULD use WSDL 1.1 [WSDLREF] and MUST NOT use earlier versions. Use of WSDL versions greater than 1.1 may introduce interoperability problems with implementations that use 1.1 😭

SPPF is a request/reply framework that lets a client application submit provisioning data and query requests to a server ✨ The SPPF data structures are designed to be protocol agnostic πŸ¦‹ Concerns about encryption, non-repudiation, and authentication are beyond the scope of this document. For more details, please refer to Section 4 ("Transport Substrate Protocol Requirements") of [RFC7877] 🫢

As the previous diagram showed, SPPF can be viewed as a set of layers that together define the structure of an SPPF request and response 🌸 Layers 1 and 2 cover the transport, envelope, and authentication technologies. This document defines layers 3, 4, 5, and 6 for SPPP over SOAP πŸ’…

  1. Layer 1: The transport protocol layer represents the communication mechanism between the client and server. SPPF can be layered over any substrate protocol that provides a set of basic requirements defined in Section 4 of [RFC7877].
  2. Layer 2: The message-envelope layer is optional, but it can provide features that sit above the transport layer and below the application messaging layer. Technologies such as HTTP and SOAP are examples of message-envelope technologies.
  3. Layers 3, 4, 5, and 6: The operation and message layers provide an envelope-independent and substrate-independent wrapper for the SPPF data model objects that are being acted on (created, modified, and queried) πŸ‘‘

4. HTTP(S) Features and SPPP over SOAP 🌈

While SOAP is not tied to HTTP(S), for reasons described in the Introduction, HTTP(S) is a good choice as the substrate protocol for SPP Protocol SOAP messages πŸ“ HTTP 1.1 includes the "persistent connection" feature, which lets multiple HTTP request/response pairs travel across a single HTTP connection. This is a seriously important performance optimization, especially when the connection is HTTPS, where the relatively time-consuming TLS handshake has already happened πŸ”₯

Implementations compliant with this document MUST use HTTP 1.1 [RFC7230] or higher. Also, implementations SHOULD use persistent connections πŸ’–

5. Authentication, Integrity, and Confidentiality πŸ”

To accomplish authentication, conforming SPPP over SOAP clients and servers MUST use HTTP Digest Authentication as defined in [RFC7235] 🧚

To achieve integrity and privacy, conforming SPPP over SOAP clients and servers MUST support TLS as defined in [RFC5246] as the secure transport mechanism. Use of TLS MUST follow the recommendations contained in [RFC7525] πŸ‘‘

6. Language Identification 🌸

Section 9 of [RFC7877] requires protocols to provide a mechanism to transmit language tags together with human-readable messages πŸ¦‹ When conforming SPPP SOAP servers use such tagging, the XML "lang" attribute ([W3C.REC-xml-20081126], Section 2.12) MUST be used. Clients MAY use the HTTP "Accept-Language" header field (see Section 5.3.5 of [RFC7231]) in order to indicate their language preference πŸ’…

7. SPPP SOAP Data Structures πŸ’–

SPPP over SOAP uses a set of XML-based data structures for all the supported operations and any parameters those operations are applied to ✨ As mentioned earlier in this document, these XML structures are envelope independent and substrate independent. Refer to "Protocol Operations" (Section 8) of this document for a description of all the operations that MUST be supported 🫢

The following sections describe the definitions of all the XML data structures πŸŽ€

7.1. Concrete Object Key Types πŸ”‘

Certain operations in SPPF require an object key that uniquely identifies the object(s) an operation needs to be performed on πŸ¦‹ SPPF defines the XML structure of any such object key in an abstract manner and delegates the concrete representation to any conforming substrate protocol. The following subsections define the various concrete object key types used in various operations in SPPP over SOAP 🧚

7.1.1. Generic Object Key πŸ“

Most objects in SPPP over SOAP are uniquely identified by the attributes in the generic object key (Refer to "Generic Object Key Type", Section 5.2.1 of [RFC7877], for details). The concrete XML representation of ObjKeyType is as below 🌈

   <complexType name="ObjKeyType">
    <complexContent>
     <extension base="sppfb:ObjKeyType">
      <sequence>
       <element name="rant" type="sppfb:OrgIdType"/>
       <element name="name" type="sppfb:ObjNameType"/>
       <element name="type" type="sppfs:ObjKeyTypeEnum"/>
      </sequence>
     </extension>
    </complexContent>
   </complexType>

The ObjKeyType has the data elements described below πŸ‘‘

  • rant: The identifier of the Registrant organization that owns the object.
  • name: The character string that contains the name of the object.
  • type: The enumeration value that represents the type of SPPF object. For example, both a Destination Group and a SED Group can have the same name "TestObj" and be associated with the same Registrant ID. Hence, to uniquely identify the object that represents a Destination Group with the name "TestObj", the type "DestGrp" MUST be specified when using this concrete ObjKeyType structure to identify the Destination Group "TestObj" πŸ’…

The object types in SPPP over SOAP MUST adhere to the above definition of generic object key and are defined as an enumeration in the XML data structure as follows πŸ”₯

    <simpleType name="ObjKeyTypeEnum">
      <restriction base="token">
        <enumeration value="SedGrp"/>
        <enumeration value="DestGrp"/>
        <enumeration value="SedRec"/>
        <enumeration value="EgrRte"/>
      </restriction>
    </simpleType>

7.1.2. Public Identifier Object Key ✨

okay so Public Identifier objects are lowkey the most main-character objects in the whole registry πŸ’… they can be a Telephone Number (TN), a Routing Number (RN), a TN Prefix, a URI, or a TN Range, and they can't be cleanly identified with just the attributes from the generic ObjKeyType πŸ™ˆ so we need PubIdKeyType to handle them. Here's the definition:

<complexType name="PubIdKeyType">
 <complexContent>
  <extension base="sppfb:PubIdKeyType">
   <sequence>
    <element name="rant" type="sppfb:OrgIdType"/>
    <choice>
     <element name="number"
     type="sppfb:NumberType"/>
     <element name="range"
      type="sppfb:NumberRangeType"/>
     <element name="uri"
      type="anyURI"/>
    </choice>
   </sequence>
  </extension>
 </complexContent>
</complexType>

PubIdKeyType has these data elements πŸ¦‹

  • rant: The identifier of the Registrant organization that owns the object.
  • number: An element of type NumberType (refer to Section 12 of [RFC7877]) that contains the value and type of a number.
  • range: An element of type NumberRangeType (refer to Section 12 of [RFC7877]) that contains a range of numbers.
  • uri: A value that represents a Public Identifier.

Any instance of PubIdKeyType MUST contain exactly one element from the following set of elements: "number", "range", "uri". no cap, that MUST is doing the heavy lifting here πŸ’œ

7.1.3. SED Group Offer Key πŸŽ€

on top of the generic ObjKeyType attributes, a SED Group Offer object is uniquely identified by the organization ID of the org it was offered to 🌸 the definition of SedGrpOfferKeyType looks like this:

<complexType name="SedGrpOfferKeyType">
 <complexContent>
  <extension base="sppfb:SedGrpOfferKeyType">
   <sequence>
    <element name="sedGrpKey" type="sppfs:ObjKeyType"/>
    <element name="offeredTo" type="sppfb:OrgIdType"/>
   </sequence>
  </extension>
 </complexContent>
</complexType>

SedGrpOfferKeyType has these data elements, as described below:

  • sedGrpKey: Identifies the SED Group that was offered.
  • offeredTo: The organization ID of the organization that was offered the SED Group object identified by the sedGrpKey.

7.2. Operation Request and Response Structures 🧚

an SPPF client talks to an SPPF server by sending one or more requests and getting the matching responses back πŸ’¬ the basic set of operations a client can submit, plus what those operations mean, is defined in "Framework Operations", Section 7 of [RFC7877]. the subsections below cover the XML data structures used for each type of operation in an SPPP over SOAP implementation ✨

7.2.1. Add Operation Structure πŸ’–

to add (or modify) an object in the Registry, an authorized entity can send the spppAddRequest to the Registry πŸ“

an SPPP over SOAP Add request gets wrapped in the <spppAddRequest> element, and an SPPP over SOAP Add response gets wrapped in an <spppAddResponse> element. the sub-sections below break down both elements. check out Section 10 for an example of an Add operation on each type of SPPF object 🌈

7.2.1.1. Add Request

an SPPP over SOAP Add request definition lives inside the generic <spppAddRequest> element πŸ’…

<element name="spppAddRequest">
 <complexType>
  <sequence>
   <element name="clientTransId"
    type="sppfb:TransIdType" minOccurs="0"/>
   <element name="minorVer"
    type="sppfb:MinorVerType" minOccurs="0"/>
   <element name="obj" type="sppfb:BasicObjType"
   maxOccurs="unbounded"/>
  </sequence>
 </complexType>
</element>

here's what the data elements inside <spppAddRequest> do 🫢

  • clientTransId: Zero or one client-generated transaction ID that, within the context of the SPPF client, identifies this request. This value can be used at the discretion of the SPPF client to track, log, or correlate requests and their responses. The SPPF server MUST echo back this value to the client in the corresponding response to the incoming request. The SPPF server will not check this value for uniqueness. πŸ‘€
  • minorVer: Zero or one minor version identifier, as defined in Section 7.4.
  • obj: One or more elements of abstract type BasicObjType (defined in [RFC7877]). Each element contains all the attributes of an SPPF object that the client is requesting the SPPF server to add. Refer to Section 3.1 of [RFC7877] for the XML structure of all concrete types, for various SPPF objects, that extend from abstract BasicObjType and hence are eligible to be passed into this element. The elements are processed by the SPPF server in the order in which they are included in the request. With respect to the handling of error conditions, conforming SPPP SOAP servers MUST stop processing BasicObjType elements in the request at the first error and roll back any BasicObjType elements that had already been processed for that add request ("stop and roll back"). 😭 the "stop and roll back" rule is non-negotiable, bestie

7.2.1.2. Add Response

an SPPP over SOAP add response object is wrapped in the generic <spppAddResponse> element. this response structure is used for every type of SPPF object the SPPF client provisions πŸŽ€

<element name="spppAddResponse">
  <complexType>
    <sequence>
      <element name="clientTransId" type="sppfb:TransIdType"
       minOccurs="0"/>
      <element name="serverTransId" type="sppfb:TransIdType"/>
      <element name="overallResult" type="sppfs:ResultCodeType"/>
      <element name="detailResult" type="sppfs:ObjResultCodeType"
      minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
  </complexType>
</element>

<complexType name="ResultCodeType">
  <sequence>
     <element name="code" type="int"/>
     <element name="msg" type="string"/>
  </sequence>
</complexType>

 <complexType name="ObjResultCodeType">
  <complexContent>
   <extension base="sppfs:ResultCodeType">
    <sequence>
     <element name="obj" type="sppfb:BasicObjType"/>
    </sequence>
   </extension>
  </complexContent>
 </complexType>

an <spppAddResponse> has everything the SPPF client needs to pin down the overall result of the request. if something goes wrong, it also tells you which specific object(s) caused the error πŸ•΅οΈβ€β™€οΈ

the data elements in the SPPP over SOAP Add response work like this 🌸

  • clientTransId: Zero or one client transaction ID. this is just an echo of the client transaction ID the SPPF client passed into the SPPF update request. When it was included in the request, the SPPF server MUST return it in the corresponding response message. 🫢
  • serverTransId: Exactly one server transaction ID that identifies this request for tracking purposes. This value MUST be unique for a given SPPF server. πŸ”₯
  • overallResult: Exactly one response code and message pair that explicitly identifies the result of the request. See Section 7.3 for further details.
  • detailResult: An optional response code, response message, and BasicObjType (as defined in [RFC7877]) triplet. This element will be present only if an object-level error has occurred. It indicates the error condition and the exact request object that contributed to the error. The response code will reflect the exact error. See Section 7.3 for further details. πŸ’€ this one only shows up when a single object went wrong, so it's giving very targeted drama

7.2.2. Delete Operation Structure πŸ¦‹

to remove an object from the Registry, an authorized entity can send the spppDelRequest into the Registry πŸ’œ an SPPP over SOAP Delete request gets wrapped in the <spppDelRequest> element, and an SPPP over SOAP Delete response gets wrapped in the generic <spppDelResponse> element. the subsections below describe both elements. check Section 10 for an example of the Delete operation on each type of SPPF object ✨

7.2.2.1. Delete Request

an SPPP over SOAP Delete request definition lives inside the generic <spppDelRequest> element 🌈

<element name="spppDelRequest">
 <complexType>
  <sequence>
   <element name="clientTransId"
   type="sppfb:TransIdType" minOccurs="0"/>
   <element name="minorVer"
   type="sppfb:MinorVerType" minOccurs="0"/>
  <element name="objKey" type="sppfb:ObjKeyType"
   maxOccurs="unbounded"/>
  </sequence>
 </complexType>
</element>

here's what the data elements inside <spppDelRequest> do πŸ“

  • clientTransId: Zero or one client-generated transaction ID that, within the context of the SPPF client, identifies this request. This value can be used at the discretion of the SPPF client to track, log, or correlate requests and their responses. The SPPF server MUST echo back this value to the client in the corresponding response to the incoming request. SPPF server will not check this value for uniqueness. πŸ‘€
  • minorVer: Zero or one minor version identifier, as defined in Section 7.4.
  • objKey: One or more elements of abstract type ObjKeyType (as defined in [RFC7877]). Each element contains attributes that uniquely identify the object that the client is requesting the server to delete. Refer to Section 7.1 for a description of all concrete object key types, for various SPPF objects, which are eligible to be passed into this element. The elements are processed by the SPPF server in the order in which they are included in the request. With respect to the handling of error conditions, conforming SPPP SOAP servers MUST stop processing ObjKeyType elements in the request at the first error and roll back any ObjKeyType elements that had already been processed for that Delete request ("stop and roll back"). 😭 same energy as Add, the rollback rule still applies

7.2.2.2. Delete Response

okay so the Delete response lives inside the generic <sppDeleteResponse> element πŸ’… and it's used for a Delete request on every type of SPPF object the SPPF client provisions πŸŽ€

   <element name="spppDelResponse">
    <complexType>
     <sequence>
      <element name="clientTransId" type="sppfb:TransIdType"
               minOccurs="0"/>
      <element name="serverTransId" type="sppfb:TransIdType"/>
      <element name="overallResult" type="sppfs:ResultCodeType"/>
      <element name="detailResult" type="sppfs:ObjKeyResultCodeType"
               minOccurs="0" maxOccurs="unbounded"/>
     </sequence>
    </complexType>
   </element>

   <complexType name="ResultCodeType">
    <sequence>
     <element name="code" type="int"/>
     <element name="msg" type="string"/>
    </sequence>
   </complexType>

   <complexType name="ObjKeyResultCodeType">
    <complexContent>
     <extension base="sppfs:ResultCodeType">
      <sequence>
       <element name="objKey" type="sppfb:ObjKeyType"/>
      </sequence>
     </extension>
    </complexContent>
   </complexType>

An <spppDelResponse> has everything the SPPF client needs to know the overall result of the request πŸ”₯ and if something goes wrong, it also tells you exactly which object key(s) caused the mess πŸ™ˆ

Here's the breakdown of the data elements in an SPPP over SOAP Delete response:

  • clientTransId: zero or one client transaction ID 🫢 It's basically an echo of the one the SPPF client sent in the SPPF update request. If it was included in the request, the SPPF server MUST return it in the matching response message.
  • serverTransId: exactly one server transaction ID that tracks this request πŸ¦‹ This value MUST be unique for a given SPPF server.
  • overallResult: exactly one response code and message pair that clearly spells out the result of the request ✨ See Section 7.3 for the deets.
  • detailResult: an optional response code, response message, and ObjKeyType (as defined in [RFC7877]) triplet πŸŽ€ It only shows up if an object-key-level error happened, and it tells you the error plus the exact request object key that caused it. The response code reflects the exact error. See Section 7.3 for further details.

7.2.3. Accept Operation Structure

okay bestie, so in SPPF, a SED Group Offer can be accepted or rejected by (or on behalf of) the Registrant it was offered to πŸ’œ (check Section 3.1 of [RFC7877] for what a SED Group Offer object is). The Accept operation is how that acceptance happens 🌸

The request for an SPPP over SOAP Accept operation is wrapped in the <spppAcceptRequest> element, and the response is wrapped in the generic <spppAcceptResponse> element 🧚 The subsections below cover both. Peep Section 10 for an example of the Accept operation on a SED Group Offer πŸ‘‘

7.2.3.1. Accept Request Structure

An SPPP over SOAP Accept request is contained within the generic <sppAcceptRequest> element ✨

   <element name="spppAcceptRequest">
    <complexType>
     <sequence>
      <element name="clientTransId"
      type="sppfb:TransIdType" minOccurs="0"/>
      <element name="minorVer"
      type="sppfb:MinorVerType" minOccurs="0"/>
      <element name="sedGrpOfferKey"
      type="sppfs:SedGrpOfferKeyType"
      maxOccurs="unbounded"/>
     </sequence>
    </complexType>
   </element>

Here's what goes inside the <spppAcceptRequest> element πŸ’–

  • clientTransId: zero or one client-generated transaction ID that, from the SPPF client's point of view, identifies this request 🌈 The SPPF client can use it however it likes to track, log, or correlate requests with their responses. The SPPF server MUST echo this value back to the client in the corresponding response to the incoming request. The SPPF server will not check this value for uniqueness πŸ™ƒ
  • minorVer: zero or one minor version identifier, as defined in Section 7.4 πŸ“
  • sedGrpOfferKey: one or more elements of type SedGrpOfferKeyType (as defined in this document) 🫢 Each one has attributes that uniquely identify a SED Group Offer the client wants the server to accept. The SPPF server processes these elements in the order they show up in the request. For error handling, conforming SPPP SOAP servers MUST stop processing SedGrpOfferKeyType elements at the first error and roll back any SedGrpOfferKeyType elements that were already processed for that Accept request ("stop and roll back") ⚠️
okay this "stop and roll back" rule is a whole vibe 🚨 the server halts at the first error and undoes whatever it already did in that request. no half-finished accepts!

7.2.3.2. Accept Response

An SPPP over SOAP accept response is contained within the generic <sppAcceptResponse> element πŸ¦‹ This structure is used for an Accept request on a SED Group Offer.

   <element name="spppAcceptResponse">
    <complexType>
     <sequence>
      <element name="clientTransId" type="sppfb:TransIdType"
               minOccurs="0"/>
      <element name="serverTransId" type="sppfb:TransIdType"/>
      <element name="overallResult" type="sppfs:ResultCodeType"/>
      <element name="detailResult"
               type="sppfs:SedGrpOfferKeyResultCodeType"
               minOccurs="0" maxOccurs="unbounded"/>
     </sequence>
    </complexType>
   </element>

   <complexType name="ResultCodeType">
    <sequence>
     <element name="code" type="int"/>
     <element name="msg" type="string"/>
    </sequence>
   </complexType>

   <complexType name="SedGrpOfferKeyResultCodeType">
    <complexContent>
     <extension base="sppfs:ResultCodeType">
      <sequence>
       <element name="sedGrpOfferKey" type="sppfs:SedGrpOfferKeyType"/>
      </sequence>
     </extension>
    </complexContent>
   </complexType>

An <spppAcceptResponse> has all the elements the SPPF client needs to nail down the overall result of the request πŸ’… and if an error pops up, it tells you which SED Group Offer key(s) caused it πŸ™ˆ

Here's the data element breakdown for the SPPP over SOAP Accept response:

  • clientTransId: zero or one client transaction ID 🫢 It's simply an echo of the client transaction ID the SPPF client passed into the SPPF update request. When it was included in the request, the SPPF server MUST return it in the corresponding response message.
  • serverTransId: exactly one server transaction ID that identifies this request for tracking purposes πŸ”₯ This value MUST be unique for a given SPPF server.
  • overallResult: exactly one response code and message pair that explicitly identifies the result of the request ✨ See Section 7.3 for further details.
  • detailResult: an optional response code, response message, and SedGrpOfferKeyType (as defined in this document) triplet 🌸 It only appears if a specific SED Group Offer key level error has happened. It tells you the error condition and the exact request SED Group Offer key that caused it. The response code reflects the exact error. See Section 7.3 for further details.

7.2.4. Reject Operation Structure

okay so, same vibe as Accept πŸ’œ in SPPF, a SED Group Offer can be accepted or rejected by (or on behalf of) the Registrant it was offered to (check "Framework Data Model Objects", Section 6 of [RFC7877] for what a SED Group Offer object is). The Reject operation is how those offers get turned down πŸ™…β€β™€οΈ

The request for an SPPP over SOAP Reject operation is wrapped in the <spppRejectRequest> element, and the response is wrapped in the generic <spppRejecResponse> element 🧚 Yes, that spelling is how it's written in the spec, typo and all πŸ™ˆ The following subsections cover both elements. Refer to Section 10 for an example of the Reject operation on a SED Group Offer πŸ‘‘

7.2.4.1. Reject Request

An SPPP over SOAP Reject request is contained within the generic <spppRejectRequest> element πŸŽ€

   <element name="spppRejectRequest">
    <complexType>
     <sequence>
      <element name="clientTransId"
      type="sppfb:TransIdType" minOccurs="0"/>
      <element name="minorVer"
      type="sppfb:MinorVerType" minOccurs="0"/>
      <element name="sedGrpOfferKey"
      type="sppfs:SedGrpOfferKeyType"
      maxOccurs="unbounded"/>
     </sequence>
    </complexType>
   </element>

The data elements within the <spppRejectRequest> element work like this πŸ’–

  • clientTransId: zero or one client-generated transaction ID that, within the context of the SPPF client, identifies this request 🌈 The SPPF client can use it at its own discretion to track, log, or correlate requests and their responses. The SPPF server MUST echo this value back to the client in the corresponding response to the incoming request. The SPPF server will not check this value for uniqueness πŸ™ƒ
  • minorVer: zero or one minor version identifier, as defined in Section 7.4 πŸ“
  • sedGrpOfferKey: one or more elements of type SedGrpOfferKeyType (as defined in this document) 🫢 Each one has attributes that uniquely identify a SED Group Offer the client is asking the server to reject. The SPPF server processes these in the order they're included in the request. For error handling, conforming SPPF servers MUST stop processing SedGrpOfferKeyType elements in the request at the first error and roll back any SedGrpOfferKeyType elements that were already processed for that Reject request ("stop and roll back") ⚠️

no half-finished rejects either bestie πŸ’€ same energy as the Accept side: stop at the first error, undo what already happened 🫢

7.2.4.2. Reject Response ✨

okay so the SPPP over SOAP reject response structure lives inside the generic <spppRejectResponse> element πŸŽ€ and it's used for a Reject request on a SED Group Offer. Here's the vibe:

<element name="spppRejectResponse">
 <complexType>
  <sequence>
   <element name="clientTransId" type="sppfb:TransIdType"
            minOccurs="0"/>
   <element name="serverTransId" type="sppfb:TransIdType"/>
   <element name="overallResult" type="sppfs:ResultCodeType"/>
   <element name="detailResult"
            type="sppfs:SedGrpOfferKeyResultCodeType"
            minOccurs="0" maxOccurs="unbounded"/>
  </sequence>
 </complexType>
</element>

<complexType name="ResultCodeType">
 <sequence>
  <element name="code" type="int"/>
  <element name="msg" type="string"/>
 </sequence>
</complexType>

<complexType name="SedGrpOfferKeyResultCodeType">
 <complexContent>
  <extension base="sppfs:ResultCodeType">
   <sequence>
    <element name="sedGrpOfferKey" type="sppfs:SedGrpOfferKeyType"/>
   </sequence>
  </extension>
 </complexContent>
</complexType>

An <spppRejectResponse> has everything the SPPF client needs to precisely determine the overall result of the request πŸ’–. And if something goes wrong, it also tells you about the specific SED Group Offer key(s) that caused the error 😭.

Now the data elements, bestie πŸ¦‹:

  • clientTransId: zero or one client transaction ID. It's just an echo of the ID the SPPF client passed into the SPPF update request 🫢. When it was included in the request, the SPPF server MUST return it in the corresponding response message πŸ’….
  • serverTransId: exactly one server transaction ID that identifies this request for tracking purposes πŸ”. This value MUST be unique for a given SPPF server 🌸.
  • overallResult: exactly one response code and message pair that explicitly tells you the result of the request ✨. Check out Section 7.3 for the full tea 🍡.
  • detailResult: an optional response code, response message, and SedGrpOfferKeyType (as defined in this document) triplet 🧚. It only shows up if a specific SED Group Offer key-level error happened πŸ’€. It tells you the error condition and the exact request SED Group Offer key that caused it, and the response code reflects the exact error πŸ‘‘. See Section 7.3 for further details.

7.2.5. Batch Operation Structure 🌈

An SPPP over SOAP Batch request lets the SPPF client send any of the Add, Del, Accept, or Reject operations together in one single request πŸ”₯. Main character energy: one request structure that handles several operations (verbs) at once πŸ’œ. The batch request is wrapped in the <spppBatchRequest> element, and an SPPF Batch response is wrapped in the <spppBatchResponse> element πŸŽ€. Refer to Section 10 for an example of a Batch operation πŸ¦‹.

7.2.5.1. Batch Request Structure πŸ’–

An SPPP over SOAP Batch request definition is contained within the generic <spppBatchRequest> element:

    <element name="spppBatchRequest">
    <complexType>
     <sequence>
      <element name="clientTransId"
      type="sppfb:TransIdType" minOccurs="0"/>
      <element name="minorVer"
      type="sppfb:MinorVerType" minOccurs="0"/>
       <choice minOccurs="1" maxOccurs="unbounded">
        <element name="addObj" type="sppfb:BasicObjType"/>
        <element name="delObj" type="sppfb:ObjKeyType"/>
        <element name="acceptSedGrpOffer"
        type="sppfs:SedGrpOfferKeyType"/>
        <element name="rejectSedGrpOffer"
        type="sppfs:SedGrpOfferKeyType"/>
       </choice>
     </sequence>
    </complexType>
   </element>

The data elements inside <spppBatchRequest> work like this πŸ“:

  • clientTransId: zero or one client-generated transaction ID that identifies this request within the SPPF client's context 🧁. The SPPF client can use it however it likes to track, log, or correlate requests and responses πŸ’…. The SPPF server MUST echo this value back to the client in the corresponding response to the incoming request 🫢. The SPPF server will not check this value for uniqueness πŸ™ˆ.
  • minorVer: zero or one minor version identifier, as defined in Section 7.4 ✨.
  • addObj: one or more elements of abstract type BasicObjType, where each element identifies an object that needs to be added 🌸.
  • delObj: one or more elements of abstract type ObjKeyType, where each element identifies a key for the object that needs to be deleted πŸ—‘οΈ.
  • acceptSedGrpOffer: one or more elements of type SedGrpOfferKeyType, where each element identifies a SED Group Offer that needs to be accepted πŸŽ‰.
  • rejectSedGrpOffer: one or more elements of type SedGrpOfferKeyType, where each element identifies a SED Group Offer that needs to be rejected πŸ₯€.

Okay, now the error handling, and this part is super serious 🚨. Conforming SPPP SOAP servers MUST stop processing elements in the request at the first error, and they MUST roll back any elements that were already processed for that Batch request ("stop and roll back") πŸ’€.

7.2.5.2. Batch Response 🌷

An SPPP over SOAP batch response is contained within the generic <spppBatchResponse> element 🧚. It's used for a Batch request that has lots of different kinds of SPPF operations in it πŸŽ€.

  <element name="spppBatchResponse">
    <complexType>
      <sequence>
        <element name="clientTransId" type="sppfb:TransIdType"
         minOccurs="0"/>
        <element name="serverTransId" type="sppfb:TransIdType"/>
        <element name="overallResult" type="sppfs:ResultCodeType"/>
        <choice minOccurs="0" maxOccurs="unbounded">
           <element name="addResult"
           type="sppfs:ObjResultCodeType"/>
           <element name="delResult"
           type="sppfs:ObjKeyResultCodeType"/>
           <element name="acceptResult"
           type="sppfs:SedGrpOfferKeyResultCodeType"/>
           <element name="rejectResult"
           type="sppfs:SedGrpOfferKeyResultCodeType"/>
         </choice>
      </sequence>
    </complexType>
  </element>

An <spppBatchResponse> has the elements an SPPF client needs to precisely determine the overall result of the various operations in the request πŸ’…. If something goes wrong, it also tells you about the specific objects or keys in the request that caused the error 😭.

The data elements in the SPPP over SOAP Batch response work like this πŸ’œ:

  • clientTransId: zero or one client transaction ID 🫢. It's simply an echo of the one the SPPF client passed into the SPPF update request. When it was included in the request, the SPPF server MUST return it in the corresponding response message πŸ’–.
  • serverTransId: exactly one server transaction ID that identifies this request for tracking purposes πŸ”. This value MUST be unique for a given SPPF server 🌸.
  • overallResult: exactly one response code and message pair that explicitly identifies the result of the request ✨. See Section 7.3 for further details.
  • addResult: one or more elements of type ObjResultCodeType, where each element identifies the result code, result message, and the specific object the result relates to πŸŽ€.
  • delResult: one or more elements of type ObjKeyResultCodeType, where each element identifies the result code, result message, and the specific object key the result relates to πŸ¦‹.
  • acceptResult: one or more elements of type SedGrpOfferKeyResultCodeType, where each element identifies the result code, result message, and the specific SED Group Offer key the result relates to πŸ‘‘.
  • rejectResult: one or more elements of type SedGrpOfferKeyResultCodeType, where each element identifies the result code, result message, and the specific SED Group Offer key the result relates to πŸ₯€.

7.2.6. Get Operation Structure πŸ”

To query the details of an object from the Registry, an authorized entity can send the spppGetRequest to the Registry 🧚. It includes a GetRqstType XML data structure with one or more object keys that uniquely identify the object being queried πŸ’…. The following subsections describe the <spppGetRequest> and <spppGetResponse> elements. Refer to Section 10 for an example of the SPPP over SOAP Get operation on each type of SPPF object 🌈.

7.2.6.1. Get Request 🫢

The request structure for an SPPP over SOAP Get operation is contained within the generic <spppGetRequest> element:

   <element name="spppGetRequest">
    <complexType>
     <sequence>
      <element name="minorVer"
      type="sppfb:MinorVerType" minOccurs="0"/>
      <element name="objKey"
      type="sppfb:ObjKeyType"
      maxOccurs="unbounded"/>
     </sequence>
    </complexType>
   </element>

The data elements in the <spppGetRequest> element work like this ✨:

  • minorVer: zero or one minor version identifier, as defined in Section 7.4 🌸.
  • objKey: one or more elements of abstract type ObjKeyType (as defined in [RFC7877]) πŸ”‘. Each element has attributes that uniquely identify the object the client wants the server to query πŸ’–. Check out Section 7.1 of this document for a description of all the concrete object key types for the various SPPF objects that are allowed in this element πŸŽ€.

7.2.6.2. Get Response πŸ’Œ

The SPPP over SOAP Get response is wrapped in the generic <spppGetResponse> element, as described in Section 7.2.8 πŸ¦‹.


7.2.7. Get SED Group Offers Operation Structure πŸ‘‘

Besides querying one or more SED Group Offers with a SED Group Offer key in the spppGetRequest, this operation gives you an extra, more flexible structure for searching SED Group Offer objects 🌈. That structure is contained within the <getSedGrpOffersRequest> element, and the response is wrapped in the generic <spppGetResponse> element 🧚. The following subsections describe the <getSedGrpOffersRequest> and <spppGetResponse> elements πŸ’œ.

7.2.7.1. Get SED Group Offers Request

okay so this is the lookup request for SED Group Offers πŸ”πŸ’– the server goes hunting for every SED Group Offer object that satisfies all the criteria you pass in. no criteria at all? then it hands back the SED Group Offer objects that belong to the Registrant 🧚. nothing matches? you get an empty result set, no drama 🫢

    <element name="getSedGrpOffersRequest">
    <complexType>
     <sequence>
      <element name="minorVer" type="sppfb:MinorVerType"
      minOccurs="0"/>
     <element name="offeredBy" type="sppfb:OrgIdType"
     minOccurs="0" maxOccurs="unbounded"/>
     <element name="offeredTo" type="sppfb:OrgIdType"
     minOccurs="0" maxOccurs="unbounded"/>
     <element name="status" type="sppfb:SedGrpOfferStatusType"
      minOccurs="0"/>
     <element name="sedGrpOfferKey" type="sppfs:SedGrpOfferKeyType"
     minOccurs="0" maxOccurs="unbounded"/>
     </sequence>
    </complexType>
   </element>

the data elements inside the <getSedGrpOffersRequest> element work like this πŸ’…

  • minorVer: zero or one minor version identifier, as defined in Section 7.4. πŸŽ€
  • offeredBy: zero or more organization IDs. only offers that are offered to the organization IDs in this list should be included in the result set. the result set is also subject to other query criteria in the request. 🌸
  • offeredTo: zero or more organization IDs. only offers that are offered by the organization IDs in this list should be included in the result set. the result set is also subject to other query criteria in the request. πŸ¦‹
  • status: the status of the offer, offered or accepted. only offers in the specified status should be included in the result set. if this element is not present, then the status of the offer should not be considered in the query. the result set is also subject to other query criteria in the request. ✨
  • sedGrpOfferKey: zero or more SED Group Offer keys. only offers having one of these keys should be included in the result set. the result set is also subject to other query criteria in the request. πŸ”‘

7.2.7.2. Get SED Group Offers Response

the spppGetResponse element is covered in Section 7.2.8, so go check that one out πŸ‘€βœ¨

7.2.8. Generic Query Response

every SPPP over SOAP query response object lives inside the generic <spppGetResponse> element πŸ“¦πŸŒˆ

    <element name="spppGetResponse">
     <complexType>
      <sequence>
       <element name="overallResult"
       type="sppfs:ResultCodeType"/>
       <element name="resultObj"
       type="sppfb:BasicObjType"
       minOccurs="0" maxOccurs="unbounded"/>
      </sequence>
     </complexType>
    </element>

an <spppGetResponse> has everything the SPPF client needs to figure out the overall result of the query and the details of any SPPF objects that matched the criteria in the request. it's giving full transparency πŸ’œ

the data elements inside the SPPP over SOAP query response work like this:

  • overallResult: exactly one response code and message pair that explicitly identifies the result of the request. see Section 7.3 for the deets. 🎯
  • resultObj: the set of zero or more objects that matched the query criteria. if no objects matched the query criteria, then the result object(s) MUST be empty and the overallResult value MUST indicate success (if no matches are found for the query criteria, the response is considered a success). no matches is still a win, bestie πŸ₯³

7.2.9. Get Server Details Operation Structure

when you wanna check on the SPPF server itself, like its status and which major/minor versions of SPPP over SOAP it supports, the Server Details operation structure SHOULD be used πŸ–₯οΈπŸ’… the request lives in the <spppServerStatusRequest> element and the response is wrapped in the <spppServerStatusResponse> element. the next two subsections break both of them down 🧚

7.2.9.1. Get Server Details Request

an SPPP over SOAP server details request is represented in the <spppServerStatusRequest> element like this:

    <element name="spppServerStatusRequest">
     <complexType>
      <sequence>
       <element name="minorVer"
       type="sppfb:MinorVerType" minOccurs="0"/>
      </sequence>
     </complexType>
    </element>

the data elements inside the <spppServerStatusRequest> element:

  • minorVer: zero or one minor version identifier, as defined in Section 7.4. 🌸

7.2.9.2. Get Server Details Response

an SPPP over SOAP server details response is contained within the generic <spppServerStatusResponse> element πŸŽ€

    <element name="spppServerStatusResponse">
     <complexType>
      <sequence>
       <element name="overallResult" type="sppfs:ResultCodeType"/>
       <element name="svcMenu" type="sppfb:SvcMenuType"/>
      </sequence>
     </complexType>
    </element>

the data elements inside the <spppServerStatusResponse> element:

  • overallResult: exactly one response code and message pair that explicitly identifies the result of the request. see Section 7.3 for further details. 🎯
  • svcMenu: exactly one element of type SvcMenuType that, in turn, contains the elements to return the server status, the major and minor versions of SPPP over SOAP supported by the SPPF server (refer to Section 12 of [RFC7877] for the definition of SvcMenuType). 🧾

7.3. Response Codes and Messages

this section is the big list of response codes and their human-readable text πŸ“‹βœ¨ they follow the response types defined in Section 5.3 of [RFC7877], so everything lines up πŸ’œ

the response code numbering scheme generally sticks to the theory formalized in Section 4.2.1 of [RFC5321] 🧠:

  • the first digit can only be 1 or 2: 1 = a positive result, and 2 = a negative result. βœ…βŒ
  • the second digit tells you the category: 0 = Protocol Syntax, 1 = Implementation Specific Business Rule, 2 = Security, and 3 = Server System. πŸ—‚οΈ
  • the third and fourth digits point to the individual message event within the category set by the first two digits. πŸ”

the codes are also sorted by whether they're overall response codes (only allowed in the overallResult data element of SPPF responses) or object-level response codes (only allowed in the detailResult element of SPPF responses) 🫢

+--------+--------------------------+-------------------------------+
| Result | Result Message           | Overall or Object Level       |
| Code   |                          |                               |
+--------+--------------------------+-------------------------------+
| 1000   | Request succeeded        | Overall Response Code         |
| 2000   | Request syntax invalid   | Overall Response Code         |
| 2001   | Request too large        | Overall Response Code         |
|        | MaxSupported:[Maximum    |                               |
|        | requests supported]      |                               |
| 2002   | Version not supported    | Overall Response Code         |
| 2100   | Command invalid          | Overall Response Code         |
| 2300   | System temporarily       | Overall Response Code         |
|        | unavailable              |                               |
| 2301   | Unexpected internal      | Overall Response Code         |
|        | system or server error   |                               |
| 2101   | Attribute value invalid  | Object-Level Response Code    |
|        | AttrName:[AttributeName] |                               |
|        | AttrVal:[AttributeValue] |                               |
| 2102   | Object does not exist    | Object-Level Response Code    |
|        | AttrName:[AttributeName] |                               |
|        | AttrVal:[AttributeValue] |                               |
| 2103   | Object status or         | Object-Level Response Code    |
|        | ownership does not allow |                               |
|        | for operation            |                               |
|        | AttrName:[AttributeName] |                               |
|        | AttrVal:[AttributeValue] |                               |
+--------+--------------------------+-------------------------------+

        Table 1: Response Code Numbering Scheme and Messages

the response message for code 2001 is "parameterized" with one parameter: "[Maximum requests supported]". when the request is too large, this parameter MUST be used to show the maximum number of requests the server supports in a single protocol operation. πŸ“πŸ’₯

response code 2000 SHOULD be used when the XML Schema validation of requests fails. πŸ™…β€β™€οΈ

each object-level response message is "parameterized" with two parameters: "AttributeName" and "AttributeValue" πŸŽ€

for example, say an SPPF client sends a request to delete a Destination Group named "TestDG", and it doesn't already exist. the error message coming back should be: Attribute value invalid. AttrName:dgName AttrVal:TestDG 😭

the use of these parameters MUST adhere to the rules in Section 5.3 of [RFC7877]. no freestyling, periodt πŸ“œπŸ’…

7.4. Minor Version Identifier

the minor version identifier element is defined like this 🧚

  • minorVer: zero or one minor version identifier, indicating the minor version of the SPPP over SOAP API that the client is trying to use. it's used together with the major version identifier in the XML Namespace to identify which version of SPPP over SOAP the client is using. if the element isn't present, the server assumes the client is using the latest minor version of SPPP over SOAP supported by the SPPF server for the given major version. clients can find out which versions a given SPPF server supports by sending this same spppServerStatusRequest without passing in the minorVer element. πŸ”Žβœ¨

8. Protocol Operations

refer to Section 7 of [RFC7877] for a description of all SPPF operations and any necessary semantics that MUST be adhered to in order to conform with SPPF. the rules are all there, so don't skip it πŸ“–πŸ’œ

9. SPPP over SOAP WSDL Definition

the SPPP over SOAP WSDL and data types are defined below 🧁 the design approach is commonly called "Generic WSDL". it's generic because there isn't a specific WSDL operation for each object type that SPPF supports. instead, there's a single WSDL structure for each type of SPPF operation. each of those structures has exactly one input structure and one output structure that wraps the data elements of the incoming request and the outgoing response, respectively. the spppSOAPBinding in the WSDL sets the binding style to "document" and the encoding to "literal". that mix of "wrapped" input and output structures, "document" binding style, and "literal" encoding is what makes up the Document Literal Wrapped style of WSDL specifications 🌈

Notes: the following WSDL has been formatted (e.g., tabs, spaces) to meet IETF requirements. Deployments MUST replace REPLACE_WITH_ACTUAL_URL in the WSDL below with the URI of the SPPF server instance. 🫢 don't forget that swap!

Okay bestie, the WSDL is still rolling, and this little <sequence> is about to open up the next chunk of the result types πŸ’–

         <sequence>
          <element name="objKey" type="sppfb:ObjKeyType"/>
         </sequence>
        </extension>
       </complexContent>
      </complexType>
         <complexType name="SedGrpOfferKeyResultCodeType">
       <complexContent>
        <extension base="sppfs:ResultCodeType">
         <sequence>
          <element name="sedGrpOfferKey"
          type="sppfs:SedGrpOfferKeyType"/>
         </sequence>
        </extension>
       </complexContent>
       </complexType>
     </xsd:schema>
    </wsdl:types>
    <wsdl:message name="spppAddRequestMsg">
     <wsdl:part name="rqst" element="sppfs:spppAddRequest"/>
    </wsdl:message>
    <wsdl:message name="spppDelRequestMsg">
     <wsdl:part name="rqst" element="sppfs:spppDelRequest"/>
    </wsdl:message>
    <wsdl:message name="spppAcceptRequestMsg">
     <wsdl:part name="rqst" element="sppfs:spppAcceptRequest"/>
    </wsdl:message>
    <wsdl:message name="spppRejectRequestMsg">
     <wsdl:part name="rqst" element="sppfs:spppRejectRequest"/>
    </wsdl:message>
    <wsdl:message name="spppBatchRequestMsg">
     <wsdl:part name="rqst" element="sppfs:spppBatchRequest"/>
    </wsdl:message>
    <wsdl:message name="spppGetRequestMsg">
     <wsdl:part name="rqst" element="sppfs:spppGetRequest"/>
    </wsdl:message>
    <wsdl:message name="spppGetSedGrpOffersRequestMsg">
     <wsdl:part name="rqst" element="sppfs:getSedGrpOffersRequest"/>
    </wsdl:message>
    <wsdl:message name="spppAddResponseMsg">
     <wsdl:part name="rspns" element="sppfs:spppAddResponse"/>
    </wsdl:message>
     <wsdl:message name="spppDelResponseMsg">
     <wsdl:part name="rspns" element="sppfs:spppDelResponse"/>
    </wsdl:message>
     <wsdl:message name="spppAcceptResponseMsg">
     <wsdl:part name="rspns" element="sppfs:spppAcceptResponse"/>
    </wsdl:message>
     <wsdl:message name="spppRejectResponseMsg">
     <wsdl:part name="rspns" element="sppfs:spppRejectResponse"/>
    </wsdl:message>
     <wsdl:message name="spppBatchResponseMsg">
     <wsdl:part name="rspns" element="sppfs:spppBatchResponse"/>
    </wsdl:message>
    <wsdl:message name="spppGetResponseMsg">
     <wsdl:part name="rspns" element="sppfs:spppGetResponse"/>
    </wsdl:message>
    <wsdl:message name="spppServerStatusRequestMsg">
     <wsdl:part name="rqst" element="sppfs:spppServerStatusRequest"/>
    </wsdl:message>
    <wsdl:message name="spppServerStatusResponseMsg">
     <wsdl:part name="rspns" element="sppfs:spppServerStatusResponse"/>
    </wsdl:message>
    <wsdl:portType name="spppPortType">
     <wsdl:operation name="submitAddRqst">
      <wsdl:input message="sppfs:spppAddRequestMsg"/>
      <wsdl:output message="sppfs:spppAddResponseMsg"/>
     </wsdl:operation>
     <wsdl:operation name="submitDelRqst">
      <wsdl:input message="sppfs:spppDelRequestMsg"/>
      <wsdl:output message="sppfs:spppDelResponseMsg"/>
     </wsdl:operation>
     <wsdl:operation name="submitAcceptRqst">
      <wsdl:input message="sppfs:spppAcceptRequestMsg"/>
      <wsdl:output message="sppfs:spppAcceptResponseMsg"/>
     </wsdl:operation>
     <wsdl:operation name="submitRejectRqst">
      <wsdl:input message="sppfs:spppRejectRequestMsg"/>
      <wsdl:output message="sppfs:spppRejectResponseMsg"/>
     </wsdl:operation>
     <wsdl:operation name="submitBatchRqst">
      <wsdl:input message="sppfs:spppBatchRequestMsg"/>
      <wsdl:output message="sppfs:spppBatchResponseMsg"/>
     </wsdl:operation>
     <wsdl:operation name="submitGetRqst">
      <wsdl:input message="sppfs:spppGetRequestMsg"/>
      <wsdl:output message="sppfs:spppGetResponseMsg"/>
     </wsdl:operation>
     <wsdl:operation name="submitGetSedGrpOffersRqst">
      <wsdl:input message="sppfs:spppGetSedGrpOffersRequestMsg"/>
      <wsdl:output message="sppfs:spppGetResponseMsg"/>
     </wsdl:operation>
     <wsdl:operation name="submitServerStatusRqst">
      <wsdl:input message="sppfs:spppServerStatusRequestMsg"/>
      <wsdl:output message="sppfs:spppServerStatusResponseMsg"/>
     </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="spppSoapBinding" type="sppfs:spppPortType">
     <soap:binding style="document"
     transport="http://schemas.xmlsoap.org/soap/http"/>
     <wsdl:operation name="submitAddRqst">
      <soap:operation soapAction="submitAddRqst" style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
     <wsdl:operation name="submitDelRqst">
      <soap:operation soapAction="submitDelRqst" style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
     <wsdl:operation name="submitAcceptRqst">
      <soap:operation soapAction="submitAcceptRqst" style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
     <wsdl:operation name="submitRejectRqst">
      <soap:operation soapAction="submitRejectRqst" style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
     <wsdl:operation name="submitBatchRqst">
      <soap:operation soapAction="submitBatchRqst" style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
     <wsdl:operation name="submitGetRqst">
      <soap:operation soapAction="submitGetRqst" style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
     <wsdl:operation name="submitGetSedGrpOffersRqst">
      <soap:operation soapAction="submitGetSedGrpOffersRqst"
      style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
     <wsdl:operation name="submitServerStatusRqst">
      <soap:operation soapAction="submitServerStatusRqst"
      style="document"/>
      <wsdl:input>
       <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
       <soap:body use="literal"/>
      </wsdl:output>
     </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="spppService">
     <wsdl:port name="spppPort" binding="sppfs:spppSoapBinding">
      <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
     </wsdl:port>
    </wsdl:service>
   </wsdl:definitions>

Figure 2: WSDL πŸŽ€

10. SPPP over SOAP Examples ✨

This section shows an XML message exchange between two SIP Service Providers (SSPs) and a Registry πŸ’… The messages in this section are valid XML instances that conform to the SPPP over SOAP schema version within this document. It also leans on the XML data structures defined in the SPPF specification [RFC7877], which should also be referenced to understand XML object types embedded in these example messages. Read that one too, bestie πŸ“š

In this sample use-case scenario, SSP1 and SSP2 provision resource data in the Registry and use SPPF constructs to selectively share the SED Groups πŸ¦‹ In the figure below, SSP2 has two ingress Signaling Path Border Element (SBE) instances that are associated with the Public Identities with which SSP2 has the retail relationship. Also, the two SBE instances for SSP1 are used to show how to use SPPF to associate route preferences for the destination Ingress Routes and exercise greater control on outbound traffic to the peer's ingress SBEs. It's giving main character energy πŸ‘‘

      ---------------+                      +------------------
                     |                      |
                 +------+               +------+
                 | sbe1 |               | sbe2 |
                 +------+               +------+
       SSP1          |                      |           SSP2
                 +------+               +------+
                 | sbe3 |               | sbe4 |
                 +------+               +------+
      iana-en:111    |                      |     iana-en:222
      ---------------+                      +------------------
              |                                     |
              |                                     |
              | SPPF   +------------------+   SPPF  |
              +------->|     Registry     |<--------+
                       +------------------+

                      Example Use-Case Infrastructure

10.1. Add Destination Group 🌸

SSP2 adds a Destination Group to the Registry for later use 🧚 The SSP2 SPPF client sets a unique transaction identifier "txn_1479" for tracking purposes. The name of the Destination Group is set to DEST_GRP_SSP2_1. Cute and organised πŸ“

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <!--Optional:-->
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:DestGrpType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry processes the request and returns a favorable response confirming successful creation of the named Destination Group πŸ₯³ On top of a unique server transaction identifier, the Registry sends the matching client transaction identifier from the request message right back to the SPPF client. Iconic behaviour, honestly ✨

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.2. Add SED Records ✨

okay so SSP2 is adding SED Records to the Registry in the form of Ingress Routes πŸ›£οΈ it's giving main character energy πŸ’…

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <!--Optional:-->
   <clientTransId>txn_1479</clientTransId>
   <!--1 or more repetitions:-->
   <obj xsi:type="urn1:NAPTRType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:sedName>SED_SSP2_SBE2</urn1:sedName>
    <urn1:isInSvc>true</urn1:isInSvc>
    <urn1:order>10</urn1:order>
    <urn1:flags>u</urn1:flags>
    <urn1:svcs>E2U+sip</urn1:svcs>
    <urn1:regx>
     <urn1:ere>^(.*)$</urn1:ere>
     <urn1:repl>sip:\1@sbe2.ssp2.example.com</urn1:repl>
    </urn1:regx>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry sends back a success response, yay πŸŽ‰

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.3. Add SED Records -- URIType πŸ¦‹

SSP2 adds another SED Record to the Registry, and this time it's using URIType πŸ”₯

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:URIType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:sedName>SED_SSP2_SBE4</urn1:sedName>
    <urn1:isInSvc>true</urn1:isInSvc>
    <urn1:ere>^(.*)$</urn1:ere>
    <urn1:uri>sip:\1;npdi@sbe4.ssp2.example.com</urn1:uri>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry sends back a success response πŸ’–

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.4. Add SED Group πŸ“

SSP2 groups SED Records together (think Ingress Routes 🧚) and gives SED_SSP2_SBE2 the higher precedence by setting a lower number for the "priority" attribute. That attribute is a protocol agnostic precedence indicator, so it doesn't care what protocol is underneath, which is lowkey iconic πŸ‘‘

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:SedGrpType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:sedGrpName>SED_GRP_SSP2_1</urn1:sedGrpName>
    <urn1:sedRecRef>
     <urn1:sedKey xsi:type="urn:ObjKeyType">
      <rant>iana-en:222</rant>
      <name>SED_SSP2_SBE2</name>
      <type>SedRec</type>
     </urn1:sedKey>
     <urn1:priority>100</urn1:priority>
    </urn1:sedRecRef>
    <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
    <urn1:isInSvc>true</urn1:isInSvc>
    <urn1:priority>10</urn1:priority>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

To confirm that the request went through, the Registry sends back the well-known result code "1000" to the SSP2 client ✨

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.5. Add Public Identifier -- Successful COR Claim πŸŽ€

SSP2 activates a TN Public Identifier by linking it to a valid Destination Group. On top of that, SSP2 claims that it's the carrier-of-record (COR) for the TN, which is a big deal, no cap 🫢

<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:TNType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
    <urn1:tn>+12025556666</urn1:tn>
    <urn1:corInfo>
     <urn1:corClaim>true</urn1:corClaim>
    </urn1:corInfo>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

Here's the tea β˜• If the Registry has access to TN authority data and runs the required checks to confirm that SSP2 really is the SP of record for that TN, the request goes through. In the response, the Registry sets <cor> to "true" to back up the SSP2 claim as the carrier-of-record, and the <corDate> shows the exact time the carrier-of-record claim got processed ⏰ iykyk

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
   <detailResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
    <obj xsi:type="ns2:TNType">
     <ns2:rant>iana-en:222</ns2:rant>
     <ns2:rar>iana-en:223</ns2:rar>
     <ns2:cDate>2010-05-30T09:30:10Z</ns2:cDate>
     <ns2:dgName>DEST_GRP_SSP2_1</ns2:dgName>
     <ns2:tn>+12025556666</ns2:tn>
     <ns2:corInfo>
      <ns2:corClaim>true</ns2:corClaim>
      <ns2:cor>true</ns2:cor>
      <ns2:corDate>2010-05-30T09:30:11Z</ns2:corDate>
     </ns2:corInfo>
    </obj>
   </detailResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.6. Add LRN πŸ“ž

Okay so if another entity that SSP2 shares SED (like routes) with has access to Number Portability data, it's allowed to do route lookups by RN πŸ‘€ That's why SSP2 links an RN to a Destination Group, so Ingress Route discovery is easier. Smart, right? 🧠

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:RNType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
    <urn1:rn>2025550000</urn1:rn>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry finishes the request successfully and sends back a favorable response to the SPPF client πŸ₯°

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.7. Add TN Range 🌈

Next up, SSP2 activates a block of ten thousand TNs and links it to a Destination Group. Ten thousand numbers in one go, bestie, that's a whole vibe πŸ’…βœ¨

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:TNRType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
    <urn1:range>
     <urn1:startTn>+12026660000</urn1:startTn>
     <urn1:endTn>+12026669999</urn1:endTn>
    </urn1:range>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and sends back a favorable response 🫢

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.8. Add TN Prefix ✨

okay next up, SSP2 activates a whole block of ten thousand TNs 🀯 by using the TNPType structure and pointing at a TN prefix πŸ“ž

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:TNPType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
    <urn1:tnPrefix>+1202777</urn1:tnPrefix>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry totally completes the request and sends back a favorable response πŸ’…

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.9. Enable Peering -- SED Group Offer 🀝

so like, for SSP1 to finish session establishment for a destination TN where the target subscriber has a retail relationship with SSP2, it first needs an asynchronous bidirectional handshake to show mutual consent πŸ’œ. SSP2 kicks it off by offering SSP1 access to its SED Group πŸŽ€

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:SedGrpOfferType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:sedGrpOfferKey xsi:type="urn:SedGrpOfferKeyType">
     <sedGrpKey xsi:type="urn:ObjKeyType">
      <rant>iana-en:222</rant>
      <name>SED_GRP_SSP2_1</name>
      <type>SedGrp</type>
     </sedGrpKey>
     <offeredTo>iana-en:111</offeredTo>
    </urn1:sedGrpOfferKey>
    <urn1:status>offered</urn1:status>
    <urn1:offerDateTime>
      2006-05-04T18:13:51.0Z
    </urn1:offerDateTime>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and confirms that SSP1 will now get the chance to weigh in on the offer and either accept or reject it 🫢 The Registry may employ out-of-band notification mechanisms for quicker updates to SSP1 so they can act faster, though this topic is beyond the scope of this document πŸ•°οΈ

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.10. Enable Peering -- SED Group Offer Accept πŸ₯°

SSP1 responds to the offer from SSP2 and agrees to have visibility to SSP2 SED (e.g., Ingress Routes). bestie said yes πŸ™Œ

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAcceptRequest>
   <!--Optional:-->
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <sedGrpOfferKey>
    <sedGrpKey>
     <rant>iana-en:222</rant>
     <name>SED_GRP_SSP2_1</name>
     <type>SedGrp</type>
    </sedGrpKey>
    <offeredTo>iana-en:111</offeredTo>
   </sedGrpOfferKey>
  </urn:spppAcceptRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry confirms that the request has been processed successfully. From this point forward, if SSP1 looks up a Public Identifier through the query resolution server, where the Public Identifier is part of the Destination Group by way of "SED_GRP_SSP2_1" SED association, SSP2 ingress SBE information will be shared with SSP1 🌈✨

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAcceptResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12350</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAcceptResponse>
 </S:Body>
</S:Envelope>

10.11. Add Egress Route πŸš€

SSP1 wants to prioritize all outbound traffic to the Ingress Route associated with the "SED_GRP_SSP2_1" SED Group record, through "sbe1.ssp1.example.com" πŸƒβ€β™€οΈπŸ’¨

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppAddRequest>
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <obj xsi:type="urn1:EgrRteType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:egrRteName>EGR_RTE_01</urn1:egrRteName>
    <urn1:pref>50</urn1:pref>
    <urn1:regxRewriteRule>
     <urn1:ere>^(.*@)(.*)$</urn1:ere>
     <urn1:repl>\1\2?route=sbe1.ssp1.example.com</urn1:repl>
    </urn1:regxRewriteRule>
    <urn1:ingrSedGrp xsi:type="urn:ObjKeyType">
     <rant>iana-en:222</rant>
     <name>SED_GRP_SSP2_1</name>
     <type>SedGrp</type>
    </urn1:ingrSedGrp>
   </obj>
  </urn:spppAddRequest>
 </soapenv:Body>
</soapenv:Envelope>

Since peering has already been established, the request to add the Egress Route has been successfully completed πŸŽ‰

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppAddResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12345</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppAddResponse>
 </S:Body>
</S:Envelope>

10.12. Remove Peering -- SED Group Offer Reject πŸ’”

earlier, SSP1 had accepted having visibility to SSP2 SED. SSP1 now decides to no longer maintain this visibility, so it rejects the SED Group Offer πŸ™…β€β™€οΈ

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppRejectRequest>
   <!--Optional:-->
   <clientTransId>txn_1479</clientTransId>
    <!--1 or more repetitions:-->
   <sedGrpOfferKey>
    <sedGrpKey>
     <rant>iana-en:222</rant>
     <name>SED_GRP_SSP2_1</name>
     <type>SedGrp</type>
    </sedGrpKey>
    <offeredTo>iana-en:111</offeredTo>
   </sedGrpOfferKey>
  </urn:spppRejectRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry confirms that the request has been processed successfully. From this point forward, if SSP1 looks up a Public Identifier through the query resolution server, where the Public Identifier is part of the Destination Group by way of "SED_GRP_SSP2_1" SED association, SSP2 ingress SBE information will not be shared with SSP1, so an SSP2 ingress SBE will not be returned in the query response πŸ₯€

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppRejectResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <clientTransId>txn_1479</clientTransId>
   <serverTransId>tx_12350</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppRejectResponse>
 </S:Body>
</S:Envelope>

10.13. Get Destination Group πŸ”

SSP2 uses the spppGetRequest operation to tally the last provisioned record for Destination Group DEST_GRP_SSP2_1 πŸ“‹βœ¨

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppGetRequest>
   <!--1 or more repetitions:-->
   <objKey xsi:type="urn:ObjKeyType">
    <rant>iana-en:222</rant>
    <name>DEST_GRP_SSP2_1</name>
    <type>DestGrp</type>
   </objKey>
  </urn:spppGetRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response πŸ’–

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <S:Body>
  <ns3:spppGetResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <overallResult>
    <code>1000</code>
    <msg>success</msg>
   </overallResult>
   <resultObj xsi:type="ns2:DestGrpType">
    <ns2:rant>iana-en:222</ns2:rant>
    <ns2:rar>iana-en:223</ns2:rar>
    <ns2:cDate>2012-10-22T09:30:10Z</ns2:cDate>
    <ns2:dgName>DEST_GRP_SSP2_1</ns2:dgName>
   </resultObj>
  </ns3:spppGetResponse>
 </S:Body>
</S:Envelope>

10.14. Get Public Identifier πŸ’–

okay so SSP2 wants to look up the last record that got provisioned for a given TN πŸ“žβœ¨

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppGetRequest>
   <!--1 or more repetitions:-->
   <objKey xsi:type="urn:PubIdKeyType">
    <rant>iana-en:222</rant>
    <number>
     <urn1:value>+12025556666</urn1:value>
     <urn1:type>TN</urn1:type>
    </number>
   </objKey>
  </urn:spppGetRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry gets the request done successfully and sends back a super positive response πŸŽ€

<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <S:Body>
  <ns3:spppGetResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <overallResult>
    <code>1000</code>
    <msg>success</msg>
   </overallResult>
   <resultObj xsi:type="ns2:TNType">
    <ns2:rant>iana-en:222</ns2:rant>
    <ns2:rar>iana-en:223</ns2:rar>
    <ns2:cDate>2012-10-22T09:30:10Z</ns2:cDate>
    <ns2:dgName>DEST_GRP_SSP2_1</ns2:dgName>
    <ns2:tn>+12025556666</ns2:tn>
    <ns2:corInfo>
     <ns2:corClaim>true</ns2:corClaim>
     <ns2:cor>true</ns2:cor>
     <ns2:corDate>2010-05-30T09:30:10Z</ns2:corDate>
    </ns2:corInfo>
   </resultObj>
  </ns3:spppGetResponse>
 </S:Body>
</S:Envelope>

10.15. Get SED Group Request 🧚

SSP2 pulls up the last provisioned record for the SED Group SED_GRP_SSP2_1. main character energy πŸ’…

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppGetRequest>
   <!--1 or more repetitions:-->
   <objKey xsi:type="urn:ObjKeyType">
    <rant>iana-en:222</rant>
    <name>SED_GRP_SSP2_1</name>
    <type>SedGrp</type>
   </objKey>
  </urn:spppGetRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response 🌸

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <S:Body>
  <ns3:spppGetResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <overallResult>
    <code>1000</code>
    <msg>success</msg>
   </overallResult>
   <resultObj xsi:type="ns2:SedGrpType">
    <ns2:rant>iana-en:222</ns2:rant>
    <ns2:rar>iana-en:223</ns2:rar>
    <ns2:cDate>2012-10-22T09:30:10Z</ns2:cDate>
    <ns2:sedGrpName>SED_GRP_SSP2_1</ns2:sedGrpName>
    <ns2:sedRecRef>
     <ns2:sedKey xsi:type="ns3:ObjKeyType">
      <rant>iana-en:222</rant>
      <name>SED_SSP2_SBE2</name>
      <type>SedRec</type>
     </ns2:sedKey>
     <ns2:priority>100</ns2:priority>
    </ns2:sedRecRef>
    <ns2:sedRecRef>
     <ns2:sedKey xsi:type="ns3:ObjKeyType">
      <rant>iana-en:222</rant>
      <name>SED_SSP2_SBE4</name>
      <type>SedRec</type>
     </ns2:sedKey>
     <ns2:priority>101</ns2:priority>
    </ns2:sedRecRef>
    <ns2:dgName>DEST_GRP_SSP2_1</ns2:dgName>
    <ns2:isInSvc>true</ns2:isInSvc>
    <ns2:priority>10</ns2:priority>
   </resultObj>
  </ns3:spppGetResponse>
 </S:Body>
</S:Envelope>

10.16. Get SED Group Offers Request πŸ¦‹

SSP2 grabs the last provisioned SED Group Offer that went out to the <peeringOrg> SSP1 ✨

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:getSedGrpOffersRequest>
   <offeredTo>iana-en:111</offeredTo>
  </urn:getSedGrpOffersRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry processes the request successfully and sends back a favorable response 🫢

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <S:Body>
  <ns3:spppGetResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <overallResult>
    <code>1000</code>
    <msg>success</msg>
   </overallResult>
   <resultObj xsi:type="ns2:SedGrpOfferType">
    <ns2:rant>iana-en:222</ns2:rant>
    <ns2:rar>iana-en:223</ns2:rar>
    <ns2:cDate>2012-10-22T09:30:10Z</ns2:cDate>
    <ns2:sedGrpOfferKey
     xsi:type="ns3:SedGrpOfferKeyType">
     <sedGrpKey>
      <rant>iana-en:222</rant>
      <name>SED_GRP_SSP2_1</name>
      <type>SedGrp</type>
     </sedGrpKey>
     <offeredTo>iana-en:111</offeredTo>
    </ns2:sedGrpOfferKey>
    <ns2:status>offered</ns2:status>
    <ns2:offerDateTime>
     2006-05-04T18:13:51.0Z
    </ns2:offerDateTime>
   </resultObj>
  </ns3:spppGetResponse>
 </S:Body>
</S:Envelope>

10.17. Get Egress Route 🌈

SSP1 wants to double-check the last provisioned record for the Egress Route called EGR_RTE_01 πŸ‘‘

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppGetRequest>
   <!--1 or more repetitions:-->
   <objKey xsi:type="urn:ObjKeyType">
    <rant>iana-en:111</rant>
    <name>EGR_RTE_01</name>
    <type>EgrRte</type>
   </objKey>
  </urn:spppGetRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response πŸ’–

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <S:Body>
  <ns3:spppGetResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <overallResult>
    <code>1000</code>
    <msg>success</msg>
   </overallResult>
   <resultObj xsi:type="ns2:EgrRteType">
    <ns2:rant>iana-en:222</ns2:rant>
    <ns2:rar>iana-en:223</ns2:rar>
    <ns2:cDate>2012-10-22T09:30:10Z</ns2:cDate>
    <ns2:egrRteName>EGR_RTE_01</ns2:egrRteName>
    <ns2:pref>50</ns2:pref>
    <ns2:regxRewriteRule>
     <ns2:ere>^(.*)$</ns2:ere>
     <ns2:repl>sip:\1@sbe1.ssp1.example.com</ns2:repl>
    </ns2:regxRewriteRule>
    <ns2:ingrSedGrp xsi:type="ns3:ObjKeyType">
     <rant>iana-en:222</rant>
     <name>SED_GRP_SSP2_1</name>
     <type>SedRec</type>
    </ns2:ingrSedGrp>
   </resultObj>
  </ns3:spppGetResponse>
 </S:Body>
</S:Envelope>

10.18. Delete Destination Group πŸ—‘οΈ

SSP2 starts a request to delete the Destination Group DEST_GRP_SSP2_1 πŸ₯€

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppDelRequest>
    <!--1 or more repetitions:-->
   <objKey xsi:type="urn:ObjKeyType">
    <rant>iana-en:222</rant>
    <name>DEST_GRP_SSP2_1</name>
    <type>DestGrp</type>
   </objKey>
  </urn:spppDelRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response πŸ“

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppDelResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <serverTransId>tx_12354</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppDelResponse>
 </S:Body>
</S:Envelope>

10.19. Delete Public Identifier πŸ“΅

SSP2 decides to deactivate the TN and remove it from the Registry, bye bye πŸ‘‹

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppDelRequest>
   <!--1 or more repetitions:-->
   <objKey xsi:type="urn:PubIdKeyType">
    <rant>iana-en:222</rant>
    <number>
     <urn1:value>+12025556666</urn1:value>
     <urn1:type>TN</urn1:type>
    </number>
   </objKey>
  </urn:spppDelRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response 🌷

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppDelResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <serverTransId>tx_12354</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppDelResponse>
 </S:Body>
</S:Envelope>

10.20. Delete SED Group Request 🫧

SSP2 removes the SED Group called SED_GRP_SSP2_1 πŸ’…βœ¨

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppDelRequest>
    <!--1 or more repetitions:-->
   <objKey xsi:type="urn:ObjKeyType">
    <rant>iana-en:222</rant>
    <name>SED_GRP_SSP2_1</name>
    <type>SedGrp</type>
   </objKey>
  </urn:spppDelRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response πŸŽ€

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppDelResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <serverTransId>tx_12354</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppDelResponse>
 </S:Body>
</S:Envelope>

10.21. Delete SED Group Offers Request πŸ—‘οΈβœ¨

okay so SSP2 is like "nah, I'm done sharing SED Group SED_GRP_SSP2_1 with SSP1" πŸ’… and here's how that looks in the XML:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppDelRequest>
    <!--1 or more repetitions:-->
   <objKey xsi:type="urn:SedGrpOfferKeyType">
    <sedGrpKey>
     <rant>iana-en:222</rant>
     <name>SED_GRP_SSP2_1</name>
     <type>SedGrp</type>
    </sedGrpKey>
    <offeredTo>iana-en:111</offeredTo>
   </objKey>
  </urn:spppDelRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and sends back a favorable response πŸŽ‰ Restoring this resource sharing will require a new SED Group Offer from SSP2 to SSP1, followed by a successful SED Group Accept request from SSP1. So it's not a permanent breakup, bestie, but you do have to go through the whole process again 🫢

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppDelResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <serverTransId>tx_12354</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppDelResponse>
 </S:Body>
</S:Envelope>

10.22. Delete Egress Route πŸ›£οΈπŸ’€

SSP1 decides to remove the Egress Route with the label EGR_RTE_01. bye bye, route 😭

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppDelRequest>
   <!--1 or more repetitions:-->
   <objKey xsi:type="urn:ObjKeyType">
    <rant>iana-en:111</rant>
    <name>EGR_RTE_01</name>
    <type>EgrRte</type>
   </objKey>
  </urn:spppDelRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response ✨

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppDelResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <serverTransId>tx_12354</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppDelResponse>
 </S:Body>
</S:Envelope>

10.23. Batch Request πŸ“¦πŸŒˆ

okay this one is the main character moment πŸ‘‘ Following is an example of how some of the operations from the previous sections MAY be performed by an SPPF client as a batch, all inside one single SPPP over SOAP request. Batching is giving efficiency 🧚

In this sample request, SSP1 wants to do a whole bunch of things at once: accept a SED Group Offer from SSP3, add a Destination Group, add a Naming Authority Pointer (NAPTR) SED Record, add a SED Group, add a SED Group Offer, delete a previously provisioned TN type Public Identifier, delete a previously provisioned SED Group, and reject a SED Group Offer from SSP4. Literally so much in one go 😭πŸ”₯

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:urn="urn:ietf:params:xml:ns:sppf:soap:1"
 xmlns:urn1="urn:ietf:params:xml:ns:sppf:base:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header/>
 <soapenv:Body>
  <urn:spppBatchRequest>
   <clientTransId>txn_1467</clientTransId>
   <minorVer>1</minorVer>

   <acceptSedGrpOffer>
    <sedGrpKey>
     <rant>iana-en:225</rant>
     <name>SED_SSP3_SBE1_Offered</name>
     <type>SedGrp</type>
    </sedGrpKey>
    <offeredTo>iana-en:222</offeredTo>
   </acceptSedGrpOffer>

   <addObj xsi:type="urn1:DestGrpType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
   </addObj>

   <addObj xsi:type="urn1:NAPTRType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:sedName>SED_SSP2_SBE2</urn1:sedName>
    <urn1:order>10</urn1:order>
    <urn1:flags>u</urn1:flags>
    <urn1:svcs>E2U+sip</urn1:svcs>
    <urn1:regx>
     <urn1:ere>^(.*)$</urn1:ere>
     <urn1:repl>sip:\1@sbe2.ssp2.example.com</urn1:repl>
    </urn1:regx>
   </addObj>

   <addObj xsi:type="urn1:SedGrpType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:sedGrpName>SED_GRP_SSP2_1</urn1:sedGrpName>
    <urn1:sedRecRef>
     <urn1:sedKey xsi:type="urn:ObjKeyType">
      <rant>iana-en:222</rant>
      <name>SED_SSP2_SBE2</name>
      <type>SedRec</type>
     </urn1:sedKey>
    <urn1:priority>100</urn1:priority>
    </urn1:sedRecRef>
     <urn1:dgName>DEST_GRP_SSP2_1</urn1:dgName>
     <urn1:isInSvc>true</urn1:isInSvc>
     <urn1:priority>10</urn1:priority>
   </addObj>

   <addObj xsi:type="urn1:SedGrpOfferType">
    <urn1:rant>iana-en:222</urn1:rant>
    <urn1:rar>iana-en:223</urn1:rar>
    <urn1:sedGrpOfferKey xsi:type="urn:SedGrpOfferKeyType">
     <sedGrpKey xsi:type="urn:ObjKeyType">
      <rant>iana-en:222</rant>
      <name>SED_GRP_SSP2_1</name>
      <type>SedGrp</type>
     </sedGrpKey>
     <offeredTo>iana-en:111</offeredTo>
    </urn1:sedGrpOfferKey>
    <urn1:status>offered</urn1:status>
    <urn1:offerDateTime>
     2006-05-04T18:13:51.0Z
    </urn1:offerDateTime>
   </addObj>

   <delObj xsi:type="urn:PubIdKeyType">
    <rant>iana-en:222</rant>
    <number>
     <urn1:value>+12025556666</urn1:value>
     <urn1:type>TN</urn1:type>
    </number>
   </delObj>
   <delObj xsi:type="urn:ObjKeyType">
    <rant>iana-en:222</rant>
    <name>SED_GRP_SSP2_Previous</name>
    <type>SedGrp</type>
   </delObj>

   <rejectSedGrpOffer>
    <sedGrpKey>
     <rant>iana-en:226</rant>
     <name>SED_SSP4_SBE1_Offered</name>
     <type>SedGrp</type>
    </sedGrpKey>
    <offeredTo>iana-en:222</offeredTo>
   </rejectSedGrpOffer>

  </urn:spppBatchRequest>
 </soapenv:Body>
</soapenv:Envelope>

The Registry completes the request successfully and returns a favorable response πŸ₯Ή

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope
 xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns3:spppBatchResponse
   xmlns:ns2="urn:ietf:params:xml:ns:sppf:base:1"
   xmlns:ns3="urn:ietf:params:xml:ns:sppf:soap:1">
   <serverTransId>tx_12354</serverTransId>
   <overallResult>
    <code>1000</code>
    <msg>Request Succeeded.</msg>
   </overallResult>
  </ns3:spppBatchResponse>
 </S:Body>
</S:Envelope>

11. Security Considerations πŸ”πŸ«Ά

bestie, this part is serious, so listen up πŸ‘€ The base security considerations of SPPP outlined in Section 9 of [RFC7877] also apply to SPPP over SOAP implementations. On top of that, the following must be considered:

SPPP over SOAP is used to query and update session peering data and addresses, so the ability to access this protocol should be limited to users and systems that are authorized to query and update this data. Because this data is sent in both directions, it may not be sufficient for just the client or user to be authenticated with the server. The identity of the server should also be authenticated by the client, which is often accomplished using the TLS certificate exchange and validation described in [RFC2818].

11.1. Vulnerabilities 😱

Section 5 describes the use of HTTP and TLS as the underlying substrate protocols for SPPP over SOAP. These underlying protocols may have various vulnerabilities, and these may be inherited by SPPP over SOAP. SPPP over SOAP itself may have vulnerabilities because an authorization model is not explicitly specified in this document. πŸ’€

During a TLS handshake, TLS servers can optionally request a certificate from a TLS client, but that option is not a requirement for this protocol. This presents a denial-of-service risk in which unauthenticated clients can consume server CPU resources by creating TLS sessions. The risk is increased if the server supports client-initiated renegotiation. This risk can be mitigated by disabling client-initiated renegotiation on the server and by ensuring that other means (such as firewall access control lists) are used to restrict unauthenticated client access to servers.

In conjunction with the above, it is important that SPPP over SOAP implementations implement an authorization model that considers the source of each query or update request and determines whether it is reasonable to authorize that source to perform that specific query or update. Authorization is a whole vibe, and it's non-negotiable πŸ™…β€β™€οΈ

12. IANA Considerations πŸ“š

This document uses URNs to describe XML Namespaces and XML Schemas. According to [RFC3688], IANA has performed the following URN assignment:

URN: urn:ietf:params:xml:ns:sppf:soap:1

Registrant Contact: IESG

XML: See Section 9 of [RFC7878]

13. References πŸ—‚οΈ

13.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <http://www.rfc-editor.org/info/rfc2119>.

[RFC3688]  Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
           DOI 10.17487/RFC3688, January 2004,
           <http://www.rfc-editor.org/info/rfc3688>.

[RFC5246]  Dierks, T. and E. Rescorla, "The Transport Layer Security
           (TLS) Protocol Version 1.2", RFC 5246,
           DOI 10.17487/RFC5246, August 2008,
           <http://www.rfc-editor.org/info/rfc5246>.

[RFC7230]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
           Protocol (HTTP/1.1): Message Syntax and Routing",
           RFC 7230, DOI 10.17487/RFC7230, June 2014,
           <http://www.rfc-editor.org/info/rfc7230>.

[RFC7231]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
           Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
           DOI 10.17487/RFC7231, June 2014,
           <http://www.rfc-editor.org/info/rfc7231>.

[RFC7235]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
           Protocol (HTTP/1.1): Authentication", RFC 7235,
           DOI 10.17487/RFC7235, June 2014,
           <http://www.rfc-editor.org/info/rfc7235>.

[RFC7525]  Sheffer, Y., Holz, R., and P. Saint-Andre,
           "Recommendations for Secure Use of Transport Layer
           Security (TLS) and Datagram Transport Layer Security
           (DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May
           2015, <http://www.rfc-editor.org/info/rfc7525>.

[RFC7877]  Cartwright, K., Bhatia, V., Ali, S., and D. Schwartz,
           "Session Peering Provisioning Framework (SPPF)", RFC 7877,
           DOI 10.17487/RFC7877, August 2016,
           <http://www.rfc-editor.org/info/rfc7877>.

[SOAPREF]  Gudgin, M., Hadley, M., Moreau, J., and H. Nielsen, "SOAP
           Version 1.2 Part 1: Messaging Framework (Second Edition)",
           W3C Recommendation REC-SOAP12-part1-20070427, April 2007,
           <http://www.w3.org/TR/soap12-part1/>.

13.2. Informative References πŸ“š

Okay bestie, these are the extra-credit reads, the stuff the spec points to for background without actually needing it to work πŸ’… Each one gets its full details below, so you can go find them yourself. πŸ¦‹


Acknowledgements 🌸

This document grew out of a bunch of chats with the IETF DRINKS working group, especially the protocol design team 🫢 Huge thank-yous go to everyone who chipped in, listed here in alphabetical order: Syed Ali, Vikas Bhatia, Kenneth Cartwright, Sumanth Channabasappa, Lisa Dusseault, Deborah A. Guyton, Scott Hollenbeck, Otmar Lendl, Manjul Maharishi, Mickael Marrache, Alexander Mayrhofer, Samuel Melloul, Jean-Francois Mule, Peter Saint-Andre, David Schwartz, and Richard Shockey. You all ate this up πŸ‘‘


Authors' Addresses πŸ¦‹

The people who wrote this, and where to find them:

Kenneth Cartwright
TNS
10740 Parkridge Boulevard
Reston, VA  20191
United States

Email: kcartwright@tnsi.com
Vikas Bhatia
TNS
10740 Parkridge Boulevard
Reston, VA  20191
United States

Email: vbhatia@tnsi.com
Jean-Francois Mule
Apple Inc.
1 Infinite Loop
Cupertino, CA  95014
United States

Email: jfmule@apple.com
Alexander Mayrhofer
nic.at GmbH
Karlsplatz 1/2/9
Wien  A-1010
Austria

Email: alexander.mayrhofer@nic.at
πŸ“¦ where this page comes from