Skip to content

Peering API

ETSI HypO may need to interact with multiple OSS systems (i.e., domains), where different types of resources could be ordered. For this reason, it is important to develop a peering mechanism that allows dynamic interaction with every OSS instance to: (i) verify the availability of the peered OSS (is it alive or not?), (ii) dynamically cherry-pick the desired service specifications from an underlying OSS and import them to the ETSI HypO catalog, while (iii) removing these service specifications from the TMF API catalog once the underlying OSS becomes unavailable or the ETSI HypO administrator desires to stop the peering process.

The peering process takes place in 3 steps:

Step 1. Create a TMF Party Organization

Before ETSI HypO peers with an underlying OSS, it needs to define who is the stakeholder behind this OSS instance. For this reason, TMF has defined the notion of a “Party”, which can be either individual or organization. That said, the first step before starting the peering process is the creation of a TMF party organization behind an OSS instance. ETSI HypO implements this via TMF's Party Management API (TMF632). Every OSS is encoded as an organization with specific party characteristics. The following example shows how we should configure these party characteristics to peer with an ETSI OpenSlice OSS:

EXTERNAL_TMF_API_BASE_URL: "[http://portal.openslice.eu](http://portal.openslice.eu)"
EXTERNAL_TMF_API_CLIENT_REGISTRATION_ID: "authOpensliceProvider"
EXTERNAL_TMF_API_OAUTH2_CLIENT_ID: "osapiWebClientId"
EXTERNAL_TMF_API_OAUTH2_CLIENT_SECRET: "secret"
EXTERNAL_TMF_API_OAUTH2_SCOPES: "admin;read"
EXTERNAL_TMF_API_OAUTH2_TOKEN_URI: "[http://portal.openslice.eu/auth/realms/openslice/protocol/openid-connect/token](http://portal.openslice.eu/auth/realms/openslice/protocol/openid-connect/token)"
EXTERNAL_TMF_API_USERNAME: "admin"
EXTERNAL_TMF_API_PASSWORD: "openslice"

The user starts by creating a TMF Party Organization by sending a POST request with the following payload to /tmf-api/party/v4/organization:

{
  "@baseType": "BaseEntity",
  "@schemaLocation": null,
  "@type": null,
  "href": null,
  "name": "Openslice-dev",
  "isHeadOffice": null,
  "isLegalEntity": null,
  "nameType": null,
  "organizationType": null,
  "tradingName": null,
  "contactMedium": [
    {
      "id": "32f05499-e187-40f4-b109-bfa16d2ee8e2",
      "preferred": false,
      "validFor": {
        "endDateTime": "2027-10-22T08:31:52.026Z",
        "startDateTime": "2018-10-22T08:31:52.028Z"
      },
      "@type": "GeographicAddressContactMedium",
      "city": "Patras",
      "country": "Greece",
      "postCode": "",
      "stateOrProvince": "",
      "street1": "",
      "street2": ""
    },
    {
      "id": "8e0021d8-300c-4ca1-9c94-38082693d8e9",
      "preferred": true,
      "validFor": {
        "endDateTime": "2027-10-22T08:31:52.026Z",
        "startDateTime": "2018-10-22T08:31:52.028Z"
      },
      "@type": "EmailContactMedium"
    }
  ],
  "creditRating": [],
  "existsDuring": null,
  "externalReference": [],
  "organizationChildRelationship": [],
  "organizationIdentification": [],
  "organizationParentRelationship": null,
  "otherName": [],
  "partyCharacteristic": [
    {
      "id": "94cff4b5-fbdb-4f86-b916-f318fda1ebb5",
      "value": {
        "value": "openslice",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_PASSWORD",
      "@baseType": "BaseEntity"
    },
    {
      "id": "2240d565-2882-4502-9730-7e3e452a0952",
      "valueType": "boolean",
      "value": {
        "value": "true",
        "alias": null
      },
      "name": "PEERED_ORGANIZATION",
      "@baseType": "BaseEntity"
    },
    {
      "id": "8f5c5995-8ed3-433f-9811-8837820d622f",
      "value": {
        "value": "admin",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_USERNAME",
      "@baseType": "BaseEntity"
    },
    {
      "id": "17b1b1a4-31da-4206-b852-7a2179e005c6",
      "value": {
        "value": "[http://portal.openslice.eu](http://portal.openslice.eu)",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_BASE_URL",
      "@baseType": "BaseEntity"
    },
    {
      "id": "bc6ad912-61b7-4636-b489-84c8d5480c63",
      "value": {
        "value": "http://portal.openslice.eu/auth/realms/openslice/protocol/openid-connect/token",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_OAUTH2_TOKEN_URI",
      "@baseType": "BaseEntity"
    },
    {
      "id": "39d57e19-738e-4bb9-adce-5f89b8ba81da",
      "value": {
        "value": "admin;read",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_OAUTH2_SCOPES",
      "@baseType": "BaseEntity"
    },
    {
      "id": "00e4c67d-4209-4847-951d-d30c661185f9",
      "value": {
        "value": "authOpensliceProvider",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_CLIENT_REGISTRATION_ID",
      "@baseType": "BaseEntity"
    },
    {
      "id": "af75816a-4134-40ec-ab2f-ebaf397506e9",
      "value": {
        "value": "osapiWebClientId",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_OAUTH2_CLIENT_ID",
      "@baseType": "BaseEntity"
    },
    {
      "id": "6838dbba-52a9-4474-a65c-661e850c2b8e",
      "value": {
        "value": "secret",
        "alias": null
      },
      "name": "EXTERNAL_TMF_API_OAUTH2_CLIENT_SECRET",
      "@baseType": "BaseEntity"
    }
  ],
  "relatedParty": [],
  "status": null,
  "taxExemptionCertificate": []
}

Step 2. Peering API Invocation

The peering process continues by posting the following request to the Peering API endpoint /peering-api/peering. Note that the organization in the following is the full TMF API response and not the string which is presented here for simplicity.

{
  "organization": "$organizationTmfAPIResponse$",
  "serviceSpecs": {},
  "peeredSpecs": {},
  "serviceCatalogs": []
}

Upon the success of step 2, the response contains a list of service specifications

[
  {
    "href": null,
    "description": "GST external example",
    "version": "5.0.0",
    "validFor": null,
    "name": "A GST(NEST) Service Example",
    "lastUpdate": "2024-04-26T11:00:56Z",
    "lifecycleStatus": "In study",
    "isBundle": false,
    "featureSpecification": [],
    "resourceSpecification": [],
    "serviceLevelSpecification": [],
    "attachment": [],
    "constraint": [],
    "entitySpecRelationship": [],
    "relatedParties": [],
    "serviceSpecRelationshipSet": [],
    "serviceSpecCharacteristics": [],
    "targetServiceSchemaRefEntity": null,
    "id": "e04843a6-8ec4-4493-b192-7506fc3e08ca",
    "@baseType": null,
    "@schemaLocation": null,
    "@type": "CustomerFacingServiceSpecification"
  },
  {
    "href": null,
    "description": null,
    "version": "0.1.0",
    "validFor": null,
    "name": "K8aaS",
    "lastUpdate": "2025-03-18T09:12:53Z",
    "lifecycleStatus": "In design",
    "isBundle": true,
    "featureSpecification": [],
    "resourceSpecification": [],
    "serviceLevelSpecification": [],
    "attachment": [],
    "constraint": [],
    "entitySpecRelationship": [],
    "relatedParties": [],
    "serviceSpecRelationshipSet": [],
    "serviceSpecCharacteristics": [],
    "targetServiceSchemaRefEntity": null,
    "id": "c04f3d66-5350-49ea-8b31-ff325f149232",
    "@baseType": null,
    "@schemaLocation": null,
    "@type": "CustomerFacingServiceSpecification"
  }
]

Step 3. Peering Configuration

The user selects the specifications needed for peering, and optionally, categories and/or catalogs he/she wishes to store these specifications. Then, a POST request must be issued to /peering-api/peering/add as follows:

{
  "organization": "organizationResponseFromStep1",
  "serviceSpecs": {
    "c04f3d66-5350-49ea-8b31-ff325f149232": "K8aaS"
  },
  "peeredSpecs": {},
  "serviceCatalogs": [
    {
      "name": "test-peer-catalog",
      "categories": [
        {
          "name": "test-peer-category",
          "specifications": [
            "K8aaS"
          ]
        }
      ]
    }
  ]
}

This operation will lead to retrieving the specifications from OpenSlice and then pass to TMF-API by publishing a message to the KAFKA topic tmf-api-peered-organization-service-specs.

These steps conclude the peering process.

In case there is a need to remove the peered organization, the user should clean up the data entries with the following order:

  • Remove the peering data. Perform a DELETE operation: /peering-api/peering/{organizationId}
  • Verify the deletion with the following GET operation: /peering-api/peering/{organizationId}
  • Then remove the organization from the TMF API as well. Perform a DELETE operation: /tmf-api/party/v4/organization/{organizationId}

Heartbeat mechanism

When peering with an external OSS there is a risk that after a while it might not be reachable or the provided specifications might have changed. We need such changes to be reflected in the Marketplace so a user can only make a service order to an active OSS with available and up-to-date specifications. To realize the above, a heartbeat mechanism is introduced that periodically ensures the peered OSS organizations are reachable. This is performed via a cron job where the heartbeat time between the keep alive sessions is configurable. This healthcheck ensures that the peered OSS is reachable by fetching the peered specifications that the user has chosen in the initial peering request. Afterwards any updates are propagated to the TMF API via the KAFKA topic updated-peered-organization-service-specs.

API Endpoints Summary

Method Endpoint Description Response Codes Auth Roles Leads to
GET /peering-api/peering List all peering resources 200, 401, 403 admin Retrieval of all active peerings from database
POST /peering-api/peering Create a new peering resource 200, 401, 403 admin A REST API call to OSL to fetch all the specification ids
POST /peering-api/peering/add Add a peering resource 200, 401, 403 admin A REST API call to OSL per chosen specification id to retrieve and then send it via kafka topic tmf-api-peered-organization-service-specs
GET /peering-api/peering/{id} Get peering resource by ID 200, 401, 403 admin Retrieval of a specific peering from database
PATCH /peering-api/peering/{id} Update a peering resource 200, 401, 403 admin Fetching the new specs from a REST call to OSL and then sends the update via kafka topic updated-peered-organization-service-specs
DELETE /peering-api/peering/{id} Delete a peering resource 200, 401, 403 admin Removal of a peered organization specs via kafka topic east-west-peering-termination

Kafka topics Summary

TOPIC Consumer Description
tmf-api-peered-organization-service-specs TMF-API Sends the specifications fetched from peering
updated-peered-organization-service-specs TMF-API Sends the updated peered specifications
east-west-peering-failure TMF-API Sends a message to inform that the peering failed
east-west-peering-termination TMF-API Sends a message for peering termination and removal of peered specs
peered-organization-heartbeat-failure TMF-API Sends a message to inform that the peered organization is no longer reachable
alarm-management-channel TMF-API Raises an alarm about peering failures