From a775e4519d1f109bc83029538815ab3a6c9b560f Mon Sep 17 00:00:00 2001 From: cmhkknight Date: Thu, 30 Apr 2026 11:45:49 +0800 Subject: [PATCH 1/4] Add files via upload --- .../API-proposal-user experience insights.md | 48 + ...ser-experience-insights-subscriptions.yaml | 1217 +++++++++++++++++ documentation/user-experience-insights.yaml | 995 ++++++++++++++ 3 files changed, 2260 insertions(+) create mode 100644 documentation/API-proposal-user experience insights.md create mode 100644 documentation/user-experience-insights-subscriptions.yaml create mode 100644 documentation/user-experience-insights.yaml diff --git a/documentation/API-proposal-user experience insights.md b/documentation/API-proposal-user experience insights.md new file mode 100644 index 0000000..6c6a724 --- /dev/null +++ b/documentation/API-proposal-user experience insights.md @@ -0,0 +1,48 @@ +# API Proposal Template +This template captures all the information that a partner should fill out when proposing a new API (or API family) to CAMARA. + + +### API family name +User Experience Insights (UEI) + +### API family owner +China Mobile Hong Kong, Huawei + +### API summary +This API allows Application Functions (AF) to subscribe to real-time network experience notifications for specific users. The API leverages the analytics capabilities of the NWDAF (Network Data Analytics Function) and exposes them through the NEF (Network Exposure Function). When a user's network experience (e.g., throughput, latency, or reliability) falls below a predefined threshold or changes significantly, the network proactively notifies the AF. + +In-scope business cases: + +VIP Customer Care & Proactive Intervention: Operator customer service systems can monitor high-value users' real-time experience. If a degradation is detected, the system can trigger automated "care" actions (e.g., issuing temporary vouchers or prioritizing technical support) before the user even files a complaint. + +Adaptive Application Logic: Streaming or gaming applications can use this API to receive proactive alerts about user experience trends, allowing them to adjust application-level parameters (like bitrates or buffering strategies) ahead of time. + +SLA Monitoring for Enterprise Services: Enterprises can subscribe to experience insights for their workforce to ensure critical remote-working applications meet the required performance standards. + +### Technical viability +This API is technically viable based on 3GPP 5G core network standards: + +3GPP TS 23.288 (NWDAF): Utilizes the "User Data Congestion" and "Service Experience" analytics ID. + +3GPP TS 23.502 / TS 29.522 (NEF): Requires NEF to support the exposure of analytics via Nnef_EventExposure or Nnef_AnalyticsExposure services. + +Maturity: These features are part of 3GPP Release 16/17, which are currently being deployed in commercial 5G SA networks. + +### Commercial viability +The underlying network capabilities (NEF and NWDAF) are now widely available as industrialized solutions. Many Tier-1 operators have already deployed NWDAF for internal network optimization and are moving towards external exposure of these insights to enhance ecosystem value. + +### YAML code available? +YES. + +### Validated in lab/productive environments? +YES. Validated in a lab environment simulating 5G SA core network signaling with actual NWDAF analytics triggers. + +### Validated with real customers? +No. + +### Validated with operators? +No. + +### Supporters in API Backlog Working Group +List of supporters. +*NOTE: That shall be added by the Working Group. Supporting an API proposal means that the supporting company must provide at least 1 (one) Maintainer at the time of the Sub Project creation.* diff --git a/documentation/user-experience-insights-subscriptions.yaml b/documentation/user-experience-insights-subscriptions.yaml new file mode 100644 index 0000000..8722279 --- /dev/null +++ b/documentation/user-experience-insights-subscriptions.yaml @@ -0,0 +1,1217 @@ +openapi: 3.0.3 +info: + title: User Experience Insights + version: wip + x-camara-commonalities: 0.6 + description: | + With CAMARA User Experience Insights subscription service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. + + # Introduction + + The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. + + This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. + + This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. + + This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. + + for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. + # Relevant terms and definitions + + * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. + + # API functionality + The API provides the datatype parameter to report network quality at different granularities. Poor-QoE events are reported in real time when the network detects poor-QoE events. + + This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). + + This API provides the function of reporting poor-QoE data in real time or periodically reporting no poor-QoE data based on the datatype parameter. + POOR_QOE_REPORT Detects poor network experience and reports the collected statistical data. + PERIODIC_REPORT Periodically collecting and reporting data. + ALL Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. + + + ### Notification callback + + This endpoint describes the event notification received on subscription listener side when the event occurred. + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +externalDocs: + description: Product documentation at CAMARA. + url: https://github.com/camaraproject/UserExperienceInsights + +servers: + - url: "{apiRoot}/user-experience-insights" + variables: + apiRoot: + default: http://localhost:9091 + description: | + API root, defined by service provider, e.g. + `api.example.com` or `api.example.com/somepath` + +tags: + - name: User Experience Insights + description: | + Create and manage a subscription to receive periodic connectivity + insights + +paths: + /subscriptions: + post: + tags: + - User Experience Insights + description: "Create a User Experience Insights Subscription for a device" + summary: "Create a User Experience Insights Subscription for a device" + operationId: createSubscription + parameters: + - $ref: "#/components/parameters/x-correlator" + security: + - openId: + - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:create + + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionRequest" + required: true + callbacks: + notifications: + "{$request.body#/sink}": + post: + summary: "Subscription notification callback" + description: | + Important: this endpoint is to be implemented by the API + consumer.The User Experience Insights server will call this + endpoint whenever a connectivity event occurs that changes + the network's ability to meet the application's demands for + a given device. + operationId: postNotification + parameters: + - $ref: "#/components/parameters/x-correlator" + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CloudEvent" + required: true + responses: + "201": + description: Successful notification + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + "400": + $ref: "#/components/responses/Generic400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "410": + $ref: "#/components/responses/Generic410" + "429": + $ref: "#/components/responses/Generic429" + security: + - {} + - notificationsBearerAuth: [] + responses: + "201": + description: Created + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionAsync" + "400": + $ref: "#/components/responses/CreateSubscriptionBadRequest400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/SubscriptionPermissionDenied403" + "409": + $ref: "#/components/responses/Generic409" + "422": + $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" + "429": + $ref: "#/components/responses/Generic429" + /subscriptions/{subscriptionId}: + get: + tags: + - User Experience Insights + summary: "Operation to retrieve a subscription based on the provided ID" + operationId: getSubscription + description: Retrieve a given subscription by ID + security: + - openId: + - connectivity-insights-subscriptions:read + parameters: + - $ref: "#/components/parameters/SubscriptionId" + - $ref: "#/components/parameters/x-correlator" + responses: + "200": + description: OK + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/Subscription" + "400": + $ref: "#/components/responses/SubscriptionIdRequired400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "404": + $ref: "#/components/responses/Generic404" + delete: + tags: + - User Experience Insights + summary: "Operation to delete a subscription" + operationId: deleteSubscription + description: Delete a given subscription by ID + security: + - openId: + - user-experience-insights:delete + parameters: + - $ref: "#/components/parameters/SubscriptionId" + - $ref: "#/components/parameters/x-correlator" + responses: + "204": + description: apiName subscription deleted + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + "202": + description: | + Request accepted to be processed. It applies for async deletion + process. + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionAsync" + "400": + $ref: "#/components/responses/SubscriptionIdRequired400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "404": + $ref: "#/components/responses/Generic404" + +components: + securitySchemes: + openId: + type: openIdConnect + description: Common security scheme for all CAMARA APIs + openIdConnectUrl: https://example.com/.well-known/openid-configuration + notificationsBearerAuth: + description: Bearer authorization for notifications + type: http + scheme: bearer + bearerFormat: "{$request.body#/sinkCredential.credentialType}" + parameters: + SubscriptionId: + name: subscriptionId + in: path + description: | + Subscription identifier that was obtained from the create event + subscription operation + required: true + schema: + $ref: "#/components/schemas/SubscriptionId" + x-correlator: + name: x-correlator + in: header + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + headers: + x-correlator: + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + schemas: + XCorrelator: + type: string + pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ + example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" + Subscription: + description: Represents a event-type subscription. + type: object + required: + - sink + - protocol + - config + - types + - id + - startsAt + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + config: + $ref: "#/components/schemas/Config" + subscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + startsAt: + type: string + format: date-time + description: Date when the event subscription will begin/began + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + expiresAt: + type: string + format: date-time + description: | + Date when the event subscription will expire. Only provided when + `subscriptionExpireTime` is indicated by API client or Telco + Operator has specific policy about that. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + status: + type: string + description: |- + Current status of the subscription - Management of Subscription + State engine is not mandatory for now. Note not all statuses may + be considered to be implemented. Details: + - `ACTIVATION_REQUESTED`: Subscription creation (POST) is + triggered but subscription creation process is not finished + yet. + - `ACTIVE`: Subscription creation process is completed. + Subscription is fully operative. + - `DEACTIVE`: Subscription is temporarily inactive, but its + workflow logic is not deleted. + - `EXPIRED`: Subscription is ended (no longer active). + This status applies when subscription is ended due to + `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. + - `DELETED`: Subscription is ended as deleted (no longer + active). This status applies when subscription information is + kept (i.e. subscription workflow is no longer active but its + metainformation is kept). + enum: + - ACTIVATION_REQUESTED + - ACTIVE + - EXPIRED + - DEACTIVE + - DELETED + discriminator: + propertyName: protocol + mapping: + HTTP: "#/components/schemas/HTTPSubscriptionResponse" + MQTT3: "#/components/schemas/MQTTSubscriptionResponse" + MQTT5: "#/components/schemas/MQTTSubscriptionResponse" + AMQP: "#/components/schemas/AMQPSubscriptionResponse" + NATS: "#/components/schemas/NATSSubscriptionResponse" + KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" + + SubscriptionAsync: + description: | + Response for a event-type subscription request managed asynchronously + (Creation or Deletion) + type: object + properties: + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + + SubscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + Device: + description: | + End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + * `phoneNumber` + * `networkAccessIdentifier` + NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. + type: object + properties: + phoneNumber: + $ref: "#/components/schemas/PhoneNumber" + networkAccessIdentifier: + $ref: "#/components/schemas/NetworkAccessIdentifier" + ipv4Address: + $ref: "#/components/schemas/DeviceIpv4Addr" + ipv6Address: + $ref: "#/components/schemas/DeviceIpv6Address" + minProperties: 1 + + NetworkAccessIdentifier: + description: | + A public identifier addressing a subscription in a mobile network. In + 3GPP terminology, it corresponds to the GPSI formatted with the + External Identifier ({Local Identifier}@{Domain Identifier}). Unlike + the telephone number, the network access identifier is not subjected + to portability ruling in force, and is individually managed by each + operator. + type: string + example: "123456789@domain.com" + + PhoneNumber: + description: | + A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN (Mobile Station International + Subscriber Directory Number). In order to be globally unique it has to + be formatted in international format, according to E.164 standard, + prefixed with '+'. + type: string + pattern: '^\+[1-9][0-9]{4,14}$' + example: "+123456789" + + DeviceIpv4Addr: + type: object + description: | + The device should be identified by either the public (observed) IP + address and port as seen by the application server, or the private + (local) and any public (observed) IP addresses in use by the device + (this information can be obtained by various means, for example from + some DNS servers). + + If the allocated and observed IP addresses are the same (i.e. NAT is + not in use) then the same address should be specified for both + publicAddress and privateAddress. + + If NAT64 is in use, the device should be identified by its + publicAddress and publicPort, or separately by its allocated IPv6 + address (field ipv6Address of the Device object) + + In all cases, publicAddress must be specified, along with at least one + of either privateAddress or publicPort, dependent upon which is known. + In general, mobile devices cannot be identified by their public IPv4 + address alone. + properties: + publicAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + privateAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + publicPort: + $ref: "#/components/schemas/Port" + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + example: {"publicAddress":"84.125.93.10", "publicPort":59765} + + SingleIpv4Addr: + description: A single IPv4 address with no subnet mask + type: string + format: ipv4 + example: "84.125.93.10" + + DeviceIpv6Address: + description: | + The device should be identified by the observed IPv6 address, or by any + single IPv6 address from within the subnet allocated to the device + (e.g. adding ::0 to the /64 prefix). + + The session shall apply to all IP flows between the device subnet and + the specified application server, unless further restricted by the + optional parameters devicePorts or applicationServerPorts. + type: string + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + + Port: + description: TCP or UDP port number + type: integer + minimum: 0 + maximum: 65535 + Protocol: + type: string + enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] + description: | + Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + Config: + description: | + Implementation-specific configuration parameters needed by the + subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`. + Specific event type attributes must be defined in `subscriptionDetail` + Note: if a request is performed for several event type, all subscribed + event will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + $ref: "#/components/schemas/CreateSubscriptionDetail" + subscriptionExpireTime: + type: string + format: date-time + description: | + The subscription expiration time (in date-time format) requested by + the API consumer. Up to API project decision to keep it. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + datatype: + type: string + description: | + POOR_QOE_REPORT: Detects poor network experience and reports the collected statistical data. + PERIODIC_REPORT: Periodically collecting and reporting data. + ALL: Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. + enum: + - POOR_QOE_REPORT + - PERIODIC_REPORT + - ALL + SinkCredential: + type: object + description: | + A sink credential provides authentication or authorization information + properties: + credentialType: + type: string + enum: + - PLAIN + - ACCESSTOKEN + - REFRESHTOKEN + description: | + The type of the credential. + Note: Type of the credential - MUST be set to ACCESSTOKEN for now + discriminator: + propertyName: credentialType + mapping: + PLAIN: "#/components/schemas/PlainCredential" + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" + required: + - credentialType + + CreateSubscriptionDetail: + description: The detail of the requested event subscription + type: object + properties: + device: + description: | + This API need to carry the subscriber's GPSI/MSISDN. + $ref: "#/components/schemas/Device" + appcationType: + description: | + Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/AppcationType" + required: + - device + + SubscriptionRequest: + description: The request for creating a event-type event subscription + type: object + required: + - sink + - protocol + - config + - types + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + sinkCredential: + $ref: "#/components/schemas/SinkCredential" + config: + $ref: "#/components/schemas/Config" + BitRate: + type: string + description: | + String representing a bit rate that shall be formatted as follows: + pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" + Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". + TrafficVolume: + type: string + description: | + String representing a traffic volume measured in bytes that shall be formatted as follows: + Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' + Examples:"125 MB", "0.125 GB", "125000 kB" + Dnn: + type: string + description: | + String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; + it shall contain either a DNN Network Identifier, or a full DNN with both the Network + Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. + It shall be coded as string in which the labels are separated by dots + (e.g. "Label1.Label2.Label3"). + QciOr5qi: + type: integer + description: | + It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). + NetType: + type: string + description: Indicates the type of network accessed. SA/EPC + AppSignalingData: + type: object + description: | + Basic . + properties: + dnn: + $ref: '#/components/schemas/Dnn' + qciOr5qi: + $ref: "#/components/schemas/QciOr5qi" + netType: + $ref: '#/components/schemas/NetType' + VolumeMeasurement: + type: object + description: | + Application-level traffic statistics. + properties: + totalVolume: + description: total running traffic statistics. + $ref: "#/components/schemas/TrafficVolume" + ulVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. + $ref: "#/components/schemas/TrafficVolume" + dlVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. + $ref: "#/components/schemas/TrafficVolume" + ApplicationIndicatorStatistics: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + subAppStartTime: + $ref: "#/components/schemas/DateTime" + subAppEffDur: + type: integer + description: | + Unsigned integer identifying a period of time in units of seconds + avgBwUl: + description: Average uplink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + avgBwDl: + description: Average downlink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + maxBwUl: + description: Maximum uplink bandwidth of the application + $ref: "#/components/schemas/BitRate" + maxBwDl: + description: Maximum downlink bandwidth of the application + $ref: "#/components/schemas/BitRate" + subAppVol: + $ref: "#/components/schemas/VolumeMeasurement" + maxDelayAn: + type: integer + description: | + Maximum wireless-side latency of an application. + maxDelayDn: + type: integer + description: | + Maximum wired-side latency of an application. + ApplicationExperienceAnalysis: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + avgQoe: + type: integer + description: | + Average score of experience analysis.Value range: 1 to 100 points. + maxResolution: + type: string + description: | + Maximum resolution in the experience analysis period. + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + mostResolution: + type: string + description: | + The resolution with the highest duration ratio within the experience analysis perio + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + maxBitRateUl: + description: Maximum uplink bit rate (kbit/s). + $ref: "#/components/schemas/BitRate" + avgBitRateUl: + description: Average uplink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + maxBitRateDl: + description: Maximum downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + avgBitRateDl: + description: Average downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + stallSec: + type: integer + description: Frame freezing duration, in seconds. + stallNum: + type: integer + description: Number of frame freezing times. The detection period is 5 seconds. + serviceDelay: + type: integer + description: Service latency, in seconds. + initialDur: + type: integer + description: | + Initial service buffering duration, in seconds. The options are as follows: + AreaData: + type: object + description: | + Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. + properties: + city: + type: string + description: user's city of residence. + district: + type: string + description: areas or streets within a city. + AppSignalingAndStatisticsAnalysisRecord: + type: object + description: | + the network's confidence level at being able to meet the network + demands of a given application for a given terminal device. + properties: + starttime: + $ref: "#/components/schemas/DateTime" + endtime: + $ref: "#/components/schemas/DateTime" + appcationType: + $ref: "#/components/schemas/AppcationType" + applicationId: + $ref: "#/components/schemas/ApplicationId" + areaData: + $ref: "#/components/schemas/AreaData" + appSignalingData: + $ref: "#/components/schemas/AppSignalingData" + applicationIndicatorStatistics: + $ref: "#/components/schemas/ApplicationIndicatorStatistics" + applicationExperienceAnalysis: + $ref: "#/components/schemas/ApplicationExperienceAnalysis" + UserExperienceInsightsRecords: + type: object + description: | + Application Network Collection and Recording + properties: + appSignalingAndStatisticsAnalysisRecords: + type: array + items: + $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' + minItems: 1 + ApplicationId: + description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + format: uuid + AppcationType: + description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + example: video/game/Live Video + Source: + type: string + format: uri-reference + minLength: 1 + description: | + Identifies the context in which an event happened, as a non-empty + `URI-reference` like: + - URI with a DNS authority: + * https://github.com/cloudevents + * mailto:cncf-wg-serverless@lists.cncf.io + - Universally-unique URN with a UUID: + * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - Application-specific identifier: + * /cloudevents/spec/pull/123 + * 1-555-123-4567 + example: "https://notificationSendServer12.supertelco.com" + CloudEvent: + description: The Cloud-Event used for the callback. + required: + - id + - source + - specversion + - type + - time + properties: + id: + type: string + description: | + identifier of this event, that must be unique in the source context. + source: + $ref: "#/components/schemas/Source" + type: + $ref: "#/components/schemas/EventTypeNotification" + specversion: + type: string + description: | + Version of the specification to which this event conforms (must be + 1.0 if it conforms to cloudevents 1.0.2 version) + enum: + - "1.0" + datacontenttype: + type: string + description: | + 'media-type that describes the event payload encoding, + must be "application/json" for CAMARA APIs' + enum: + - application/json + data: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + time: + $ref: "#/components/schemas/DateTime" + discriminator: + propertyName: "type" + mapping: + org.camaraproject.user-experience-insights.v0.network-quality: + "#/components/schemas/EventNetworkQuality" + org.camaraproject.connectivityinsights.v0.eventSubscriptionEnded: + "#/components/schemas/EventSubscriptionEnded" + + EventNetworkQuality: + description: event structure for Network Quality + allOf: + - $ref: "#/components/schemas/CloudEvent" + - type: object + properties: + data: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + + EventSubscriptionEnded: + description: event structure for event subscription ended + allOf: + - $ref: "#/components/schemas/CloudEvent" + - type: object + properties: + data: + $ref: "#/components/schemas/SubscriptionEnded" + + SubscriptionEnded: + description: Event detail structure for subscription ended event + type: object + required: + - terminationReason + - subscriptionId + properties: + terminationReason: + $ref: "#/components/schemas/TerminationReason" + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + terminationDescription: + description: Explanation why a subscription ended or had to end. + type: string + + TerminationReason: + type: string + description: | + - NETWORK_TERMINATED - API server stopped sending notification + - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by + the requester) has been reached + - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the + requester) has been reached + - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by + the requester) expiration time has been reached + - SUBSCRIPTION_DELETED - Subscription was deleted by the requester + enum: + - MAX_EVENTS_REACHED + - NETWORK_TERMINATED + - SUBSCRIPTION_EXPIRED + - ACCESS_TOKEN_EXPIRED + - SUBSCRIPTION_DELETED + + DateTime: + type: string + format: date-time + description: | + Timestamp of when the occurrence happened. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + + EventTypeNotification: + type: string + description: | + event-type - Event triggered when an event-type event occurred + subscription-ended: Event triggered when the subscription ends + enum: + - org.camaraproject.user-experience-insights.v0.network-quality + - org.camaraproject.user-experience-insights.v0.subscription-ended + ErrorInfo: + type: object + description: Error information + required: + - status + - code + - message + properties: + status: + type: integer + description: HTTP response status code + code: + type: string + description: A human-readable code to describe the error + message: + type: string + description: A human-readable description of what the event represents + + responses: + CreateSubscriptionBadRequest400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + - INVALID_PROTOCOL + - INVALID_CREDENTIAL + - INVALID_TOKEN + - INVALID_SINK + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_INVALID_PROTOCOL: + description: Invalid protocol for events subscription management + value: + status: 400 + code: INVALID_PROTOCOL + message: Only HTTP is supported + GENERIC_400_INVALID_CREDENTIAL: + description: Invalid sink credential type + value: + status: 400 + code: INVALID_CREDENTIAL + message: Only Access token is supported + GENERIC_400_INVALID_TOKEN: + description: Invalid token type for sink credential of type ACCESSTOKEN + value: + status: 400 + code: INVALID_TOKEN + message: Only bearer token is supported + GENERIC_400_INVALID_SINK: + description: Invalid sink value + value: + status: 400 + code: INVALID_SINK + message: sink not valid for the specified protocol + Generic400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + SubscriptionIdRequired400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_SUBSCRIPTION_ID_REQUIRED: + description: subscription id is required + value: + status: 400 + code: INVALID_ARGUMENT + message: "Expected property is missing: subscriptionId" + Generic401: + description: Authentication problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 401 + code: + enum: + - UNAUTHENTICATED + + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. + + Generic403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + SubscriptionPermissionDenied403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + - SUBSCRIPTION_MISMATCH + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + GENERIC_403_SUBSCRIPTION_MISMATCH: + description: Inconsistent access token for requested subscription + value: + status: 403 + code: "SUBSCRIPTION_MISMATCH" + message: "Inconsistent access token for requested events subscription" + Generic404: + description: Resource Not Found + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - NOT_FOUND + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + Generic409: + description: Conflict + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 409 + code: + enum: + - ABORTED + - ALREADY_EXISTS + examples: + GENERIC_409_ABORTED: + description: Concurreny of processes of the same nature/scope + value: + status: 409 + code: ABORTED + message: Concurrency conflict. + GENERIC_409_ALREADY_EXISTS: + description: Trying to create an existing resource + value: + status: 409 + code: ALREADY_EXISTS + message: The resource that a client tried to create already exists. + Generic410: + description: Gone + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 410 + code: + enum: + - GONE + examples: + GENERIC_410_GONE: + description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available + value: + status: 410 + code: GONE + message: Access to the target resource is no longer available. + CreateSubscriptionUnprocessableEntity422: + description: Unprocessable Entity + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNNECESSARY_IDENTIFIER + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 429 + code: + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. \ No newline at end of file diff --git a/documentation/user-experience-insights.yaml b/documentation/user-experience-insights.yaml new file mode 100644 index 0000000..f8421f7 --- /dev/null +++ b/documentation/user-experience-insights.yaml @@ -0,0 +1,995 @@ +openapi: 3.0.3 +info: + title: User Experience Insights + version: wip + x-camara-commonalities: 0.6 + description: | + With CAMARA User Experience Insights service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. + + # Introduction + + The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. + + This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. + + This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. + + This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. + + for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. + # Relevant terms and definitions + + * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. + + # API functionality + + This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). + + + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +externalDocs: + description: Product documentation at CAMARA. + url: https://github.com/camaraproject/UserExperienceInsights + +servers: + - url: "{apiRoot}/user-experience-insights/" + variables: + apiRoot: + default: http://localhost:9091 + description: | + API root, defined by service provider, e.g. + `api.example.com` or `api.example.com/somepath` + +tags: + - name: User Experience Insights + description: | + read User Experience Insights + +paths: + /userexperienceinsights: + post: + tags: + - User Experience Insights + description: "read a User Experience Insights for a device" + summary: "read a User Experience Insights for a device" + operationId: readSubscription + parameters: + - $ref: "#/components/parameters/x-correlator" + security: + - openId: + - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:read + + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionRequest" + required: true + responses: + "200": + description: OK + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/UserExperienceInsightsResponse" + "400": + $ref: "#/components/responses/CreateSubscriptionBadRequest400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/SubscriptionPermissionDenied403" + "422": + $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" + "429": + $ref: "#/components/responses/Generic429" +components: + securitySchemes: + openId: + type: openIdConnect + description: Common security scheme for all CAMARA APIs + openIdConnectUrl: https://example.com/.well-known/openid-configuration + notificationsBearerAuth: + description: Bearer authorization for notifications + type: http + scheme: bearer + bearerFormat: "{$request.body#/sinkCredential.credentialType}" + parameters: + SubscriptionId: + name: subscriptionId + in: path + description: | + Subscription identifier that was obtained from the create event + subscription operation + required: true + schema: + $ref: "#/components/schemas/SubscriptionId" + x-correlator: + name: x-correlator + in: header + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + headers: + x-correlator: + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + schemas: + XCorrelator: + type: string + pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ + example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" + Subscription: + description: Represents a event-type subscription. + type: object + required: + - sink + - protocol + - config + - types + - id + - startsAt + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + config: + $ref: "#/components/schemas/Config" + subscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + startsAt: + type: string + format: date-time + description: Date when the event subscription will begin/began + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + expiresAt: + type: string + format: date-time + description: | + Date when the event subscription will expire. Only provided when + `subscriptionExpireTime` is indicated by API client or Telco + Operator has specific policy about that. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + status: + type: string + description: |- + Current status of the subscription - Management of Subscription + State engine is not mandatory for now. Note not all statuses may + be considered to be implemented. Details: + - `ACTIVATION_REQUESTED`: Subscription creation (POST) is + triggered but subscription creation process is not finished + yet. + - `ACTIVE`: Subscription creation process is completed. + Subscription is fully operative. + - `DEACTIVE`: Subscription is temporarily inactive, but its + workflow logic is not deleted. + - `EXPIRED`: Subscription is ended (no longer active). + This status applies when subscription is ended due to + `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. + - `DELETED`: Subscription is ended as deleted (no longer + active). This status applies when subscription information is + kept (i.e. subscription workflow is no longer active but its + metainformation is kept). + enum: + - ACTIVATION_REQUESTED + - ACTIVE + - EXPIRED + - DEACTIVE + - DELETED + discriminator: + propertyName: protocol + mapping: + HTTP: "#/components/schemas/HTTPSubscriptionResponse" + MQTT3: "#/components/schemas/MQTTSubscriptionResponse" + MQTT5: "#/components/schemas/MQTTSubscriptionResponse" + AMQP: "#/components/schemas/AMQPSubscriptionResponse" + NATS: "#/components/schemas/NATSSubscriptionResponse" + KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" + + SubscriptionAsync: + description: | + Response for a event-type subscription request managed asynchronously + (Creation or Deletion) + type: object + properties: + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + + SubscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + Device: + description: | + End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + * `phoneNumber` + * `networkAccessIdentifier` + NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. + type: object + properties: + phoneNumber: + $ref: "#/components/schemas/PhoneNumber" + networkAccessIdentifier: + $ref: "#/components/schemas/NetworkAccessIdentifier" + ipv4Address: + $ref: "#/components/schemas/DeviceIpv4Addr" + ipv6Address: + $ref: "#/components/schemas/DeviceIpv6Address" + minProperties: 1 + + NetworkAccessIdentifier: + description: | + A public identifier addressing a subscription in a mobile network. In + 3GPP terminology, it corresponds to the GPSI formatted with the + External Identifier ({Local Identifier}@{Domain Identifier}). Unlike + the telephone number, the network access identifier is not subjected + to portability ruling in force, and is individually managed by each + operator. + type: string + example: "123456789@domain.com" + + PhoneNumber: + description: | + A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN (Mobile Station International + Subscriber Directory Number). In order to be globally unique it has to + be formatted in international format, according to E.164 standard, + prefixed with '+'. + type: string + pattern: '^\+[1-9][0-9]{4,14}$' + example: "+123456789" + + DeviceIpv4Addr: + type: object + description: | + The device should be identified by either the public (observed) IP + address and port as seen by the application server, or the private + (local) and any public (observed) IP addresses in use by the device + (this information can be obtained by various means, for example from + some DNS servers). + + If the allocated and observed IP addresses are the same (i.e. NAT is + not in use) then the same address should be specified for both + publicAddress and privateAddress. + + If NAT64 is in use, the device should be identified by its + publicAddress and publicPort, or separately by its allocated IPv6 + address (field ipv6Address of the Device object) + + In all cases, publicAddress must be specified, along with at least one + of either privateAddress or publicPort, dependent upon which is known. + In general, mobile devices cannot be identified by their public IPv4 + address alone. + properties: + publicAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + privateAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + publicPort: + $ref: "#/components/schemas/Port" + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + example: {"publicAddress":"84.125.93.10", "publicPort":59765} + + SingleIpv4Addr: + description: A single IPv4 address with no subnet mask + type: string + format: ipv4 + example: "84.125.93.10" + + DeviceIpv6Address: + description: | + The device should be identified by the observed IPv6 address, or by any + single IPv6 address from within the subnet allocated to the device + (e.g. adding ::0 to the /64 prefix). + + The session shall apply to all IP flows between the device subnet and + the specified application server, unless further restricted by the + optional parameters devicePorts or applicationServerPorts. + type: string + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + + Port: + description: TCP or UDP port number + type: integer + minimum: 0 + maximum: 65535 + Protocol: + type: string + enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] + description: | + Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + Config: + description: | + Implementation-specific configuration parameters needed by the + subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`. + Specific event type attributes must be defined in `subscriptionDetail` + Note: if a request is performed for several event type, all subscribed + event will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + $ref: "#/components/schemas/CreateSubscriptionDetail" + subscriptionExpireTime: + type: string + format: date-time + description: | + The subscription expiration time (in date-time format) requested by + the API consumer. Up to API project decision to keep it. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + SinkCredential: + type: object + description: | + A sink credential provides authentication or authorization information + properties: + credentialType: + type: string + enum: + - PLAIN + - ACCESSTOKEN + - REFRESHTOKEN + description: | + The type of the credential. + Note: Type of the credential - MUST be set to ACCESSTOKEN for now + discriminator: + propertyName: credentialType + mapping: + PLAIN: "#/components/schemas/PlainCredential" + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" + required: + - credentialType + + CreateSubscriptionDetail: + description: The detail of the requested event subscription + type: object + properties: + device: + description: | + This API need to carry the subscriber's GPSI/MSISDN. + $ref: "#/components/schemas/Device" + applicationId: + description: | + Indicates the Application Identifier. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/ApplicationId" + appcationType: + description: | + Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/AppcationType" + required: + - device + + SubscriptionRequest: + description: The request for creating a event-type event subscription + type: object + required: + - sink + - protocol + - config + - types + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + sinkCredential: + $ref: "#/components/schemas/SinkCredential" + config: + $ref: "#/components/schemas/Config" + BitRate: + type: string + description: | + String representing a bit rate that shall be formatted as follows: + pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" + Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". + TrafficVolume: + type: string + description: | + String representing a traffic volume measured in bytes that shall be formatted as follows: + Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' + Examples:"125 MB", "0.125 GB", "125000 kB" + Dnn: + type: string + description: | + String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; + it shall contain either a DNN Network Identifier, or a full DNN with both the Network + Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. + It shall be coded as string in which the labels are separated by dots + (e.g. "Label1.Label2.Label3"). + QciOr5qi: + type: integer + description: | + It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). + NetType: + type: string + description: Indicates the type of network accessed. SA/EPC + AppSignalingData: + type: object + description: | + Basic . + properties: + dnn: + $ref: '#/components/schemas/Dnn' + qciOr5qi: + $ref: "#/components/schemas/QciOr5qi" + netType: + $ref: '#/components/schemas/NetType' + VolumeMeasurement: + type: object + description: | + Application-level traffic statistics. + properties: + totalVolume: + description: total running traffic statistics. + $ref: "#/components/schemas/TrafficVolume" + ulVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. + $ref: "#/components/schemas/TrafficVolume" + dlVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. + $ref: "#/components/schemas/TrafficVolume" + ApplicationIndicatorStatistics: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + subAppStartTime: + $ref: "#/components/schemas/DateTime" + subAppEffDur: + type: integer + description: | + Unsigned integer identifying a period of time in units of seconds + avgBwUl: + description: Average uplink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + avgBwDl: + description: Average downlink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + maxBwUl: + description: Maximum uplink bandwidth of the application + $ref: "#/components/schemas/BitRate" + maxBwDl: + description: Maximum downlink bandwidth of the application + $ref: "#/components/schemas/BitRate" + subAppVol: + $ref: "#/components/schemas/VolumeMeasurement" + maxDelayAn: + type: integer + description: | + Maximum wireless-side latency of an application. + maxDelayDn: + type: integer + description: | + Maximum wired-side latency of an application. + ApplicationExperienceAnalysis: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + avgQoe: + type: integer + description: | + Average score of experience analysis.Value range: 1 to 100 points. + maxResolution: + type: string + description: | + Maximum resolution in the experience analysis period. + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + mostResolution: + type: string + description: | + The resolution with the highest duration ratio within the experience analysis perio + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + maxBitRateUl: + description: Maximum uplink bit rate (kbit/s). + $ref: "#/components/schemas/BitRate" + avgBitRateUl: + description: Average uplink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + maxBitRateDl: + description: Maximum downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + avgBitRateDl: + description: Average downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + stallSec: + type: integer + description: Frame freezing duration, in seconds. + stallNum: + type: integer + description: Number of frame freezing times. The detection period is 5 seconds. + serviceDelay: + type: integer + description: Service latency, in seconds. + initialDur: + type: integer + description: | + Initial service buffering duration, in seconds. The options are as follows: + AreaData: + type: object + description: | + Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. + properties: + city: + type: string + description: user's city of residence. + district: + type: string + description: areas or streets within a city. + AppSignalingAndStatisticsAnalysisRecord: + type: object + description: | + the network's confidence level at being able to meet the network + demands of a given application for a given terminal device. + properties: + starttime: + $ref: "#/components/schemas/DateTime" + endtime: + $ref: "#/components/schemas/DateTime" + appcationType: + $ref: "#/components/schemas/AppcationType" + applicationId: + $ref: "#/components/schemas/ApplicationId" + areaData: + $ref: "#/components/schemas/AreaData" + appSignalingData: + $ref: "#/components/schemas/AppSignalingData" + applicationIndicatorStatistics: + $ref: "#/components/schemas/ApplicationIndicatorStatistics" + applicationExperienceAnalysis: + $ref: "#/components/schemas/ApplicationExperienceAnalysis" + UserExperienceInsightsRecords: + type: object + description: | + Application Network Collection and Recording + properties: + appSignalingAndStatisticsAnalysisRecords: + type: array + items: + $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' + minItems: 1 + ApplicationId: + description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + format: uuid + AppcationType: + description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + example: video/game/Live Video + Source: + type: string + format: uri-reference + minLength: 1 + description: | + Identifies the context in which an event happened, as a non-empty + `URI-reference` like: + - URI with a DNS authority: + * https://github.com/cloudevents + * mailto:cncf-wg-serverless@lists.cncf.io + - Universally-unique URN with a UUID: + * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - Application-specific identifier: + * /cloudevents/spec/pull/123 + * 1-555-123-4567 + example: "https://notificationSendServer12.supertelco.com" + TerminationReason: + type: string + description: | + - NETWORK_TERMINATED - API server stopped sending notification + - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by + the requester) has been reached + - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the + requester) has been reached + - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by + the requester) expiration time has been reached + - SUBSCRIPTION_DELETED - Subscription was deleted by the requester + enum: + - MAX_EVENTS_REACHED + - NETWORK_TERMINATED + - SUBSCRIPTION_EXPIRED + - ACCESS_TOKEN_EXPIRED + - SUBSCRIPTION_DELETED + + DateTime: + type: string + format: date-time + description: | + Timestamp of when the occurrence happened. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + + EventTypeNotification: + type: string + description: | + event-type - Event triggered when an event-type event occurred + subscription-ended: Event triggered when the subscription ends + enum: + - org.camaraproject.user-experience-insights.v0.network-quality + - org.camaraproject.user-experience-insights.v0.subscription-ended + ErrorInfo: + type: object + description: Error information + required: + - status + - code + - message + properties: + status: + type: integer + description: HTTP response status code + code: + type: string + description: A human-readable code to describe the error + message: + type: string + description: A human-readable description of what the event represents + UserExperienceInsightsResponse: + type: object + description: user experience insights result + required: + - UserExperienceInsightsRecords + properties: + device: + $ref: '#/components/schemas/Device' + UserExperienceInsightsRecords: + type: array + items: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + minItems: 1 + responses: + CreateSubscriptionBadRequest400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + - INVALID_PROTOCOL + - INVALID_CREDENTIAL + - INVALID_TOKEN + - INVALID_SINK + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_INVALID_PROTOCOL: + description: Invalid protocol for events subscription management + value: + status: 400 + code: INVALID_PROTOCOL + message: Only HTTP is supported + GENERIC_400_INVALID_CREDENTIAL: + description: Invalid sink credential type + value: + status: 400 + code: INVALID_CREDENTIAL + message: Only Access token is supported + GENERIC_400_INVALID_TOKEN: + description: Invalid token type for sink credential of type ACCESSTOKEN + value: + status: 400 + code: INVALID_TOKEN + message: Only bearer token is supported + GENERIC_400_INVALID_SINK: + description: Invalid sink value + value: + status: 400 + code: INVALID_SINK + message: sink not valid for the specified protocol + Generic400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + SubscriptionIdRequired400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_SUBSCRIPTION_ID_REQUIRED: + description: subscription id is required + value: + status: 400 + code: INVALID_ARGUMENT + message: "Expected property is missing: subscriptionId" + Generic401: + description: Authentication problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 401 + code: + enum: + - UNAUTHENTICATED + + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. + + Generic403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + SubscriptionPermissionDenied403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + - SUBSCRIPTION_MISMATCH + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + GENERIC_403_SUBSCRIPTION_MISMATCH: + description: Inconsistent access token for requested subscription + value: + status: 403 + code: "SUBSCRIPTION_MISMATCH" + message: "Inconsistent access token for requested events subscription" + Generic404: + description: Resource Not Found + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - NOT_FOUND + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + Generic410: + description: Gone + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 410 + code: + enum: + - GONE + examples: + GENERIC_410_GONE: + description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available + value: + status: 410 + code: GONE + message: Access to the target resource is no longer available. + CreateSubscriptionUnprocessableEntity422: + description: Unprocessable Entity + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNNECESSARY_IDENTIFIER + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 429 + code: + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. \ No newline at end of file From e2ea9493736a1f19f9b33ef523fb73274a891f9e Mon Sep 17 00:00:00 2001 From: cmhkknight Date: Thu, 30 Apr 2026 11:52:50 +0800 Subject: [PATCH 2/4] Add files via upload --- .../API-proposal-user experience insights.md | 48 + ...ser-experience-insights-subscriptions.yaml | 1217 +++++++++++++++++ .../user-experience-insights.yaml | 995 ++++++++++++++ 3 files changed, 2260 insertions(+) create mode 100644 documentation/API proposals/API-proposal-user experience insights.md create mode 100644 documentation/API proposals/user-experience-insights-subscriptions.yaml create mode 100644 documentation/API proposals/user-experience-insights.yaml diff --git a/documentation/API proposals/API-proposal-user experience insights.md b/documentation/API proposals/API-proposal-user experience insights.md new file mode 100644 index 0000000..6c6a724 --- /dev/null +++ b/documentation/API proposals/API-proposal-user experience insights.md @@ -0,0 +1,48 @@ +# API Proposal Template +This template captures all the information that a partner should fill out when proposing a new API (or API family) to CAMARA. + + +### API family name +User Experience Insights (UEI) + +### API family owner +China Mobile Hong Kong, Huawei + +### API summary +This API allows Application Functions (AF) to subscribe to real-time network experience notifications for specific users. The API leverages the analytics capabilities of the NWDAF (Network Data Analytics Function) and exposes them through the NEF (Network Exposure Function). When a user's network experience (e.g., throughput, latency, or reliability) falls below a predefined threshold or changes significantly, the network proactively notifies the AF. + +In-scope business cases: + +VIP Customer Care & Proactive Intervention: Operator customer service systems can monitor high-value users' real-time experience. If a degradation is detected, the system can trigger automated "care" actions (e.g., issuing temporary vouchers or prioritizing technical support) before the user even files a complaint. + +Adaptive Application Logic: Streaming or gaming applications can use this API to receive proactive alerts about user experience trends, allowing them to adjust application-level parameters (like bitrates or buffering strategies) ahead of time. + +SLA Monitoring for Enterprise Services: Enterprises can subscribe to experience insights for their workforce to ensure critical remote-working applications meet the required performance standards. + +### Technical viability +This API is technically viable based on 3GPP 5G core network standards: + +3GPP TS 23.288 (NWDAF): Utilizes the "User Data Congestion" and "Service Experience" analytics ID. + +3GPP TS 23.502 / TS 29.522 (NEF): Requires NEF to support the exposure of analytics via Nnef_EventExposure or Nnef_AnalyticsExposure services. + +Maturity: These features are part of 3GPP Release 16/17, which are currently being deployed in commercial 5G SA networks. + +### Commercial viability +The underlying network capabilities (NEF and NWDAF) are now widely available as industrialized solutions. Many Tier-1 operators have already deployed NWDAF for internal network optimization and are moving towards external exposure of these insights to enhance ecosystem value. + +### YAML code available? +YES. + +### Validated in lab/productive environments? +YES. Validated in a lab environment simulating 5G SA core network signaling with actual NWDAF analytics triggers. + +### Validated with real customers? +No. + +### Validated with operators? +No. + +### Supporters in API Backlog Working Group +List of supporters. +*NOTE: That shall be added by the Working Group. Supporting an API proposal means that the supporting company must provide at least 1 (one) Maintainer at the time of the Sub Project creation.* diff --git a/documentation/API proposals/user-experience-insights-subscriptions.yaml b/documentation/API proposals/user-experience-insights-subscriptions.yaml new file mode 100644 index 0000000..8722279 --- /dev/null +++ b/documentation/API proposals/user-experience-insights-subscriptions.yaml @@ -0,0 +1,1217 @@ +openapi: 3.0.3 +info: + title: User Experience Insights + version: wip + x-camara-commonalities: 0.6 + description: | + With CAMARA User Experience Insights subscription service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. + + # Introduction + + The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. + + This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. + + This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. + + This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. + + for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. + # Relevant terms and definitions + + * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. + + # API functionality + The API provides the datatype parameter to report network quality at different granularities. Poor-QoE events are reported in real time when the network detects poor-QoE events. + + This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). + + This API provides the function of reporting poor-QoE data in real time or periodically reporting no poor-QoE data based on the datatype parameter. + POOR_QOE_REPORT Detects poor network experience and reports the collected statistical data. + PERIODIC_REPORT Periodically collecting and reporting data. + ALL Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. + + + ### Notification callback + + This endpoint describes the event notification received on subscription listener side when the event occurred. + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +externalDocs: + description: Product documentation at CAMARA. + url: https://github.com/camaraproject/UserExperienceInsights + +servers: + - url: "{apiRoot}/user-experience-insights" + variables: + apiRoot: + default: http://localhost:9091 + description: | + API root, defined by service provider, e.g. + `api.example.com` or `api.example.com/somepath` + +tags: + - name: User Experience Insights + description: | + Create and manage a subscription to receive periodic connectivity + insights + +paths: + /subscriptions: + post: + tags: + - User Experience Insights + description: "Create a User Experience Insights Subscription for a device" + summary: "Create a User Experience Insights Subscription for a device" + operationId: createSubscription + parameters: + - $ref: "#/components/parameters/x-correlator" + security: + - openId: + - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:create + + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionRequest" + required: true + callbacks: + notifications: + "{$request.body#/sink}": + post: + summary: "Subscription notification callback" + description: | + Important: this endpoint is to be implemented by the API + consumer.The User Experience Insights server will call this + endpoint whenever a connectivity event occurs that changes + the network's ability to meet the application's demands for + a given device. + operationId: postNotification + parameters: + - $ref: "#/components/parameters/x-correlator" + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CloudEvent" + required: true + responses: + "201": + description: Successful notification + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + "400": + $ref: "#/components/responses/Generic400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "410": + $ref: "#/components/responses/Generic410" + "429": + $ref: "#/components/responses/Generic429" + security: + - {} + - notificationsBearerAuth: [] + responses: + "201": + description: Created + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionAsync" + "400": + $ref: "#/components/responses/CreateSubscriptionBadRequest400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/SubscriptionPermissionDenied403" + "409": + $ref: "#/components/responses/Generic409" + "422": + $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" + "429": + $ref: "#/components/responses/Generic429" + /subscriptions/{subscriptionId}: + get: + tags: + - User Experience Insights + summary: "Operation to retrieve a subscription based on the provided ID" + operationId: getSubscription + description: Retrieve a given subscription by ID + security: + - openId: + - connectivity-insights-subscriptions:read + parameters: + - $ref: "#/components/parameters/SubscriptionId" + - $ref: "#/components/parameters/x-correlator" + responses: + "200": + description: OK + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/Subscription" + "400": + $ref: "#/components/responses/SubscriptionIdRequired400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "404": + $ref: "#/components/responses/Generic404" + delete: + tags: + - User Experience Insights + summary: "Operation to delete a subscription" + operationId: deleteSubscription + description: Delete a given subscription by ID + security: + - openId: + - user-experience-insights:delete + parameters: + - $ref: "#/components/parameters/SubscriptionId" + - $ref: "#/components/parameters/x-correlator" + responses: + "204": + description: apiName subscription deleted + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + "202": + description: | + Request accepted to be processed. It applies for async deletion + process. + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionAsync" + "400": + $ref: "#/components/responses/SubscriptionIdRequired400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "404": + $ref: "#/components/responses/Generic404" + +components: + securitySchemes: + openId: + type: openIdConnect + description: Common security scheme for all CAMARA APIs + openIdConnectUrl: https://example.com/.well-known/openid-configuration + notificationsBearerAuth: + description: Bearer authorization for notifications + type: http + scheme: bearer + bearerFormat: "{$request.body#/sinkCredential.credentialType}" + parameters: + SubscriptionId: + name: subscriptionId + in: path + description: | + Subscription identifier that was obtained from the create event + subscription operation + required: true + schema: + $ref: "#/components/schemas/SubscriptionId" + x-correlator: + name: x-correlator + in: header + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + headers: + x-correlator: + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + schemas: + XCorrelator: + type: string + pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ + example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" + Subscription: + description: Represents a event-type subscription. + type: object + required: + - sink + - protocol + - config + - types + - id + - startsAt + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + config: + $ref: "#/components/schemas/Config" + subscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + startsAt: + type: string + format: date-time + description: Date when the event subscription will begin/began + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + expiresAt: + type: string + format: date-time + description: | + Date when the event subscription will expire. Only provided when + `subscriptionExpireTime` is indicated by API client or Telco + Operator has specific policy about that. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + status: + type: string + description: |- + Current status of the subscription - Management of Subscription + State engine is not mandatory for now. Note not all statuses may + be considered to be implemented. Details: + - `ACTIVATION_REQUESTED`: Subscription creation (POST) is + triggered but subscription creation process is not finished + yet. + - `ACTIVE`: Subscription creation process is completed. + Subscription is fully operative. + - `DEACTIVE`: Subscription is temporarily inactive, but its + workflow logic is not deleted. + - `EXPIRED`: Subscription is ended (no longer active). + This status applies when subscription is ended due to + `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. + - `DELETED`: Subscription is ended as deleted (no longer + active). This status applies when subscription information is + kept (i.e. subscription workflow is no longer active but its + metainformation is kept). + enum: + - ACTIVATION_REQUESTED + - ACTIVE + - EXPIRED + - DEACTIVE + - DELETED + discriminator: + propertyName: protocol + mapping: + HTTP: "#/components/schemas/HTTPSubscriptionResponse" + MQTT3: "#/components/schemas/MQTTSubscriptionResponse" + MQTT5: "#/components/schemas/MQTTSubscriptionResponse" + AMQP: "#/components/schemas/AMQPSubscriptionResponse" + NATS: "#/components/schemas/NATSSubscriptionResponse" + KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" + + SubscriptionAsync: + description: | + Response for a event-type subscription request managed asynchronously + (Creation or Deletion) + type: object + properties: + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + + SubscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + Device: + description: | + End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + * `phoneNumber` + * `networkAccessIdentifier` + NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. + type: object + properties: + phoneNumber: + $ref: "#/components/schemas/PhoneNumber" + networkAccessIdentifier: + $ref: "#/components/schemas/NetworkAccessIdentifier" + ipv4Address: + $ref: "#/components/schemas/DeviceIpv4Addr" + ipv6Address: + $ref: "#/components/schemas/DeviceIpv6Address" + minProperties: 1 + + NetworkAccessIdentifier: + description: | + A public identifier addressing a subscription in a mobile network. In + 3GPP terminology, it corresponds to the GPSI formatted with the + External Identifier ({Local Identifier}@{Domain Identifier}). Unlike + the telephone number, the network access identifier is not subjected + to portability ruling in force, and is individually managed by each + operator. + type: string + example: "123456789@domain.com" + + PhoneNumber: + description: | + A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN (Mobile Station International + Subscriber Directory Number). In order to be globally unique it has to + be formatted in international format, according to E.164 standard, + prefixed with '+'. + type: string + pattern: '^\+[1-9][0-9]{4,14}$' + example: "+123456789" + + DeviceIpv4Addr: + type: object + description: | + The device should be identified by either the public (observed) IP + address and port as seen by the application server, or the private + (local) and any public (observed) IP addresses in use by the device + (this information can be obtained by various means, for example from + some DNS servers). + + If the allocated and observed IP addresses are the same (i.e. NAT is + not in use) then the same address should be specified for both + publicAddress and privateAddress. + + If NAT64 is in use, the device should be identified by its + publicAddress and publicPort, or separately by its allocated IPv6 + address (field ipv6Address of the Device object) + + In all cases, publicAddress must be specified, along with at least one + of either privateAddress or publicPort, dependent upon which is known. + In general, mobile devices cannot be identified by their public IPv4 + address alone. + properties: + publicAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + privateAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + publicPort: + $ref: "#/components/schemas/Port" + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + example: {"publicAddress":"84.125.93.10", "publicPort":59765} + + SingleIpv4Addr: + description: A single IPv4 address with no subnet mask + type: string + format: ipv4 + example: "84.125.93.10" + + DeviceIpv6Address: + description: | + The device should be identified by the observed IPv6 address, or by any + single IPv6 address from within the subnet allocated to the device + (e.g. adding ::0 to the /64 prefix). + + The session shall apply to all IP flows between the device subnet and + the specified application server, unless further restricted by the + optional parameters devicePorts or applicationServerPorts. + type: string + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + + Port: + description: TCP or UDP port number + type: integer + minimum: 0 + maximum: 65535 + Protocol: + type: string + enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] + description: | + Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + Config: + description: | + Implementation-specific configuration parameters needed by the + subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`. + Specific event type attributes must be defined in `subscriptionDetail` + Note: if a request is performed for several event type, all subscribed + event will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + $ref: "#/components/schemas/CreateSubscriptionDetail" + subscriptionExpireTime: + type: string + format: date-time + description: | + The subscription expiration time (in date-time format) requested by + the API consumer. Up to API project decision to keep it. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + datatype: + type: string + description: | + POOR_QOE_REPORT: Detects poor network experience and reports the collected statistical data. + PERIODIC_REPORT: Periodically collecting and reporting data. + ALL: Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. + enum: + - POOR_QOE_REPORT + - PERIODIC_REPORT + - ALL + SinkCredential: + type: object + description: | + A sink credential provides authentication or authorization information + properties: + credentialType: + type: string + enum: + - PLAIN + - ACCESSTOKEN + - REFRESHTOKEN + description: | + The type of the credential. + Note: Type of the credential - MUST be set to ACCESSTOKEN for now + discriminator: + propertyName: credentialType + mapping: + PLAIN: "#/components/schemas/PlainCredential" + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" + required: + - credentialType + + CreateSubscriptionDetail: + description: The detail of the requested event subscription + type: object + properties: + device: + description: | + This API need to carry the subscriber's GPSI/MSISDN. + $ref: "#/components/schemas/Device" + appcationType: + description: | + Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/AppcationType" + required: + - device + + SubscriptionRequest: + description: The request for creating a event-type event subscription + type: object + required: + - sink + - protocol + - config + - types + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + sinkCredential: + $ref: "#/components/schemas/SinkCredential" + config: + $ref: "#/components/schemas/Config" + BitRate: + type: string + description: | + String representing a bit rate that shall be formatted as follows: + pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" + Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". + TrafficVolume: + type: string + description: | + String representing a traffic volume measured in bytes that shall be formatted as follows: + Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' + Examples:"125 MB", "0.125 GB", "125000 kB" + Dnn: + type: string + description: | + String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; + it shall contain either a DNN Network Identifier, or a full DNN with both the Network + Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. + It shall be coded as string in which the labels are separated by dots + (e.g. "Label1.Label2.Label3"). + QciOr5qi: + type: integer + description: | + It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). + NetType: + type: string + description: Indicates the type of network accessed. SA/EPC + AppSignalingData: + type: object + description: | + Basic . + properties: + dnn: + $ref: '#/components/schemas/Dnn' + qciOr5qi: + $ref: "#/components/schemas/QciOr5qi" + netType: + $ref: '#/components/schemas/NetType' + VolumeMeasurement: + type: object + description: | + Application-level traffic statistics. + properties: + totalVolume: + description: total running traffic statistics. + $ref: "#/components/schemas/TrafficVolume" + ulVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. + $ref: "#/components/schemas/TrafficVolume" + dlVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. + $ref: "#/components/schemas/TrafficVolume" + ApplicationIndicatorStatistics: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + subAppStartTime: + $ref: "#/components/schemas/DateTime" + subAppEffDur: + type: integer + description: | + Unsigned integer identifying a period of time in units of seconds + avgBwUl: + description: Average uplink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + avgBwDl: + description: Average downlink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + maxBwUl: + description: Maximum uplink bandwidth of the application + $ref: "#/components/schemas/BitRate" + maxBwDl: + description: Maximum downlink bandwidth of the application + $ref: "#/components/schemas/BitRate" + subAppVol: + $ref: "#/components/schemas/VolumeMeasurement" + maxDelayAn: + type: integer + description: | + Maximum wireless-side latency of an application. + maxDelayDn: + type: integer + description: | + Maximum wired-side latency of an application. + ApplicationExperienceAnalysis: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + avgQoe: + type: integer + description: | + Average score of experience analysis.Value range: 1 to 100 points. + maxResolution: + type: string + description: | + Maximum resolution in the experience analysis period. + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + mostResolution: + type: string + description: | + The resolution with the highest duration ratio within the experience analysis perio + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + maxBitRateUl: + description: Maximum uplink bit rate (kbit/s). + $ref: "#/components/schemas/BitRate" + avgBitRateUl: + description: Average uplink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + maxBitRateDl: + description: Maximum downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + avgBitRateDl: + description: Average downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + stallSec: + type: integer + description: Frame freezing duration, in seconds. + stallNum: + type: integer + description: Number of frame freezing times. The detection period is 5 seconds. + serviceDelay: + type: integer + description: Service latency, in seconds. + initialDur: + type: integer + description: | + Initial service buffering duration, in seconds. The options are as follows: + AreaData: + type: object + description: | + Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. + properties: + city: + type: string + description: user's city of residence. + district: + type: string + description: areas or streets within a city. + AppSignalingAndStatisticsAnalysisRecord: + type: object + description: | + the network's confidence level at being able to meet the network + demands of a given application for a given terminal device. + properties: + starttime: + $ref: "#/components/schemas/DateTime" + endtime: + $ref: "#/components/schemas/DateTime" + appcationType: + $ref: "#/components/schemas/AppcationType" + applicationId: + $ref: "#/components/schemas/ApplicationId" + areaData: + $ref: "#/components/schemas/AreaData" + appSignalingData: + $ref: "#/components/schemas/AppSignalingData" + applicationIndicatorStatistics: + $ref: "#/components/schemas/ApplicationIndicatorStatistics" + applicationExperienceAnalysis: + $ref: "#/components/schemas/ApplicationExperienceAnalysis" + UserExperienceInsightsRecords: + type: object + description: | + Application Network Collection and Recording + properties: + appSignalingAndStatisticsAnalysisRecords: + type: array + items: + $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' + minItems: 1 + ApplicationId: + description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + format: uuid + AppcationType: + description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + example: video/game/Live Video + Source: + type: string + format: uri-reference + minLength: 1 + description: | + Identifies the context in which an event happened, as a non-empty + `URI-reference` like: + - URI with a DNS authority: + * https://github.com/cloudevents + * mailto:cncf-wg-serverless@lists.cncf.io + - Universally-unique URN with a UUID: + * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - Application-specific identifier: + * /cloudevents/spec/pull/123 + * 1-555-123-4567 + example: "https://notificationSendServer12.supertelco.com" + CloudEvent: + description: The Cloud-Event used for the callback. + required: + - id + - source + - specversion + - type + - time + properties: + id: + type: string + description: | + identifier of this event, that must be unique in the source context. + source: + $ref: "#/components/schemas/Source" + type: + $ref: "#/components/schemas/EventTypeNotification" + specversion: + type: string + description: | + Version of the specification to which this event conforms (must be + 1.0 if it conforms to cloudevents 1.0.2 version) + enum: + - "1.0" + datacontenttype: + type: string + description: | + 'media-type that describes the event payload encoding, + must be "application/json" for CAMARA APIs' + enum: + - application/json + data: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + time: + $ref: "#/components/schemas/DateTime" + discriminator: + propertyName: "type" + mapping: + org.camaraproject.user-experience-insights.v0.network-quality: + "#/components/schemas/EventNetworkQuality" + org.camaraproject.connectivityinsights.v0.eventSubscriptionEnded: + "#/components/schemas/EventSubscriptionEnded" + + EventNetworkQuality: + description: event structure for Network Quality + allOf: + - $ref: "#/components/schemas/CloudEvent" + - type: object + properties: + data: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + + EventSubscriptionEnded: + description: event structure for event subscription ended + allOf: + - $ref: "#/components/schemas/CloudEvent" + - type: object + properties: + data: + $ref: "#/components/schemas/SubscriptionEnded" + + SubscriptionEnded: + description: Event detail structure for subscription ended event + type: object + required: + - terminationReason + - subscriptionId + properties: + terminationReason: + $ref: "#/components/schemas/TerminationReason" + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + terminationDescription: + description: Explanation why a subscription ended or had to end. + type: string + + TerminationReason: + type: string + description: | + - NETWORK_TERMINATED - API server stopped sending notification + - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by + the requester) has been reached + - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the + requester) has been reached + - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by + the requester) expiration time has been reached + - SUBSCRIPTION_DELETED - Subscription was deleted by the requester + enum: + - MAX_EVENTS_REACHED + - NETWORK_TERMINATED + - SUBSCRIPTION_EXPIRED + - ACCESS_TOKEN_EXPIRED + - SUBSCRIPTION_DELETED + + DateTime: + type: string + format: date-time + description: | + Timestamp of when the occurrence happened. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + + EventTypeNotification: + type: string + description: | + event-type - Event triggered when an event-type event occurred + subscription-ended: Event triggered when the subscription ends + enum: + - org.camaraproject.user-experience-insights.v0.network-quality + - org.camaraproject.user-experience-insights.v0.subscription-ended + ErrorInfo: + type: object + description: Error information + required: + - status + - code + - message + properties: + status: + type: integer + description: HTTP response status code + code: + type: string + description: A human-readable code to describe the error + message: + type: string + description: A human-readable description of what the event represents + + responses: + CreateSubscriptionBadRequest400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + - INVALID_PROTOCOL + - INVALID_CREDENTIAL + - INVALID_TOKEN + - INVALID_SINK + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_INVALID_PROTOCOL: + description: Invalid protocol for events subscription management + value: + status: 400 + code: INVALID_PROTOCOL + message: Only HTTP is supported + GENERIC_400_INVALID_CREDENTIAL: + description: Invalid sink credential type + value: + status: 400 + code: INVALID_CREDENTIAL + message: Only Access token is supported + GENERIC_400_INVALID_TOKEN: + description: Invalid token type for sink credential of type ACCESSTOKEN + value: + status: 400 + code: INVALID_TOKEN + message: Only bearer token is supported + GENERIC_400_INVALID_SINK: + description: Invalid sink value + value: + status: 400 + code: INVALID_SINK + message: sink not valid for the specified protocol + Generic400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + SubscriptionIdRequired400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_SUBSCRIPTION_ID_REQUIRED: + description: subscription id is required + value: + status: 400 + code: INVALID_ARGUMENT + message: "Expected property is missing: subscriptionId" + Generic401: + description: Authentication problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 401 + code: + enum: + - UNAUTHENTICATED + + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. + + Generic403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + SubscriptionPermissionDenied403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + - SUBSCRIPTION_MISMATCH + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + GENERIC_403_SUBSCRIPTION_MISMATCH: + description: Inconsistent access token for requested subscription + value: + status: 403 + code: "SUBSCRIPTION_MISMATCH" + message: "Inconsistent access token for requested events subscription" + Generic404: + description: Resource Not Found + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - NOT_FOUND + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + Generic409: + description: Conflict + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 409 + code: + enum: + - ABORTED + - ALREADY_EXISTS + examples: + GENERIC_409_ABORTED: + description: Concurreny of processes of the same nature/scope + value: + status: 409 + code: ABORTED + message: Concurrency conflict. + GENERIC_409_ALREADY_EXISTS: + description: Trying to create an existing resource + value: + status: 409 + code: ALREADY_EXISTS + message: The resource that a client tried to create already exists. + Generic410: + description: Gone + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 410 + code: + enum: + - GONE + examples: + GENERIC_410_GONE: + description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available + value: + status: 410 + code: GONE + message: Access to the target resource is no longer available. + CreateSubscriptionUnprocessableEntity422: + description: Unprocessable Entity + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNNECESSARY_IDENTIFIER + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 429 + code: + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. \ No newline at end of file diff --git a/documentation/API proposals/user-experience-insights.yaml b/documentation/API proposals/user-experience-insights.yaml new file mode 100644 index 0000000..f8421f7 --- /dev/null +++ b/documentation/API proposals/user-experience-insights.yaml @@ -0,0 +1,995 @@ +openapi: 3.0.3 +info: + title: User Experience Insights + version: wip + x-camara-commonalities: 0.6 + description: | + With CAMARA User Experience Insights service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. + + # Introduction + + The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. + + This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. + + This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. + + This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. + + for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. + # Relevant terms and definitions + + * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. + + # API functionality + + This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). + + + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +externalDocs: + description: Product documentation at CAMARA. + url: https://github.com/camaraproject/UserExperienceInsights + +servers: + - url: "{apiRoot}/user-experience-insights/" + variables: + apiRoot: + default: http://localhost:9091 + description: | + API root, defined by service provider, e.g. + `api.example.com` or `api.example.com/somepath` + +tags: + - name: User Experience Insights + description: | + read User Experience Insights + +paths: + /userexperienceinsights: + post: + tags: + - User Experience Insights + description: "read a User Experience Insights for a device" + summary: "read a User Experience Insights for a device" + operationId: readSubscription + parameters: + - $ref: "#/components/parameters/x-correlator" + security: + - openId: + - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:read + + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionRequest" + required: true + responses: + "200": + description: OK + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/UserExperienceInsightsResponse" + "400": + $ref: "#/components/responses/CreateSubscriptionBadRequest400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/SubscriptionPermissionDenied403" + "422": + $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" + "429": + $ref: "#/components/responses/Generic429" +components: + securitySchemes: + openId: + type: openIdConnect + description: Common security scheme for all CAMARA APIs + openIdConnectUrl: https://example.com/.well-known/openid-configuration + notificationsBearerAuth: + description: Bearer authorization for notifications + type: http + scheme: bearer + bearerFormat: "{$request.body#/sinkCredential.credentialType}" + parameters: + SubscriptionId: + name: subscriptionId + in: path + description: | + Subscription identifier that was obtained from the create event + subscription operation + required: true + schema: + $ref: "#/components/schemas/SubscriptionId" + x-correlator: + name: x-correlator + in: header + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + headers: + x-correlator: + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + schemas: + XCorrelator: + type: string + pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ + example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" + Subscription: + description: Represents a event-type subscription. + type: object + required: + - sink + - protocol + - config + - types + - id + - startsAt + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + config: + $ref: "#/components/schemas/Config" + subscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + startsAt: + type: string + format: date-time + description: Date when the event subscription will begin/began + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + expiresAt: + type: string + format: date-time + description: | + Date when the event subscription will expire. Only provided when + `subscriptionExpireTime` is indicated by API client or Telco + Operator has specific policy about that. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + status: + type: string + description: |- + Current status of the subscription - Management of Subscription + State engine is not mandatory for now. Note not all statuses may + be considered to be implemented. Details: + - `ACTIVATION_REQUESTED`: Subscription creation (POST) is + triggered but subscription creation process is not finished + yet. + - `ACTIVE`: Subscription creation process is completed. + Subscription is fully operative. + - `DEACTIVE`: Subscription is temporarily inactive, but its + workflow logic is not deleted. + - `EXPIRED`: Subscription is ended (no longer active). + This status applies when subscription is ended due to + `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. + - `DELETED`: Subscription is ended as deleted (no longer + active). This status applies when subscription information is + kept (i.e. subscription workflow is no longer active but its + metainformation is kept). + enum: + - ACTIVATION_REQUESTED + - ACTIVE + - EXPIRED + - DEACTIVE + - DELETED + discriminator: + propertyName: protocol + mapping: + HTTP: "#/components/schemas/HTTPSubscriptionResponse" + MQTT3: "#/components/schemas/MQTTSubscriptionResponse" + MQTT5: "#/components/schemas/MQTTSubscriptionResponse" + AMQP: "#/components/schemas/AMQPSubscriptionResponse" + NATS: "#/components/schemas/NATSSubscriptionResponse" + KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" + + SubscriptionAsync: + description: | + Response for a event-type subscription request managed asynchronously + (Creation or Deletion) + type: object + properties: + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + + SubscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + Device: + description: | + End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + * `phoneNumber` + * `networkAccessIdentifier` + NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. + type: object + properties: + phoneNumber: + $ref: "#/components/schemas/PhoneNumber" + networkAccessIdentifier: + $ref: "#/components/schemas/NetworkAccessIdentifier" + ipv4Address: + $ref: "#/components/schemas/DeviceIpv4Addr" + ipv6Address: + $ref: "#/components/schemas/DeviceIpv6Address" + minProperties: 1 + + NetworkAccessIdentifier: + description: | + A public identifier addressing a subscription in a mobile network. In + 3GPP terminology, it corresponds to the GPSI formatted with the + External Identifier ({Local Identifier}@{Domain Identifier}). Unlike + the telephone number, the network access identifier is not subjected + to portability ruling in force, and is individually managed by each + operator. + type: string + example: "123456789@domain.com" + + PhoneNumber: + description: | + A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN (Mobile Station International + Subscriber Directory Number). In order to be globally unique it has to + be formatted in international format, according to E.164 standard, + prefixed with '+'. + type: string + pattern: '^\+[1-9][0-9]{4,14}$' + example: "+123456789" + + DeviceIpv4Addr: + type: object + description: | + The device should be identified by either the public (observed) IP + address and port as seen by the application server, or the private + (local) and any public (observed) IP addresses in use by the device + (this information can be obtained by various means, for example from + some DNS servers). + + If the allocated and observed IP addresses are the same (i.e. NAT is + not in use) then the same address should be specified for both + publicAddress and privateAddress. + + If NAT64 is in use, the device should be identified by its + publicAddress and publicPort, or separately by its allocated IPv6 + address (field ipv6Address of the Device object) + + In all cases, publicAddress must be specified, along with at least one + of either privateAddress or publicPort, dependent upon which is known. + In general, mobile devices cannot be identified by their public IPv4 + address alone. + properties: + publicAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + privateAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + publicPort: + $ref: "#/components/schemas/Port" + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + example: {"publicAddress":"84.125.93.10", "publicPort":59765} + + SingleIpv4Addr: + description: A single IPv4 address with no subnet mask + type: string + format: ipv4 + example: "84.125.93.10" + + DeviceIpv6Address: + description: | + The device should be identified by the observed IPv6 address, or by any + single IPv6 address from within the subnet allocated to the device + (e.g. adding ::0 to the /64 prefix). + + The session shall apply to all IP flows between the device subnet and + the specified application server, unless further restricted by the + optional parameters devicePorts or applicationServerPorts. + type: string + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + + Port: + description: TCP or UDP port number + type: integer + minimum: 0 + maximum: 65535 + Protocol: + type: string + enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] + description: | + Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + Config: + description: | + Implementation-specific configuration parameters needed by the + subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`. + Specific event type attributes must be defined in `subscriptionDetail` + Note: if a request is performed for several event type, all subscribed + event will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + $ref: "#/components/schemas/CreateSubscriptionDetail" + subscriptionExpireTime: + type: string + format: date-time + description: | + The subscription expiration time (in date-time format) requested by + the API consumer. Up to API project decision to keep it. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + SinkCredential: + type: object + description: | + A sink credential provides authentication or authorization information + properties: + credentialType: + type: string + enum: + - PLAIN + - ACCESSTOKEN + - REFRESHTOKEN + description: | + The type of the credential. + Note: Type of the credential - MUST be set to ACCESSTOKEN for now + discriminator: + propertyName: credentialType + mapping: + PLAIN: "#/components/schemas/PlainCredential" + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" + required: + - credentialType + + CreateSubscriptionDetail: + description: The detail of the requested event subscription + type: object + properties: + device: + description: | + This API need to carry the subscriber's GPSI/MSISDN. + $ref: "#/components/schemas/Device" + applicationId: + description: | + Indicates the Application Identifier. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/ApplicationId" + appcationType: + description: | + Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/AppcationType" + required: + - device + + SubscriptionRequest: + description: The request for creating a event-type event subscription + type: object + required: + - sink + - protocol + - config + - types + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + sinkCredential: + $ref: "#/components/schemas/SinkCredential" + config: + $ref: "#/components/schemas/Config" + BitRate: + type: string + description: | + String representing a bit rate that shall be formatted as follows: + pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" + Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". + TrafficVolume: + type: string + description: | + String representing a traffic volume measured in bytes that shall be formatted as follows: + Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' + Examples:"125 MB", "0.125 GB", "125000 kB" + Dnn: + type: string + description: | + String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; + it shall contain either a DNN Network Identifier, or a full DNN with both the Network + Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. + It shall be coded as string in which the labels are separated by dots + (e.g. "Label1.Label2.Label3"). + QciOr5qi: + type: integer + description: | + It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). + NetType: + type: string + description: Indicates the type of network accessed. SA/EPC + AppSignalingData: + type: object + description: | + Basic . + properties: + dnn: + $ref: '#/components/schemas/Dnn' + qciOr5qi: + $ref: "#/components/schemas/QciOr5qi" + netType: + $ref: '#/components/schemas/NetType' + VolumeMeasurement: + type: object + description: | + Application-level traffic statistics. + properties: + totalVolume: + description: total running traffic statistics. + $ref: "#/components/schemas/TrafficVolume" + ulVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. + $ref: "#/components/schemas/TrafficVolume" + dlVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. + $ref: "#/components/schemas/TrafficVolume" + ApplicationIndicatorStatistics: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + subAppStartTime: + $ref: "#/components/schemas/DateTime" + subAppEffDur: + type: integer + description: | + Unsigned integer identifying a period of time in units of seconds + avgBwUl: + description: Average uplink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + avgBwDl: + description: Average downlink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + maxBwUl: + description: Maximum uplink bandwidth of the application + $ref: "#/components/schemas/BitRate" + maxBwDl: + description: Maximum downlink bandwidth of the application + $ref: "#/components/schemas/BitRate" + subAppVol: + $ref: "#/components/schemas/VolumeMeasurement" + maxDelayAn: + type: integer + description: | + Maximum wireless-side latency of an application. + maxDelayDn: + type: integer + description: | + Maximum wired-side latency of an application. + ApplicationExperienceAnalysis: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + avgQoe: + type: integer + description: | + Average score of experience analysis.Value range: 1 to 100 points. + maxResolution: + type: string + description: | + Maximum resolution in the experience analysis period. + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + mostResolution: + type: string + description: | + The resolution with the highest duration ratio within the experience analysis perio + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + maxBitRateUl: + description: Maximum uplink bit rate (kbit/s). + $ref: "#/components/schemas/BitRate" + avgBitRateUl: + description: Average uplink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + maxBitRateDl: + description: Maximum downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + avgBitRateDl: + description: Average downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + stallSec: + type: integer + description: Frame freezing duration, in seconds. + stallNum: + type: integer + description: Number of frame freezing times. The detection period is 5 seconds. + serviceDelay: + type: integer + description: Service latency, in seconds. + initialDur: + type: integer + description: | + Initial service buffering duration, in seconds. The options are as follows: + AreaData: + type: object + description: | + Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. + properties: + city: + type: string + description: user's city of residence. + district: + type: string + description: areas or streets within a city. + AppSignalingAndStatisticsAnalysisRecord: + type: object + description: | + the network's confidence level at being able to meet the network + demands of a given application for a given terminal device. + properties: + starttime: + $ref: "#/components/schemas/DateTime" + endtime: + $ref: "#/components/schemas/DateTime" + appcationType: + $ref: "#/components/schemas/AppcationType" + applicationId: + $ref: "#/components/schemas/ApplicationId" + areaData: + $ref: "#/components/schemas/AreaData" + appSignalingData: + $ref: "#/components/schemas/AppSignalingData" + applicationIndicatorStatistics: + $ref: "#/components/schemas/ApplicationIndicatorStatistics" + applicationExperienceAnalysis: + $ref: "#/components/schemas/ApplicationExperienceAnalysis" + UserExperienceInsightsRecords: + type: object + description: | + Application Network Collection and Recording + properties: + appSignalingAndStatisticsAnalysisRecords: + type: array + items: + $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' + minItems: 1 + ApplicationId: + description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + format: uuid + AppcationType: + description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + example: video/game/Live Video + Source: + type: string + format: uri-reference + minLength: 1 + description: | + Identifies the context in which an event happened, as a non-empty + `URI-reference` like: + - URI with a DNS authority: + * https://github.com/cloudevents + * mailto:cncf-wg-serverless@lists.cncf.io + - Universally-unique URN with a UUID: + * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - Application-specific identifier: + * /cloudevents/spec/pull/123 + * 1-555-123-4567 + example: "https://notificationSendServer12.supertelco.com" + TerminationReason: + type: string + description: | + - NETWORK_TERMINATED - API server stopped sending notification + - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by + the requester) has been reached + - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the + requester) has been reached + - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by + the requester) expiration time has been reached + - SUBSCRIPTION_DELETED - Subscription was deleted by the requester + enum: + - MAX_EVENTS_REACHED + - NETWORK_TERMINATED + - SUBSCRIPTION_EXPIRED + - ACCESS_TOKEN_EXPIRED + - SUBSCRIPTION_DELETED + + DateTime: + type: string + format: date-time + description: | + Timestamp of when the occurrence happened. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + + EventTypeNotification: + type: string + description: | + event-type - Event triggered when an event-type event occurred + subscription-ended: Event triggered when the subscription ends + enum: + - org.camaraproject.user-experience-insights.v0.network-quality + - org.camaraproject.user-experience-insights.v0.subscription-ended + ErrorInfo: + type: object + description: Error information + required: + - status + - code + - message + properties: + status: + type: integer + description: HTTP response status code + code: + type: string + description: A human-readable code to describe the error + message: + type: string + description: A human-readable description of what the event represents + UserExperienceInsightsResponse: + type: object + description: user experience insights result + required: + - UserExperienceInsightsRecords + properties: + device: + $ref: '#/components/schemas/Device' + UserExperienceInsightsRecords: + type: array + items: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + minItems: 1 + responses: + CreateSubscriptionBadRequest400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + - INVALID_PROTOCOL + - INVALID_CREDENTIAL + - INVALID_TOKEN + - INVALID_SINK + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_INVALID_PROTOCOL: + description: Invalid protocol for events subscription management + value: + status: 400 + code: INVALID_PROTOCOL + message: Only HTTP is supported + GENERIC_400_INVALID_CREDENTIAL: + description: Invalid sink credential type + value: + status: 400 + code: INVALID_CREDENTIAL + message: Only Access token is supported + GENERIC_400_INVALID_TOKEN: + description: Invalid token type for sink credential of type ACCESSTOKEN + value: + status: 400 + code: INVALID_TOKEN + message: Only bearer token is supported + GENERIC_400_INVALID_SINK: + description: Invalid sink value + value: + status: 400 + code: INVALID_SINK + message: sink not valid for the specified protocol + Generic400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + SubscriptionIdRequired400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_SUBSCRIPTION_ID_REQUIRED: + description: subscription id is required + value: + status: 400 + code: INVALID_ARGUMENT + message: "Expected property is missing: subscriptionId" + Generic401: + description: Authentication problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 401 + code: + enum: + - UNAUTHENTICATED + + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. + + Generic403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + SubscriptionPermissionDenied403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + - SUBSCRIPTION_MISMATCH + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + GENERIC_403_SUBSCRIPTION_MISMATCH: + description: Inconsistent access token for requested subscription + value: + status: 403 + code: "SUBSCRIPTION_MISMATCH" + message: "Inconsistent access token for requested events subscription" + Generic404: + description: Resource Not Found + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - NOT_FOUND + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + Generic410: + description: Gone + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 410 + code: + enum: + - GONE + examples: + GENERIC_410_GONE: + description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available + value: + status: 410 + code: GONE + message: Access to the target resource is no longer available. + CreateSubscriptionUnprocessableEntity422: + description: Unprocessable Entity + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNNECESSARY_IDENTIFIER + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 429 + code: + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. \ No newline at end of file From e4cd427c02ad0c94c3071ffffa2761c27b0c895f Mon Sep 17 00:00:00 2001 From: cmhkknight Date: Thu, 30 Apr 2026 11:53:24 +0800 Subject: [PATCH 3/4] Add files via upload --- .../API-proposal-user experience insights.md | 48 + ...ser-experience-insights-subscriptions.yaml | 1217 +++++++++++++++++ .../user-experience-insights.yaml | 995 ++++++++++++++ 3 files changed, 2260 insertions(+) create mode 100644 documentation/SupportingDocuments/API-proposal-user experience insights.md create mode 100644 documentation/SupportingDocuments/user-experience-insights-subscriptions.yaml create mode 100644 documentation/SupportingDocuments/user-experience-insights.yaml diff --git a/documentation/SupportingDocuments/API-proposal-user experience insights.md b/documentation/SupportingDocuments/API-proposal-user experience insights.md new file mode 100644 index 0000000..6c6a724 --- /dev/null +++ b/documentation/SupportingDocuments/API-proposal-user experience insights.md @@ -0,0 +1,48 @@ +# API Proposal Template +This template captures all the information that a partner should fill out when proposing a new API (or API family) to CAMARA. + + +### API family name +User Experience Insights (UEI) + +### API family owner +China Mobile Hong Kong, Huawei + +### API summary +This API allows Application Functions (AF) to subscribe to real-time network experience notifications for specific users. The API leverages the analytics capabilities of the NWDAF (Network Data Analytics Function) and exposes them through the NEF (Network Exposure Function). When a user's network experience (e.g., throughput, latency, or reliability) falls below a predefined threshold or changes significantly, the network proactively notifies the AF. + +In-scope business cases: + +VIP Customer Care & Proactive Intervention: Operator customer service systems can monitor high-value users' real-time experience. If a degradation is detected, the system can trigger automated "care" actions (e.g., issuing temporary vouchers or prioritizing technical support) before the user even files a complaint. + +Adaptive Application Logic: Streaming or gaming applications can use this API to receive proactive alerts about user experience trends, allowing them to adjust application-level parameters (like bitrates or buffering strategies) ahead of time. + +SLA Monitoring for Enterprise Services: Enterprises can subscribe to experience insights for their workforce to ensure critical remote-working applications meet the required performance standards. + +### Technical viability +This API is technically viable based on 3GPP 5G core network standards: + +3GPP TS 23.288 (NWDAF): Utilizes the "User Data Congestion" and "Service Experience" analytics ID. + +3GPP TS 23.502 / TS 29.522 (NEF): Requires NEF to support the exposure of analytics via Nnef_EventExposure or Nnef_AnalyticsExposure services. + +Maturity: These features are part of 3GPP Release 16/17, which are currently being deployed in commercial 5G SA networks. + +### Commercial viability +The underlying network capabilities (NEF and NWDAF) are now widely available as industrialized solutions. Many Tier-1 operators have already deployed NWDAF for internal network optimization and are moving towards external exposure of these insights to enhance ecosystem value. + +### YAML code available? +YES. + +### Validated in lab/productive environments? +YES. Validated in a lab environment simulating 5G SA core network signaling with actual NWDAF analytics triggers. + +### Validated with real customers? +No. + +### Validated with operators? +No. + +### Supporters in API Backlog Working Group +List of supporters. +*NOTE: That shall be added by the Working Group. Supporting an API proposal means that the supporting company must provide at least 1 (one) Maintainer at the time of the Sub Project creation.* diff --git a/documentation/SupportingDocuments/user-experience-insights-subscriptions.yaml b/documentation/SupportingDocuments/user-experience-insights-subscriptions.yaml new file mode 100644 index 0000000..8722279 --- /dev/null +++ b/documentation/SupportingDocuments/user-experience-insights-subscriptions.yaml @@ -0,0 +1,1217 @@ +openapi: 3.0.3 +info: + title: User Experience Insights + version: wip + x-camara-commonalities: 0.6 + description: | + With CAMARA User Experience Insights subscription service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. + + # Introduction + + The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. + + This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. + + This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. + + This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. + + for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. + # Relevant terms and definitions + + * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. + + # API functionality + The API provides the datatype parameter to report network quality at different granularities. Poor-QoE events are reported in real time when the network detects poor-QoE events. + + This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). + + This API provides the function of reporting poor-QoE data in real time or periodically reporting no poor-QoE data based on the datatype parameter. + POOR_QOE_REPORT Detects poor network experience and reports the collected statistical data. + PERIODIC_REPORT Periodically collecting and reporting data. + ALL Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. + + + ### Notification callback + + This endpoint describes the event notification received on subscription listener side when the event occurred. + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +externalDocs: + description: Product documentation at CAMARA. + url: https://github.com/camaraproject/UserExperienceInsights + +servers: + - url: "{apiRoot}/user-experience-insights" + variables: + apiRoot: + default: http://localhost:9091 + description: | + API root, defined by service provider, e.g. + `api.example.com` or `api.example.com/somepath` + +tags: + - name: User Experience Insights + description: | + Create and manage a subscription to receive periodic connectivity + insights + +paths: + /subscriptions: + post: + tags: + - User Experience Insights + description: "Create a User Experience Insights Subscription for a device" + summary: "Create a User Experience Insights Subscription for a device" + operationId: createSubscription + parameters: + - $ref: "#/components/parameters/x-correlator" + security: + - openId: + - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:create + + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionRequest" + required: true + callbacks: + notifications: + "{$request.body#/sink}": + post: + summary: "Subscription notification callback" + description: | + Important: this endpoint is to be implemented by the API + consumer.The User Experience Insights server will call this + endpoint whenever a connectivity event occurs that changes + the network's ability to meet the application's demands for + a given device. + operationId: postNotification + parameters: + - $ref: "#/components/parameters/x-correlator" + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CloudEvent" + required: true + responses: + "201": + description: Successful notification + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + "400": + $ref: "#/components/responses/Generic400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "410": + $ref: "#/components/responses/Generic410" + "429": + $ref: "#/components/responses/Generic429" + security: + - {} + - notificationsBearerAuth: [] + responses: + "201": + description: Created + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionAsync" + "400": + $ref: "#/components/responses/CreateSubscriptionBadRequest400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/SubscriptionPermissionDenied403" + "409": + $ref: "#/components/responses/Generic409" + "422": + $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" + "429": + $ref: "#/components/responses/Generic429" + /subscriptions/{subscriptionId}: + get: + tags: + - User Experience Insights + summary: "Operation to retrieve a subscription based on the provided ID" + operationId: getSubscription + description: Retrieve a given subscription by ID + security: + - openId: + - connectivity-insights-subscriptions:read + parameters: + - $ref: "#/components/parameters/SubscriptionId" + - $ref: "#/components/parameters/x-correlator" + responses: + "200": + description: OK + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/Subscription" + "400": + $ref: "#/components/responses/SubscriptionIdRequired400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "404": + $ref: "#/components/responses/Generic404" + delete: + tags: + - User Experience Insights + summary: "Operation to delete a subscription" + operationId: deleteSubscription + description: Delete a given subscription by ID + security: + - openId: + - user-experience-insights:delete + parameters: + - $ref: "#/components/parameters/SubscriptionId" + - $ref: "#/components/parameters/x-correlator" + responses: + "204": + description: apiName subscription deleted + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + "202": + description: | + Request accepted to be processed. It applies for async deletion + process. + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionAsync" + "400": + $ref: "#/components/responses/SubscriptionIdRequired400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/Generic403" + "404": + $ref: "#/components/responses/Generic404" + +components: + securitySchemes: + openId: + type: openIdConnect + description: Common security scheme for all CAMARA APIs + openIdConnectUrl: https://example.com/.well-known/openid-configuration + notificationsBearerAuth: + description: Bearer authorization for notifications + type: http + scheme: bearer + bearerFormat: "{$request.body#/sinkCredential.credentialType}" + parameters: + SubscriptionId: + name: subscriptionId + in: path + description: | + Subscription identifier that was obtained from the create event + subscription operation + required: true + schema: + $ref: "#/components/schemas/SubscriptionId" + x-correlator: + name: x-correlator + in: header + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + headers: + x-correlator: + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + schemas: + XCorrelator: + type: string + pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ + example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" + Subscription: + description: Represents a event-type subscription. + type: object + required: + - sink + - protocol + - config + - types + - id + - startsAt + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + config: + $ref: "#/components/schemas/Config" + subscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + startsAt: + type: string + format: date-time + description: Date when the event subscription will begin/began + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + expiresAt: + type: string + format: date-time + description: | + Date when the event subscription will expire. Only provided when + `subscriptionExpireTime` is indicated by API client or Telco + Operator has specific policy about that. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + status: + type: string + description: |- + Current status of the subscription - Management of Subscription + State engine is not mandatory for now. Note not all statuses may + be considered to be implemented. Details: + - `ACTIVATION_REQUESTED`: Subscription creation (POST) is + triggered but subscription creation process is not finished + yet. + - `ACTIVE`: Subscription creation process is completed. + Subscription is fully operative. + - `DEACTIVE`: Subscription is temporarily inactive, but its + workflow logic is not deleted. + - `EXPIRED`: Subscription is ended (no longer active). + This status applies when subscription is ended due to + `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. + - `DELETED`: Subscription is ended as deleted (no longer + active). This status applies when subscription information is + kept (i.e. subscription workflow is no longer active but its + metainformation is kept). + enum: + - ACTIVATION_REQUESTED + - ACTIVE + - EXPIRED + - DEACTIVE + - DELETED + discriminator: + propertyName: protocol + mapping: + HTTP: "#/components/schemas/HTTPSubscriptionResponse" + MQTT3: "#/components/schemas/MQTTSubscriptionResponse" + MQTT5: "#/components/schemas/MQTTSubscriptionResponse" + AMQP: "#/components/schemas/AMQPSubscriptionResponse" + NATS: "#/components/schemas/NATSSubscriptionResponse" + KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" + + SubscriptionAsync: + description: | + Response for a event-type subscription request managed asynchronously + (Creation or Deletion) + type: object + properties: + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + + SubscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + Device: + description: | + End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + * `phoneNumber` + * `networkAccessIdentifier` + NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. + type: object + properties: + phoneNumber: + $ref: "#/components/schemas/PhoneNumber" + networkAccessIdentifier: + $ref: "#/components/schemas/NetworkAccessIdentifier" + ipv4Address: + $ref: "#/components/schemas/DeviceIpv4Addr" + ipv6Address: + $ref: "#/components/schemas/DeviceIpv6Address" + minProperties: 1 + + NetworkAccessIdentifier: + description: | + A public identifier addressing a subscription in a mobile network. In + 3GPP terminology, it corresponds to the GPSI formatted with the + External Identifier ({Local Identifier}@{Domain Identifier}). Unlike + the telephone number, the network access identifier is not subjected + to portability ruling in force, and is individually managed by each + operator. + type: string + example: "123456789@domain.com" + + PhoneNumber: + description: | + A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN (Mobile Station International + Subscriber Directory Number). In order to be globally unique it has to + be formatted in international format, according to E.164 standard, + prefixed with '+'. + type: string + pattern: '^\+[1-9][0-9]{4,14}$' + example: "+123456789" + + DeviceIpv4Addr: + type: object + description: | + The device should be identified by either the public (observed) IP + address and port as seen by the application server, or the private + (local) and any public (observed) IP addresses in use by the device + (this information can be obtained by various means, for example from + some DNS servers). + + If the allocated and observed IP addresses are the same (i.e. NAT is + not in use) then the same address should be specified for both + publicAddress and privateAddress. + + If NAT64 is in use, the device should be identified by its + publicAddress and publicPort, or separately by its allocated IPv6 + address (field ipv6Address of the Device object) + + In all cases, publicAddress must be specified, along with at least one + of either privateAddress or publicPort, dependent upon which is known. + In general, mobile devices cannot be identified by their public IPv4 + address alone. + properties: + publicAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + privateAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + publicPort: + $ref: "#/components/schemas/Port" + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + example: {"publicAddress":"84.125.93.10", "publicPort":59765} + + SingleIpv4Addr: + description: A single IPv4 address with no subnet mask + type: string + format: ipv4 + example: "84.125.93.10" + + DeviceIpv6Address: + description: | + The device should be identified by the observed IPv6 address, or by any + single IPv6 address from within the subnet allocated to the device + (e.g. adding ::0 to the /64 prefix). + + The session shall apply to all IP flows between the device subnet and + the specified application server, unless further restricted by the + optional parameters devicePorts or applicationServerPorts. + type: string + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + + Port: + description: TCP or UDP port number + type: integer + minimum: 0 + maximum: 65535 + Protocol: + type: string + enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] + description: | + Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + Config: + description: | + Implementation-specific configuration parameters needed by the + subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`. + Specific event type attributes must be defined in `subscriptionDetail` + Note: if a request is performed for several event type, all subscribed + event will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + $ref: "#/components/schemas/CreateSubscriptionDetail" + subscriptionExpireTime: + type: string + format: date-time + description: | + The subscription expiration time (in date-time format) requested by + the API consumer. Up to API project decision to keep it. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + datatype: + type: string + description: | + POOR_QOE_REPORT: Detects poor network experience and reports the collected statistical data. + PERIODIC_REPORT: Periodically collecting and reporting data. + ALL: Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. + enum: + - POOR_QOE_REPORT + - PERIODIC_REPORT + - ALL + SinkCredential: + type: object + description: | + A sink credential provides authentication or authorization information + properties: + credentialType: + type: string + enum: + - PLAIN + - ACCESSTOKEN + - REFRESHTOKEN + description: | + The type of the credential. + Note: Type of the credential - MUST be set to ACCESSTOKEN for now + discriminator: + propertyName: credentialType + mapping: + PLAIN: "#/components/schemas/PlainCredential" + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" + required: + - credentialType + + CreateSubscriptionDetail: + description: The detail of the requested event subscription + type: object + properties: + device: + description: | + This API need to carry the subscriber's GPSI/MSISDN. + $ref: "#/components/schemas/Device" + appcationType: + description: | + Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/AppcationType" + required: + - device + + SubscriptionRequest: + description: The request for creating a event-type event subscription + type: object + required: + - sink + - protocol + - config + - types + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + sinkCredential: + $ref: "#/components/schemas/SinkCredential" + config: + $ref: "#/components/schemas/Config" + BitRate: + type: string + description: | + String representing a bit rate that shall be formatted as follows: + pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" + Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". + TrafficVolume: + type: string + description: | + String representing a traffic volume measured in bytes that shall be formatted as follows: + Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' + Examples:"125 MB", "0.125 GB", "125000 kB" + Dnn: + type: string + description: | + String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; + it shall contain either a DNN Network Identifier, or a full DNN with both the Network + Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. + It shall be coded as string in which the labels are separated by dots + (e.g. "Label1.Label2.Label3"). + QciOr5qi: + type: integer + description: | + It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). + NetType: + type: string + description: Indicates the type of network accessed. SA/EPC + AppSignalingData: + type: object + description: | + Basic . + properties: + dnn: + $ref: '#/components/schemas/Dnn' + qciOr5qi: + $ref: "#/components/schemas/QciOr5qi" + netType: + $ref: '#/components/schemas/NetType' + VolumeMeasurement: + type: object + description: | + Application-level traffic statistics. + properties: + totalVolume: + description: total running traffic statistics. + $ref: "#/components/schemas/TrafficVolume" + ulVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. + $ref: "#/components/schemas/TrafficVolume" + dlVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. + $ref: "#/components/schemas/TrafficVolume" + ApplicationIndicatorStatistics: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + subAppStartTime: + $ref: "#/components/schemas/DateTime" + subAppEffDur: + type: integer + description: | + Unsigned integer identifying a period of time in units of seconds + avgBwUl: + description: Average uplink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + avgBwDl: + description: Average downlink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + maxBwUl: + description: Maximum uplink bandwidth of the application + $ref: "#/components/schemas/BitRate" + maxBwDl: + description: Maximum downlink bandwidth of the application + $ref: "#/components/schemas/BitRate" + subAppVol: + $ref: "#/components/schemas/VolumeMeasurement" + maxDelayAn: + type: integer + description: | + Maximum wireless-side latency of an application. + maxDelayDn: + type: integer + description: | + Maximum wired-side latency of an application. + ApplicationExperienceAnalysis: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + avgQoe: + type: integer + description: | + Average score of experience analysis.Value range: 1 to 100 points. + maxResolution: + type: string + description: | + Maximum resolution in the experience analysis period. + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + mostResolution: + type: string + description: | + The resolution with the highest duration ratio within the experience analysis perio + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + maxBitRateUl: + description: Maximum uplink bit rate (kbit/s). + $ref: "#/components/schemas/BitRate" + avgBitRateUl: + description: Average uplink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + maxBitRateDl: + description: Maximum downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + avgBitRateDl: + description: Average downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + stallSec: + type: integer + description: Frame freezing duration, in seconds. + stallNum: + type: integer + description: Number of frame freezing times. The detection period is 5 seconds. + serviceDelay: + type: integer + description: Service latency, in seconds. + initialDur: + type: integer + description: | + Initial service buffering duration, in seconds. The options are as follows: + AreaData: + type: object + description: | + Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. + properties: + city: + type: string + description: user's city of residence. + district: + type: string + description: areas or streets within a city. + AppSignalingAndStatisticsAnalysisRecord: + type: object + description: | + the network's confidence level at being able to meet the network + demands of a given application for a given terminal device. + properties: + starttime: + $ref: "#/components/schemas/DateTime" + endtime: + $ref: "#/components/schemas/DateTime" + appcationType: + $ref: "#/components/schemas/AppcationType" + applicationId: + $ref: "#/components/schemas/ApplicationId" + areaData: + $ref: "#/components/schemas/AreaData" + appSignalingData: + $ref: "#/components/schemas/AppSignalingData" + applicationIndicatorStatistics: + $ref: "#/components/schemas/ApplicationIndicatorStatistics" + applicationExperienceAnalysis: + $ref: "#/components/schemas/ApplicationExperienceAnalysis" + UserExperienceInsightsRecords: + type: object + description: | + Application Network Collection and Recording + properties: + appSignalingAndStatisticsAnalysisRecords: + type: array + items: + $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' + minItems: 1 + ApplicationId: + description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + format: uuid + AppcationType: + description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + example: video/game/Live Video + Source: + type: string + format: uri-reference + minLength: 1 + description: | + Identifies the context in which an event happened, as a non-empty + `URI-reference` like: + - URI with a DNS authority: + * https://github.com/cloudevents + * mailto:cncf-wg-serverless@lists.cncf.io + - Universally-unique URN with a UUID: + * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - Application-specific identifier: + * /cloudevents/spec/pull/123 + * 1-555-123-4567 + example: "https://notificationSendServer12.supertelco.com" + CloudEvent: + description: The Cloud-Event used for the callback. + required: + - id + - source + - specversion + - type + - time + properties: + id: + type: string + description: | + identifier of this event, that must be unique in the source context. + source: + $ref: "#/components/schemas/Source" + type: + $ref: "#/components/schemas/EventTypeNotification" + specversion: + type: string + description: | + Version of the specification to which this event conforms (must be + 1.0 if it conforms to cloudevents 1.0.2 version) + enum: + - "1.0" + datacontenttype: + type: string + description: | + 'media-type that describes the event payload encoding, + must be "application/json" for CAMARA APIs' + enum: + - application/json + data: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + time: + $ref: "#/components/schemas/DateTime" + discriminator: + propertyName: "type" + mapping: + org.camaraproject.user-experience-insights.v0.network-quality: + "#/components/schemas/EventNetworkQuality" + org.camaraproject.connectivityinsights.v0.eventSubscriptionEnded: + "#/components/schemas/EventSubscriptionEnded" + + EventNetworkQuality: + description: event structure for Network Quality + allOf: + - $ref: "#/components/schemas/CloudEvent" + - type: object + properties: + data: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + + EventSubscriptionEnded: + description: event structure for event subscription ended + allOf: + - $ref: "#/components/schemas/CloudEvent" + - type: object + properties: + data: + $ref: "#/components/schemas/SubscriptionEnded" + + SubscriptionEnded: + description: Event detail structure for subscription ended event + type: object + required: + - terminationReason + - subscriptionId + properties: + terminationReason: + $ref: "#/components/schemas/TerminationReason" + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + terminationDescription: + description: Explanation why a subscription ended or had to end. + type: string + + TerminationReason: + type: string + description: | + - NETWORK_TERMINATED - API server stopped sending notification + - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by + the requester) has been reached + - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the + requester) has been reached + - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by + the requester) expiration time has been reached + - SUBSCRIPTION_DELETED - Subscription was deleted by the requester + enum: + - MAX_EVENTS_REACHED + - NETWORK_TERMINATED + - SUBSCRIPTION_EXPIRED + - ACCESS_TOKEN_EXPIRED + - SUBSCRIPTION_DELETED + + DateTime: + type: string + format: date-time + description: | + Timestamp of when the occurrence happened. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + + EventTypeNotification: + type: string + description: | + event-type - Event triggered when an event-type event occurred + subscription-ended: Event triggered when the subscription ends + enum: + - org.camaraproject.user-experience-insights.v0.network-quality + - org.camaraproject.user-experience-insights.v0.subscription-ended + ErrorInfo: + type: object + description: Error information + required: + - status + - code + - message + properties: + status: + type: integer + description: HTTP response status code + code: + type: string + description: A human-readable code to describe the error + message: + type: string + description: A human-readable description of what the event represents + + responses: + CreateSubscriptionBadRequest400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + - INVALID_PROTOCOL + - INVALID_CREDENTIAL + - INVALID_TOKEN + - INVALID_SINK + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_INVALID_PROTOCOL: + description: Invalid protocol for events subscription management + value: + status: 400 + code: INVALID_PROTOCOL + message: Only HTTP is supported + GENERIC_400_INVALID_CREDENTIAL: + description: Invalid sink credential type + value: + status: 400 + code: INVALID_CREDENTIAL + message: Only Access token is supported + GENERIC_400_INVALID_TOKEN: + description: Invalid token type for sink credential of type ACCESSTOKEN + value: + status: 400 + code: INVALID_TOKEN + message: Only bearer token is supported + GENERIC_400_INVALID_SINK: + description: Invalid sink value + value: + status: 400 + code: INVALID_SINK + message: sink not valid for the specified protocol + Generic400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + SubscriptionIdRequired400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_SUBSCRIPTION_ID_REQUIRED: + description: subscription id is required + value: + status: 400 + code: INVALID_ARGUMENT + message: "Expected property is missing: subscriptionId" + Generic401: + description: Authentication problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 401 + code: + enum: + - UNAUTHENTICATED + + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. + + Generic403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + SubscriptionPermissionDenied403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + - SUBSCRIPTION_MISMATCH + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + GENERIC_403_SUBSCRIPTION_MISMATCH: + description: Inconsistent access token for requested subscription + value: + status: 403 + code: "SUBSCRIPTION_MISMATCH" + message: "Inconsistent access token for requested events subscription" + Generic404: + description: Resource Not Found + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - NOT_FOUND + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + Generic409: + description: Conflict + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 409 + code: + enum: + - ABORTED + - ALREADY_EXISTS + examples: + GENERIC_409_ABORTED: + description: Concurreny of processes of the same nature/scope + value: + status: 409 + code: ABORTED + message: Concurrency conflict. + GENERIC_409_ALREADY_EXISTS: + description: Trying to create an existing resource + value: + status: 409 + code: ALREADY_EXISTS + message: The resource that a client tried to create already exists. + Generic410: + description: Gone + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 410 + code: + enum: + - GONE + examples: + GENERIC_410_GONE: + description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available + value: + status: 410 + code: GONE + message: Access to the target resource is no longer available. + CreateSubscriptionUnprocessableEntity422: + description: Unprocessable Entity + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNNECESSARY_IDENTIFIER + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 429 + code: + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. \ No newline at end of file diff --git a/documentation/SupportingDocuments/user-experience-insights.yaml b/documentation/SupportingDocuments/user-experience-insights.yaml new file mode 100644 index 0000000..f8421f7 --- /dev/null +++ b/documentation/SupportingDocuments/user-experience-insights.yaml @@ -0,0 +1,995 @@ +openapi: 3.0.3 +info: + title: User Experience Insights + version: wip + x-camara-commonalities: 0.6 + description: | + With CAMARA User Experience Insights service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. + + # Introduction + + The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. + + This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. + + This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. + + This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. + + for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. + # Relevant terms and definitions + + * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. + + # API functionality + + This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). + + + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + +externalDocs: + description: Product documentation at CAMARA. + url: https://github.com/camaraproject/UserExperienceInsights + +servers: + - url: "{apiRoot}/user-experience-insights/" + variables: + apiRoot: + default: http://localhost:9091 + description: | + API root, defined by service provider, e.g. + `api.example.com` or `api.example.com/somepath` + +tags: + - name: User Experience Insights + description: | + read User Experience Insights + +paths: + /userexperienceinsights: + post: + tags: + - User Experience Insights + description: "read a User Experience Insights for a device" + summary: "read a User Experience Insights for a device" + operationId: readSubscription + parameters: + - $ref: "#/components/parameters/x-correlator" + security: + - openId: + - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:read + + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SubscriptionRequest" + required: true + responses: + "200": + description: OK + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + $ref: "#/components/schemas/UserExperienceInsightsResponse" + "400": + $ref: "#/components/responses/CreateSubscriptionBadRequest400" + "401": + $ref: "#/components/responses/Generic401" + "403": + $ref: "#/components/responses/SubscriptionPermissionDenied403" + "422": + $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" + "429": + $ref: "#/components/responses/Generic429" +components: + securitySchemes: + openId: + type: openIdConnect + description: Common security scheme for all CAMARA APIs + openIdConnectUrl: https://example.com/.well-known/openid-configuration + notificationsBearerAuth: + description: Bearer authorization for notifications + type: http + scheme: bearer + bearerFormat: "{$request.body#/sinkCredential.credentialType}" + parameters: + SubscriptionId: + name: subscriptionId + in: path + description: | + Subscription identifier that was obtained from the create event + subscription operation + required: true + schema: + $ref: "#/components/schemas/SubscriptionId" + x-correlator: + name: x-correlator + in: header + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + headers: + x-correlator: + description: Correlation id for the different services + schema: + $ref: "#/components/schemas/XCorrelator" + schemas: + XCorrelator: + type: string + pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ + example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" + Subscription: + description: Represents a event-type subscription. + type: object + required: + - sink + - protocol + - config + - types + - id + - startsAt + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + pattern: ^https:\/\/.+$ + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + config: + $ref: "#/components/schemas/Config" + subscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + startsAt: + type: string + format: date-time + description: Date when the event subscription will begin/began + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + expiresAt: + type: string + format: date-time + description: | + Date when the event subscription will expire. Only provided when + `subscriptionExpireTime` is indicated by API client or Telco + Operator has specific policy about that. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + status: + type: string + description: |- + Current status of the subscription - Management of Subscription + State engine is not mandatory for now. Note not all statuses may + be considered to be implemented. Details: + - `ACTIVATION_REQUESTED`: Subscription creation (POST) is + triggered but subscription creation process is not finished + yet. + - `ACTIVE`: Subscription creation process is completed. + Subscription is fully operative. + - `DEACTIVE`: Subscription is temporarily inactive, but its + workflow logic is not deleted. + - `EXPIRED`: Subscription is ended (no longer active). + This status applies when subscription is ended due to + `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. + - `DELETED`: Subscription is ended as deleted (no longer + active). This status applies when subscription information is + kept (i.e. subscription workflow is no longer active but its + metainformation is kept). + enum: + - ACTIVATION_REQUESTED + - ACTIVE + - EXPIRED + - DEACTIVE + - DELETED + discriminator: + propertyName: protocol + mapping: + HTTP: "#/components/schemas/HTTPSubscriptionResponse" + MQTT3: "#/components/schemas/MQTTSubscriptionResponse" + MQTT5: "#/components/schemas/MQTTSubscriptionResponse" + AMQP: "#/components/schemas/AMQPSubscriptionResponse" + NATS: "#/components/schemas/NATSSubscriptionResponse" + KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" + + SubscriptionAsync: + description: | + Response for a event-type subscription request managed asynchronously + (Creation or Deletion) + type: object + properties: + subscriptionId: + $ref: "#/components/schemas/SubscriptionId" + + SubscriptionId: + type: string + description: | + When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. + example: qs15-h556-rt89-1298 + Device: + description: | + End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. + The developer can choose to provide the below specified device identifiers: + * `ipv4Address` + * `ipv6Address` + * `phoneNumber` + * `networkAccessIdentifier` + NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. + NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. + type: object + properties: + phoneNumber: + $ref: "#/components/schemas/PhoneNumber" + networkAccessIdentifier: + $ref: "#/components/schemas/NetworkAccessIdentifier" + ipv4Address: + $ref: "#/components/schemas/DeviceIpv4Addr" + ipv6Address: + $ref: "#/components/schemas/DeviceIpv6Address" + minProperties: 1 + + NetworkAccessIdentifier: + description: | + A public identifier addressing a subscription in a mobile network. In + 3GPP terminology, it corresponds to the GPSI formatted with the + External Identifier ({Local Identifier}@{Domain Identifier}). Unlike + the telephone number, the network access identifier is not subjected + to portability ruling in force, and is individually managed by each + operator. + type: string + example: "123456789@domain.com" + + PhoneNumber: + description: | + A public identifier addressing a telephone subscription. In mobile + networks it corresponds to the MSISDN (Mobile Station International + Subscriber Directory Number). In order to be globally unique it has to + be formatted in international format, according to E.164 standard, + prefixed with '+'. + type: string + pattern: '^\+[1-9][0-9]{4,14}$' + example: "+123456789" + + DeviceIpv4Addr: + type: object + description: | + The device should be identified by either the public (observed) IP + address and port as seen by the application server, or the private + (local) and any public (observed) IP addresses in use by the device + (this information can be obtained by various means, for example from + some DNS servers). + + If the allocated and observed IP addresses are the same (i.e. NAT is + not in use) then the same address should be specified for both + publicAddress and privateAddress. + + If NAT64 is in use, the device should be identified by its + publicAddress and publicPort, or separately by its allocated IPv6 + address (field ipv6Address of the Device object) + + In all cases, publicAddress must be specified, along with at least one + of either privateAddress or publicPort, dependent upon which is known. + In general, mobile devices cannot be identified by their public IPv4 + address alone. + properties: + publicAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + privateAddress: + $ref: "#/components/schemas/SingleIpv4Addr" + publicPort: + $ref: "#/components/schemas/Port" + anyOf: + - required: [publicAddress, privateAddress] + - required: [publicAddress, publicPort] + example: {"publicAddress":"84.125.93.10", "publicPort":59765} + + SingleIpv4Addr: + description: A single IPv4 address with no subnet mask + type: string + format: ipv4 + example: "84.125.93.10" + + DeviceIpv6Address: + description: | + The device should be identified by the observed IPv6 address, or by any + single IPv6 address from within the subnet allocated to the device + (e.g. adding ::0 to the /64 prefix). + + The session shall apply to all IP flows between the device subnet and + the specified application server, unless further restricted by the + optional parameters devicePorts or applicationServerPorts. + type: string + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + + Port: + description: TCP or UDP port number + type: integer + minimum: 0 + maximum: 65535 + Protocol: + type: string + enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] + description: | + Identifier of a delivery protocol. Only HTTP is allowed for now + example: "HTTP" + Config: + description: | + Implementation-specific configuration parameters needed by the + subscription manager for acquiring events. + In CAMARA we have predefined attributes like `subscriptionExpireTime`. + Specific event type attributes must be defined in `subscriptionDetail` + Note: if a request is performed for several event type, all subscribed + event will use same `config` parameters. + type: object + required: + - subscriptionDetail + properties: + subscriptionDetail: + $ref: "#/components/schemas/CreateSubscriptionDetail" + subscriptionExpireTime: + type: string + format: date-time + description: | + The subscription expiration time (in date-time format) requested by + the API consumer. Up to API project decision to keep it. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + SinkCredential: + type: object + description: | + A sink credential provides authentication or authorization information + properties: + credentialType: + type: string + enum: + - PLAIN + - ACCESSTOKEN + - REFRESHTOKEN + description: | + The type of the credential. + Note: Type of the credential - MUST be set to ACCESSTOKEN for now + discriminator: + propertyName: credentialType + mapping: + PLAIN: "#/components/schemas/PlainCredential" + ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" + REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" + required: + - credentialType + + CreateSubscriptionDetail: + description: The detail of the requested event subscription + type: object + properties: + device: + description: | + This API need to carry the subscriber's GPSI/MSISDN. + $ref: "#/components/schemas/Device" + applicationId: + description: | + Indicates the Application Identifier. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/ApplicationId" + appcationType: + description: | + Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. + $ref: "#/components/schemas/AppcationType" + required: + - device + + SubscriptionRequest: + description: The request for creating a event-type event subscription + type: object + required: + - sink + - protocol + - config + - types + properties: + protocol: + $ref: "#/components/schemas/Protocol" + sink: + type: string + format: uri + description: | + The address to which events shall be delivered using the selected + protocol. + example: "https://endpoint.example.com/sink" + sinkCredential: + $ref: "#/components/schemas/SinkCredential" + config: + $ref: "#/components/schemas/Config" + BitRate: + type: string + description: | + String representing a bit rate that shall be formatted as follows: + pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" + Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". + TrafficVolume: + type: string + description: | + String representing a traffic volume measured in bytes that shall be formatted as follows: + Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' + Examples:"125 MB", "0.125 GB", "125000 kB" + Dnn: + type: string + description: | + String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; + it shall contain either a DNN Network Identifier, or a full DNN with both the Network + Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. + It shall be coded as string in which the labels are separated by dots + (e.g. "Label1.Label2.Label3"). + QciOr5qi: + type: integer + description: | + It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). + NetType: + type: string + description: Indicates the type of network accessed. SA/EPC + AppSignalingData: + type: object + description: | + Basic . + properties: + dnn: + $ref: '#/components/schemas/Dnn' + qciOr5qi: + $ref: "#/components/schemas/QciOr5qi" + netType: + $ref: '#/components/schemas/NetType' + VolumeMeasurement: + type: object + description: | + Application-level traffic statistics. + properties: + totalVolume: + description: total running traffic statistics. + $ref: "#/components/schemas/TrafficVolume" + ulVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. + $ref: "#/components/schemas/TrafficVolume" + dlVolume: + description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. + $ref: "#/components/schemas/TrafficVolume" + ApplicationIndicatorStatistics: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + subAppStartTime: + $ref: "#/components/schemas/DateTime" + subAppEffDur: + type: integer + description: | + Unsigned integer identifying a period of time in units of seconds + avgBwUl: + description: Average uplink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + avgBwDl: + description: Average downlink bandwidth of an application. + $ref: "#/components/schemas/BitRate" + maxBwUl: + description: Maximum uplink bandwidth of the application + $ref: "#/components/schemas/BitRate" + maxBwDl: + description: Maximum downlink bandwidth of the application + $ref: "#/components/schemas/BitRate" + subAppVol: + $ref: "#/components/schemas/VolumeMeasurement" + maxDelayAn: + type: integer + description: | + Maximum wireless-side latency of an application. + maxDelayDn: + type: integer + description: | + Maximum wired-side latency of an application. + ApplicationExperienceAnalysis: + type: object + description: | + Basic statistics on the application during the application use period. + properties: + avgQoe: + type: integer + description: | + Average score of experience analysis.Value range: 1 to 100 points. + maxResolution: + type: string + description: | + Maximum resolution in the experience analysis period. + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + mostResolution: + type: string + description: | + The resolution with the highest duration ratio within the experience analysis perio + example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). + maxBitRateUl: + description: Maximum uplink bit rate (kbit/s). + $ref: "#/components/schemas/BitRate" + avgBitRateUl: + description: Average uplink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + maxBitRateDl: + description: Maximum downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + avgBitRateDl: + description: Average downlink bit rate (kbit/s) + $ref: "#/components/schemas/BitRate" + stallSec: + type: integer + description: Frame freezing duration, in seconds. + stallNum: + type: integer + description: Number of frame freezing times. The detection period is 5 seconds. + serviceDelay: + type: integer + description: Service latency, in seconds. + initialDur: + type: integer + description: | + Initial service buffering duration, in seconds. The options are as follows: + AreaData: + type: object + description: | + Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. + properties: + city: + type: string + description: user's city of residence. + district: + type: string + description: areas or streets within a city. + AppSignalingAndStatisticsAnalysisRecord: + type: object + description: | + the network's confidence level at being able to meet the network + demands of a given application for a given terminal device. + properties: + starttime: + $ref: "#/components/schemas/DateTime" + endtime: + $ref: "#/components/schemas/DateTime" + appcationType: + $ref: "#/components/schemas/AppcationType" + applicationId: + $ref: "#/components/schemas/ApplicationId" + areaData: + $ref: "#/components/schemas/AreaData" + appSignalingData: + $ref: "#/components/schemas/AppSignalingData" + applicationIndicatorStatistics: + $ref: "#/components/schemas/ApplicationIndicatorStatistics" + applicationExperienceAnalysis: + $ref: "#/components/schemas/ApplicationExperienceAnalysis" + UserExperienceInsightsRecords: + type: object + description: | + Application Network Collection and Recording + properties: + appSignalingAndStatisticsAnalysisRecords: + type: array + items: + $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' + minItems: 1 + ApplicationId: + description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + format: uuid + AppcationType: + description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. + type: string + example: video/game/Live Video + Source: + type: string + format: uri-reference + minLength: 1 + description: | + Identifies the context in which an event happened, as a non-empty + `URI-reference` like: + - URI with a DNS authority: + * https://github.com/cloudevents + * mailto:cncf-wg-serverless@lists.cncf.io + - Universally-unique URN with a UUID: + * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - Application-specific identifier: + * /cloudevents/spec/pull/123 + * 1-555-123-4567 + example: "https://notificationSendServer12.supertelco.com" + TerminationReason: + type: string + description: | + - NETWORK_TERMINATED - API server stopped sending notification + - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by + the requester) has been reached + - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the + requester) has been reached + - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by + the requester) expiration time has been reached + - SUBSCRIPTION_DELETED - Subscription was deleted by the requester + enum: + - MAX_EVENTS_REACHED + - NETWORK_TERMINATED + - SUBSCRIPTION_EXPIRED + - ACCESS_TOKEN_EXPIRED + - SUBSCRIPTION_DELETED + + DateTime: + type: string + format: date-time + description: | + Timestamp of when the occurrence happened. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + example: "2023-07-03T12:27:08.312Z" + + EventTypeNotification: + type: string + description: | + event-type - Event triggered when an event-type event occurred + subscription-ended: Event triggered when the subscription ends + enum: + - org.camaraproject.user-experience-insights.v0.network-quality + - org.camaraproject.user-experience-insights.v0.subscription-ended + ErrorInfo: + type: object + description: Error information + required: + - status + - code + - message + properties: + status: + type: integer + description: HTTP response status code + code: + type: string + description: A human-readable code to describe the error + message: + type: string + description: A human-readable description of what the event represents + UserExperienceInsightsResponse: + type: object + description: user experience insights result + required: + - UserExperienceInsightsRecords + properties: + device: + $ref: '#/components/schemas/Device' + UserExperienceInsightsRecords: + type: array + items: + $ref: "#/components/schemas/UserExperienceInsightsRecords" + minItems: 1 + responses: + CreateSubscriptionBadRequest400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + - OUT_OF_RANGE + - INVALID_PROTOCOL + - INVALID_CREDENTIAL + - INVALID_TOKEN + - INVALID_SINK + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_OUT_OF_RANGE: + description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested + value: + status: 400 + code: OUT_OF_RANGE + message: Client specified an invalid range. + GENERIC_400_INVALID_PROTOCOL: + description: Invalid protocol for events subscription management + value: + status: 400 + code: INVALID_PROTOCOL + message: Only HTTP is supported + GENERIC_400_INVALID_CREDENTIAL: + description: Invalid sink credential type + value: + status: 400 + code: INVALID_CREDENTIAL + message: Only Access token is supported + GENERIC_400_INVALID_TOKEN: + description: Invalid token type for sink credential of type ACCESSTOKEN + value: + status: 400 + code: INVALID_TOKEN + message: Only bearer token is supported + GENERIC_400_INVALID_SINK: + description: Invalid sink value + value: + status: 400 + code: INVALID_SINK + message: sink not valid for the specified protocol + Generic400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + SubscriptionIdRequired400: + description: Problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + GENERIC_400_SUBSCRIPTION_ID_REQUIRED: + description: subscription id is required + value: + status: 400 + code: INVALID_ARGUMENT + message: "Expected property is missing: subscriptionId" + Generic401: + description: Authentication problem with the client request + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 401 + code: + enum: + - UNAUTHENTICATED + + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. + + Generic403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + SubscriptionPermissionDenied403: + description: Client does not have sufficient permission + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + - SUBSCRIPTION_MISMATCH + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + GENERIC_403_SUBSCRIPTION_MISMATCH: + description: Inconsistent access token for requested subscription + value: + status: 403 + code: "SUBSCRIPTION_MISMATCH" + message: "Inconsistent access token for requested events subscription" + Generic404: + description: Resource Not Found + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - NOT_FOUND + examples: + GENERIC_404_NOT_FOUND: + description: Resource is not found + value: + status: 404 + code: NOT_FOUND + message: The specified resource is not found. + Generic410: + description: Gone + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 410 + code: + enum: + - GONE + examples: + GENERIC_410_GONE: + description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available + value: + status: 410 + code: GONE + message: Access to the target resource is no longer available. + CreateSubscriptionUnprocessableEntity422: + description: Unprocessable Entity + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNNECESSARY_IDENTIFIER + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device or phone number has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: "#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 429 + code: + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. \ No newline at end of file From 505c181d2a9d90d4c689ac66a71baf6e6559812b Mon Sep 17 00:00:00 2001 From: XunliYang Date: Thu, 30 Apr 2026 15:09:30 +0800 Subject: [PATCH 4/4] modify file catalog --- ...ExperienceInsights_ChinaMobileHongKong.md} | 96 +- ...ser-experience-insights-subscriptions.yaml | 1217 ----------------- .../user-experience-insights.yaml | 995 -------------- .../API-proposal-user experience insights.md | 48 - .../API-proposal-user experience insights.md | 48 - ...ser-experience-insights-subscriptions.yaml | 1217 ----------------- documentation/user-experience-insights.yaml | 995 -------------- 7 files changed, 48 insertions(+), 4568 deletions(-) rename documentation/API proposals/{API-proposal-user experience insights.md => API-proposal_UserExperienceInsights_ChinaMobileHongKong.md} (98%) delete mode 100644 documentation/API proposals/user-experience-insights-subscriptions.yaml delete mode 100644 documentation/API proposals/user-experience-insights.yaml delete mode 100644 documentation/API-proposal-user experience insights.md delete mode 100644 documentation/SupportingDocuments/API-proposal-user experience insights.md delete mode 100644 documentation/user-experience-insights-subscriptions.yaml delete mode 100644 documentation/user-experience-insights.yaml diff --git a/documentation/API proposals/API-proposal-user experience insights.md b/documentation/API proposals/API-proposal_UserExperienceInsights_ChinaMobileHongKong.md similarity index 98% rename from documentation/API proposals/API-proposal-user experience insights.md rename to documentation/API proposals/API-proposal_UserExperienceInsights_ChinaMobileHongKong.md index 6c6a724..6cd1fc1 100644 --- a/documentation/API proposals/API-proposal-user experience insights.md +++ b/documentation/API proposals/API-proposal_UserExperienceInsights_ChinaMobileHongKong.md @@ -1,48 +1,48 @@ -# API Proposal Template -This template captures all the information that a partner should fill out when proposing a new API (or API family) to CAMARA. - - -### API family name -User Experience Insights (UEI) - -### API family owner -China Mobile Hong Kong, Huawei - -### API summary -This API allows Application Functions (AF) to subscribe to real-time network experience notifications for specific users. The API leverages the analytics capabilities of the NWDAF (Network Data Analytics Function) and exposes them through the NEF (Network Exposure Function). When a user's network experience (e.g., throughput, latency, or reliability) falls below a predefined threshold or changes significantly, the network proactively notifies the AF. - -In-scope business cases: - -VIP Customer Care & Proactive Intervention: Operator customer service systems can monitor high-value users' real-time experience. If a degradation is detected, the system can trigger automated "care" actions (e.g., issuing temporary vouchers or prioritizing technical support) before the user even files a complaint. - -Adaptive Application Logic: Streaming or gaming applications can use this API to receive proactive alerts about user experience trends, allowing them to adjust application-level parameters (like bitrates or buffering strategies) ahead of time. - -SLA Monitoring for Enterprise Services: Enterprises can subscribe to experience insights for their workforce to ensure critical remote-working applications meet the required performance standards. - -### Technical viability -This API is technically viable based on 3GPP 5G core network standards: - -3GPP TS 23.288 (NWDAF): Utilizes the "User Data Congestion" and "Service Experience" analytics ID. - -3GPP TS 23.502 / TS 29.522 (NEF): Requires NEF to support the exposure of analytics via Nnef_EventExposure or Nnef_AnalyticsExposure services. - -Maturity: These features are part of 3GPP Release 16/17, which are currently being deployed in commercial 5G SA networks. - -### Commercial viability -The underlying network capabilities (NEF and NWDAF) are now widely available as industrialized solutions. Many Tier-1 operators have already deployed NWDAF for internal network optimization and are moving towards external exposure of these insights to enhance ecosystem value. - -### YAML code available? -YES. - -### Validated in lab/productive environments? -YES. Validated in a lab environment simulating 5G SA core network signaling with actual NWDAF analytics triggers. - -### Validated with real customers? -No. - -### Validated with operators? -No. - -### Supporters in API Backlog Working Group -List of supporters. -*NOTE: That shall be added by the Working Group. Supporting an API proposal means that the supporting company must provide at least 1 (one) Maintainer at the time of the Sub Project creation.* +# API Proposal Template +This template captures all the information that a partner should fill out when proposing a new API (or API family) to CAMARA. + + +### API family name +User Experience Insights (UEI) + +### API family owner +China Mobile Hong Kong, Huawei + +### API summary +This API allows Application Functions (AF) to subscribe to real-time network experience notifications for specific users. The API leverages the analytics capabilities of the NWDAF (Network Data Analytics Function) and exposes them through the NEF (Network Exposure Function). When a user's network experience (e.g., throughput, latency, or reliability) falls below a predefined threshold or changes significantly, the network proactively notifies the AF. + +In-scope business cases: + +VIP Customer Care & Proactive Intervention: Operator customer service systems can monitor high-value users' real-time experience. If a degradation is detected, the system can trigger automated "care" actions (e.g., issuing temporary vouchers or prioritizing technical support) before the user even files a complaint. + +Adaptive Application Logic: Streaming or gaming applications can use this API to receive proactive alerts about user experience trends, allowing them to adjust application-level parameters (like bitrates or buffering strategies) ahead of time. + +SLA Monitoring for Enterprise Services: Enterprises can subscribe to experience insights for their workforce to ensure critical remote-working applications meet the required performance standards. + +### Technical viability +This API is technically viable based on 3GPP 5G core network standards: + +3GPP TS 23.288 (NWDAF): Utilizes the "User Data Congestion" and "Service Experience" analytics ID. + +3GPP TS 23.502 / TS 29.522 (NEF): Requires NEF to support the exposure of analytics via Nnef_EventExposure or Nnef_AnalyticsExposure services. + +Maturity: These features are part of 3GPP Release 16/17, which are currently being deployed in commercial 5G SA networks. + +### Commercial viability +The underlying network capabilities (NEF and NWDAF) are now widely available as industrialized solutions. Many Tier-1 operators have already deployed NWDAF for internal network optimization and are moving towards external exposure of these insights to enhance ecosystem value. + +### YAML code available? +YES. + +### Validated in lab/productive environments? +YES. Validated in a lab environment simulating 5G SA core network signaling with actual NWDAF analytics triggers. + +### Validated with real customers? +No. + +### Validated with operators? +No. + +### Supporters in API Backlog Working Group +List of supporters. +*NOTE: That shall be added by the Working Group. Supporting an API proposal means that the supporting company must provide at least 1 (one) Maintainer at the time of the Sub Project creation.* diff --git a/documentation/API proposals/user-experience-insights-subscriptions.yaml b/documentation/API proposals/user-experience-insights-subscriptions.yaml deleted file mode 100644 index 8722279..0000000 --- a/documentation/API proposals/user-experience-insights-subscriptions.yaml +++ /dev/null @@ -1,1217 +0,0 @@ -openapi: 3.0.3 -info: - title: User Experience Insights - version: wip - x-camara-commonalities: 0.6 - description: | - With CAMARA User Experience Insights subscription service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. - - # Introduction - - The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. - - This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. - - This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. - - This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. - - for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. - # Relevant terms and definitions - - * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. - - # API functionality - The API provides the datatype parameter to report network quality at different granularities. Poor-QoE events are reported in real time when the network detects poor-QoE events. - - This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). - - This API provides the function of reporting poor-QoE data in real time or periodically reporting no poor-QoE data based on the datatype parameter. - POOR_QOE_REPORT Detects poor network experience and reports the collected statistical data. - PERIODIC_REPORT Periodically collecting and reporting data. - ALL Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. - - - ### Notification callback - - This endpoint describes the event notification received on subscription listener side when the event occurred. - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -externalDocs: - description: Product documentation at CAMARA. - url: https://github.com/camaraproject/UserExperienceInsights - -servers: - - url: "{apiRoot}/user-experience-insights" - variables: - apiRoot: - default: http://localhost:9091 - description: | - API root, defined by service provider, e.g. - `api.example.com` or `api.example.com/somepath` - -tags: - - name: User Experience Insights - description: | - Create and manage a subscription to receive periodic connectivity - insights - -paths: - /subscriptions: - post: - tags: - - User Experience Insights - description: "Create a User Experience Insights Subscription for a device" - summary: "Create a User Experience Insights Subscription for a device" - operationId: createSubscription - parameters: - - $ref: "#/components/parameters/x-correlator" - security: - - openId: - - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:create - - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionRequest" - required: true - callbacks: - notifications: - "{$request.body#/sink}": - post: - summary: "Subscription notification callback" - description: | - Important: this endpoint is to be implemented by the API - consumer.The User Experience Insights server will call this - endpoint whenever a connectivity event occurs that changes - the network's ability to meet the application's demands for - a given device. - operationId: postNotification - parameters: - - $ref: "#/components/parameters/x-correlator" - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/CloudEvent" - required: true - responses: - "201": - description: Successful notification - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - "400": - $ref: "#/components/responses/Generic400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/Generic403" - "410": - $ref: "#/components/responses/Generic410" - "429": - $ref: "#/components/responses/Generic429" - security: - - {} - - notificationsBearerAuth: [] - responses: - "201": - description: Created - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionAsync" - "400": - $ref: "#/components/responses/CreateSubscriptionBadRequest400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/SubscriptionPermissionDenied403" - "409": - $ref: "#/components/responses/Generic409" - "422": - $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" - "429": - $ref: "#/components/responses/Generic429" - /subscriptions/{subscriptionId}: - get: - tags: - - User Experience Insights - summary: "Operation to retrieve a subscription based on the provided ID" - operationId: getSubscription - description: Retrieve a given subscription by ID - security: - - openId: - - connectivity-insights-subscriptions:read - parameters: - - $ref: "#/components/parameters/SubscriptionId" - - $ref: "#/components/parameters/x-correlator" - responses: - "200": - description: OK - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/Subscription" - "400": - $ref: "#/components/responses/SubscriptionIdRequired400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/Generic403" - "404": - $ref: "#/components/responses/Generic404" - delete: - tags: - - User Experience Insights - summary: "Operation to delete a subscription" - operationId: deleteSubscription - description: Delete a given subscription by ID - security: - - openId: - - user-experience-insights:delete - parameters: - - $ref: "#/components/parameters/SubscriptionId" - - $ref: "#/components/parameters/x-correlator" - responses: - "204": - description: apiName subscription deleted - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - "202": - description: | - Request accepted to be processed. It applies for async deletion - process. - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionAsync" - "400": - $ref: "#/components/responses/SubscriptionIdRequired400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/Generic403" - "404": - $ref: "#/components/responses/Generic404" - -components: - securitySchemes: - openId: - type: openIdConnect - description: Common security scheme for all CAMARA APIs - openIdConnectUrl: https://example.com/.well-known/openid-configuration - notificationsBearerAuth: - description: Bearer authorization for notifications - type: http - scheme: bearer - bearerFormat: "{$request.body#/sinkCredential.credentialType}" - parameters: - SubscriptionId: - name: subscriptionId - in: path - description: | - Subscription identifier that was obtained from the create event - subscription operation - required: true - schema: - $ref: "#/components/schemas/SubscriptionId" - x-correlator: - name: x-correlator - in: header - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - headers: - x-correlator: - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - schemas: - XCorrelator: - type: string - pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ - example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" - Subscription: - description: Represents a event-type subscription. - type: object - required: - - sink - - protocol - - config - - types - - id - - startsAt - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - pattern: ^https:\/\/.+$ - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - config: - $ref: "#/components/schemas/Config" - subscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - startsAt: - type: string - format: date-time - description: Date when the event subscription will begin/began - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - expiresAt: - type: string - format: date-time - description: | - Date when the event subscription will expire. Only provided when - `subscriptionExpireTime` is indicated by API client or Telco - Operator has specific policy about that. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - status: - type: string - description: |- - Current status of the subscription - Management of Subscription - State engine is not mandatory for now. Note not all statuses may - be considered to be implemented. Details: - - `ACTIVATION_REQUESTED`: Subscription creation (POST) is - triggered but subscription creation process is not finished - yet. - - `ACTIVE`: Subscription creation process is completed. - Subscription is fully operative. - - `DEACTIVE`: Subscription is temporarily inactive, but its - workflow logic is not deleted. - - `EXPIRED`: Subscription is ended (no longer active). - This status applies when subscription is ended due to - `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. - - `DELETED`: Subscription is ended as deleted (no longer - active). This status applies when subscription information is - kept (i.e. subscription workflow is no longer active but its - metainformation is kept). - enum: - - ACTIVATION_REQUESTED - - ACTIVE - - EXPIRED - - DEACTIVE - - DELETED - discriminator: - propertyName: protocol - mapping: - HTTP: "#/components/schemas/HTTPSubscriptionResponse" - MQTT3: "#/components/schemas/MQTTSubscriptionResponse" - MQTT5: "#/components/schemas/MQTTSubscriptionResponse" - AMQP: "#/components/schemas/AMQPSubscriptionResponse" - NATS: "#/components/schemas/NATSSubscriptionResponse" - KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" - - SubscriptionAsync: - description: | - Response for a event-type subscription request managed asynchronously - (Creation or Deletion) - type: object - properties: - subscriptionId: - $ref: "#/components/schemas/SubscriptionId" - - SubscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - Device: - description: | - End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. - The developer can choose to provide the below specified device identifiers: - * `ipv4Address` - * `ipv6Address` - * `phoneNumber` - * `networkAccessIdentifier` - NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. - NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. - type: object - properties: - phoneNumber: - $ref: "#/components/schemas/PhoneNumber" - networkAccessIdentifier: - $ref: "#/components/schemas/NetworkAccessIdentifier" - ipv4Address: - $ref: "#/components/schemas/DeviceIpv4Addr" - ipv6Address: - $ref: "#/components/schemas/DeviceIpv6Address" - minProperties: 1 - - NetworkAccessIdentifier: - description: | - A public identifier addressing a subscription in a mobile network. In - 3GPP terminology, it corresponds to the GPSI formatted with the - External Identifier ({Local Identifier}@{Domain Identifier}). Unlike - the telephone number, the network access identifier is not subjected - to portability ruling in force, and is individually managed by each - operator. - type: string - example: "123456789@domain.com" - - PhoneNumber: - description: | - A public identifier addressing a telephone subscription. In mobile - networks it corresponds to the MSISDN (Mobile Station International - Subscriber Directory Number). In order to be globally unique it has to - be formatted in international format, according to E.164 standard, - prefixed with '+'. - type: string - pattern: '^\+[1-9][0-9]{4,14}$' - example: "+123456789" - - DeviceIpv4Addr: - type: object - description: | - The device should be identified by either the public (observed) IP - address and port as seen by the application server, or the private - (local) and any public (observed) IP addresses in use by the device - (this information can be obtained by various means, for example from - some DNS servers). - - If the allocated and observed IP addresses are the same (i.e. NAT is - not in use) then the same address should be specified for both - publicAddress and privateAddress. - - If NAT64 is in use, the device should be identified by its - publicAddress and publicPort, or separately by its allocated IPv6 - address (field ipv6Address of the Device object) - - In all cases, publicAddress must be specified, along with at least one - of either privateAddress or publicPort, dependent upon which is known. - In general, mobile devices cannot be identified by their public IPv4 - address alone. - properties: - publicAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - privateAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - publicPort: - $ref: "#/components/schemas/Port" - anyOf: - - required: [publicAddress, privateAddress] - - required: [publicAddress, publicPort] - example: {"publicAddress":"84.125.93.10", "publicPort":59765} - - SingleIpv4Addr: - description: A single IPv4 address with no subnet mask - type: string - format: ipv4 - example: "84.125.93.10" - - DeviceIpv6Address: - description: | - The device should be identified by the observed IPv6 address, or by any - single IPv6 address from within the subnet allocated to the device - (e.g. adding ::0 to the /64 prefix). - - The session shall apply to all IP flows between the device subnet and - the specified application server, unless further restricted by the - optional parameters devicePorts or applicationServerPorts. - type: string - format: ipv6 - example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 - - Port: - description: TCP or UDP port number - type: integer - minimum: 0 - maximum: 65535 - Protocol: - type: string - enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] - description: | - Identifier of a delivery protocol. Only HTTP is allowed for now - example: "HTTP" - Config: - description: | - Implementation-specific configuration parameters needed by the - subscription manager for acquiring events. - In CAMARA we have predefined attributes like `subscriptionExpireTime`. - Specific event type attributes must be defined in `subscriptionDetail` - Note: if a request is performed for several event type, all subscribed - event will use same `config` parameters. - type: object - required: - - subscriptionDetail - properties: - subscriptionDetail: - $ref: "#/components/schemas/CreateSubscriptionDetail" - subscriptionExpireTime: - type: string - format: date-time - description: | - The subscription expiration time (in date-time format) requested by - the API consumer. Up to API project decision to keep it. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - datatype: - type: string - description: | - POOR_QOE_REPORT: Detects poor network experience and reports the collected statistical data. - PERIODIC_REPORT: Periodically collecting and reporting data. - ALL: Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. - enum: - - POOR_QOE_REPORT - - PERIODIC_REPORT - - ALL - SinkCredential: - type: object - description: | - A sink credential provides authentication or authorization information - properties: - credentialType: - type: string - enum: - - PLAIN - - ACCESSTOKEN - - REFRESHTOKEN - description: | - The type of the credential. - Note: Type of the credential - MUST be set to ACCESSTOKEN for now - discriminator: - propertyName: credentialType - mapping: - PLAIN: "#/components/schemas/PlainCredential" - ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" - REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" - required: - - credentialType - - CreateSubscriptionDetail: - description: The detail of the requested event subscription - type: object - properties: - device: - description: | - This API need to carry the subscriber's GPSI/MSISDN. - $ref: "#/components/schemas/Device" - appcationType: - description: | - Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. - $ref: "#/components/schemas/AppcationType" - required: - - device - - SubscriptionRequest: - description: The request for creating a event-type event subscription - type: object - required: - - sink - - protocol - - config - - types - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - sinkCredential: - $ref: "#/components/schemas/SinkCredential" - config: - $ref: "#/components/schemas/Config" - BitRate: - type: string - description: | - String representing a bit rate that shall be formatted as follows: - pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" - Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". - TrafficVolume: - type: string - description: | - String representing a traffic volume measured in bytes that shall be formatted as follows: - Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' - Examples:"125 MB", "0.125 GB", "125000 kB" - Dnn: - type: string - description: | - String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; - it shall contain either a DNN Network Identifier, or a full DNN with both the Network - Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. - It shall be coded as string in which the labels are separated by dots - (e.g. "Label1.Label2.Label3"). - QciOr5qi: - type: integer - description: | - It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). - NetType: - type: string - description: Indicates the type of network accessed. SA/EPC - AppSignalingData: - type: object - description: | - Basic . - properties: - dnn: - $ref: '#/components/schemas/Dnn' - qciOr5qi: - $ref: "#/components/schemas/QciOr5qi" - netType: - $ref: '#/components/schemas/NetType' - VolumeMeasurement: - type: object - description: | - Application-level traffic statistics. - properties: - totalVolume: - description: total running traffic statistics. - $ref: "#/components/schemas/TrafficVolume" - ulVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. - $ref: "#/components/schemas/TrafficVolume" - dlVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. - $ref: "#/components/schemas/TrafficVolume" - ApplicationIndicatorStatistics: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - subAppStartTime: - $ref: "#/components/schemas/DateTime" - subAppEffDur: - type: integer - description: | - Unsigned integer identifying a period of time in units of seconds - avgBwUl: - description: Average uplink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - avgBwDl: - description: Average downlink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - maxBwUl: - description: Maximum uplink bandwidth of the application - $ref: "#/components/schemas/BitRate" - maxBwDl: - description: Maximum downlink bandwidth of the application - $ref: "#/components/schemas/BitRate" - subAppVol: - $ref: "#/components/schemas/VolumeMeasurement" - maxDelayAn: - type: integer - description: | - Maximum wireless-side latency of an application. - maxDelayDn: - type: integer - description: | - Maximum wired-side latency of an application. - ApplicationExperienceAnalysis: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - avgQoe: - type: integer - description: | - Average score of experience analysis.Value range: 1 to 100 points. - maxResolution: - type: string - description: | - Maximum resolution in the experience analysis period. - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - mostResolution: - type: string - description: | - The resolution with the highest duration ratio within the experience analysis perio - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - maxBitRateUl: - description: Maximum uplink bit rate (kbit/s). - $ref: "#/components/schemas/BitRate" - avgBitRateUl: - description: Average uplink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - maxBitRateDl: - description: Maximum downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - avgBitRateDl: - description: Average downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - stallSec: - type: integer - description: Frame freezing duration, in seconds. - stallNum: - type: integer - description: Number of frame freezing times. The detection period is 5 seconds. - serviceDelay: - type: integer - description: Service latency, in seconds. - initialDur: - type: integer - description: | - Initial service buffering duration, in seconds. The options are as follows: - AreaData: - type: object - description: | - Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. - properties: - city: - type: string - description: user's city of residence. - district: - type: string - description: areas or streets within a city. - AppSignalingAndStatisticsAnalysisRecord: - type: object - description: | - the network's confidence level at being able to meet the network - demands of a given application for a given terminal device. - properties: - starttime: - $ref: "#/components/schemas/DateTime" - endtime: - $ref: "#/components/schemas/DateTime" - appcationType: - $ref: "#/components/schemas/AppcationType" - applicationId: - $ref: "#/components/schemas/ApplicationId" - areaData: - $ref: "#/components/schemas/AreaData" - appSignalingData: - $ref: "#/components/schemas/AppSignalingData" - applicationIndicatorStatistics: - $ref: "#/components/schemas/ApplicationIndicatorStatistics" - applicationExperienceAnalysis: - $ref: "#/components/schemas/ApplicationExperienceAnalysis" - UserExperienceInsightsRecords: - type: object - description: | - Application Network Collection and Recording - properties: - appSignalingAndStatisticsAnalysisRecords: - type: array - items: - $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' - minItems: 1 - ApplicationId: - description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - format: uuid - AppcationType: - description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - example: video/game/Live Video - Source: - type: string - format: uri-reference - minLength: 1 - description: | - Identifies the context in which an event happened, as a non-empty - `URI-reference` like: - - URI with a DNS authority: - * https://github.com/cloudevents - * mailto:cncf-wg-serverless@lists.cncf.io - - Universally-unique URN with a UUID: - * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 - - Application-specific identifier: - * /cloudevents/spec/pull/123 - * 1-555-123-4567 - example: "https://notificationSendServer12.supertelco.com" - CloudEvent: - description: The Cloud-Event used for the callback. - required: - - id - - source - - specversion - - type - - time - properties: - id: - type: string - description: | - identifier of this event, that must be unique in the source context. - source: - $ref: "#/components/schemas/Source" - type: - $ref: "#/components/schemas/EventTypeNotification" - specversion: - type: string - description: | - Version of the specification to which this event conforms (must be - 1.0 if it conforms to cloudevents 1.0.2 version) - enum: - - "1.0" - datacontenttype: - type: string - description: | - 'media-type that describes the event payload encoding, - must be "application/json" for CAMARA APIs' - enum: - - application/json - data: - $ref: "#/components/schemas/UserExperienceInsightsRecords" - time: - $ref: "#/components/schemas/DateTime" - discriminator: - propertyName: "type" - mapping: - org.camaraproject.user-experience-insights.v0.network-quality: - "#/components/schemas/EventNetworkQuality" - org.camaraproject.connectivityinsights.v0.eventSubscriptionEnded: - "#/components/schemas/EventSubscriptionEnded" - - EventNetworkQuality: - description: event structure for Network Quality - allOf: - - $ref: "#/components/schemas/CloudEvent" - - type: object - properties: - data: - $ref: "#/components/schemas/UserExperienceInsightsRecords" - - EventSubscriptionEnded: - description: event structure for event subscription ended - allOf: - - $ref: "#/components/schemas/CloudEvent" - - type: object - properties: - data: - $ref: "#/components/schemas/SubscriptionEnded" - - SubscriptionEnded: - description: Event detail structure for subscription ended event - type: object - required: - - terminationReason - - subscriptionId - properties: - terminationReason: - $ref: "#/components/schemas/TerminationReason" - subscriptionId: - $ref: "#/components/schemas/SubscriptionId" - terminationDescription: - description: Explanation why a subscription ended or had to end. - type: string - - TerminationReason: - type: string - description: | - - NETWORK_TERMINATED - API server stopped sending notification - - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by - the requester) has been reached - - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the - requester) has been reached - - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by - the requester) expiration time has been reached - - SUBSCRIPTION_DELETED - Subscription was deleted by the requester - enum: - - MAX_EVENTS_REACHED - - NETWORK_TERMINATED - - SUBSCRIPTION_EXPIRED - - ACCESS_TOKEN_EXPIRED - - SUBSCRIPTION_DELETED - - DateTime: - type: string - format: date-time - description: | - Timestamp of when the occurrence happened. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - - EventTypeNotification: - type: string - description: | - event-type - Event triggered when an event-type event occurred - subscription-ended: Event triggered when the subscription ends - enum: - - org.camaraproject.user-experience-insights.v0.network-quality - - org.camaraproject.user-experience-insights.v0.subscription-ended - ErrorInfo: - type: object - description: Error information - required: - - status - - code - - message - properties: - status: - type: integer - description: HTTP response status code - code: - type: string - description: A human-readable code to describe the error - message: - type: string - description: A human-readable description of what the event represents - - responses: - CreateSubscriptionBadRequest400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - - OUT_OF_RANGE - - INVALID_PROTOCOL - - INVALID_CREDENTIAL - - INVALID_TOKEN - - INVALID_SINK - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_OUT_OF_RANGE: - description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested - value: - status: 400 - code: OUT_OF_RANGE - message: Client specified an invalid range. - GENERIC_400_INVALID_PROTOCOL: - description: Invalid protocol for events subscription management - value: - status: 400 - code: INVALID_PROTOCOL - message: Only HTTP is supported - GENERIC_400_INVALID_CREDENTIAL: - description: Invalid sink credential type - value: - status: 400 - code: INVALID_CREDENTIAL - message: Only Access token is supported - GENERIC_400_INVALID_TOKEN: - description: Invalid token type for sink credential of type ACCESSTOKEN - value: - status: 400 - code: INVALID_TOKEN - message: Only bearer token is supported - GENERIC_400_INVALID_SINK: - description: Invalid sink value - value: - status: 400 - code: INVALID_SINK - message: sink not valid for the specified protocol - Generic400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - SubscriptionIdRequired400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_SUBSCRIPTION_ID_REQUIRED: - description: subscription id is required - value: - status: 400 - code: INVALID_ARGUMENT - message: "Expected property is missing: subscriptionId" - Generic401: - description: Authentication problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 401 - code: - enum: - - UNAUTHENTICATED - - examples: - GENERIC_401_UNAUTHENTICATED: - description: Request cannot be authenticated and a new authentication is required - value: - status: 401 - code: UNAUTHENTICATED - message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. - - Generic403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - SubscriptionPermissionDenied403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - - SUBSCRIPTION_MISMATCH - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - GENERIC_403_SUBSCRIPTION_MISMATCH: - description: Inconsistent access token for requested subscription - value: - status: 403 - code: "SUBSCRIPTION_MISMATCH" - message: "Inconsistent access token for requested events subscription" - Generic404: - description: Resource Not Found - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 404 - code: - enum: - - NOT_FOUND - examples: - GENERIC_404_NOT_FOUND: - description: Resource is not found - value: - status: 404 - code: NOT_FOUND - message: The specified resource is not found. - Generic409: - description: Conflict - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 409 - code: - enum: - - ABORTED - - ALREADY_EXISTS - examples: - GENERIC_409_ABORTED: - description: Concurreny of processes of the same nature/scope - value: - status: 409 - code: ABORTED - message: Concurrency conflict. - GENERIC_409_ALREADY_EXISTS: - description: Trying to create an existing resource - value: - status: 409 - code: ALREADY_EXISTS - message: The resource that a client tried to create already exists. - Generic410: - description: Gone - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 410 - code: - enum: - - GONE - examples: - GENERIC_410_GONE: - description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available - value: - status: 410 - code: GONE - message: Access to the target resource is no longer available. - CreateSubscriptionUnprocessableEntity422: - description: Unprocessable Entity - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 422 - code: - enum: - - SERVICE_NOT_APPLICABLE - - MISSING_IDENTIFIER - - UNNECESSARY_IDENTIFIER - examples: - GENERIC_422_SERVICE_NOT_APPLICABLE: - description: Service not applicable for the provided identifier - value: - status: 422 - code: SERVICE_NOT_APPLICABLE - message: The service is not available for the provided identifier. - GENERIC_422_MISSING_IDENTIFIER: - description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token - value: - status: 422 - code: MISSING_IDENTIFIER - message: The device cannot be identified. - GENERIC_422_UNNECESSARY_IDENTIFIER: - description: An explicit identifier is provided when a device or phone number has already been identified from the access token - value: - status: 422 - code: UNNECESSARY_IDENTIFIER - message: The device is already identified by the access token. - Generic429: - description: Too Many Requests - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 429 - code: - enum: - - QUOTA_EXCEEDED - - TOO_MANY_REQUESTS - examples: - GENERIC_429_QUOTA_EXCEEDED: - description: Request is rejected due to exceeding a business quota limit - value: - status: 429 - code: QUOTA_EXCEEDED - message: Out of resource quota. - GENERIC_429_TOO_MANY_REQUESTS: - description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached - value: - status: 429 - code: TOO_MANY_REQUESTS - message: Rate limit reached. \ No newline at end of file diff --git a/documentation/API proposals/user-experience-insights.yaml b/documentation/API proposals/user-experience-insights.yaml deleted file mode 100644 index f8421f7..0000000 --- a/documentation/API proposals/user-experience-insights.yaml +++ /dev/null @@ -1,995 +0,0 @@ -openapi: 3.0.3 -info: - title: User Experience Insights - version: wip - x-camara-commonalities: 0.6 - description: | - With CAMARA User Experience Insights service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. - - # Introduction - - The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. - - This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. - - This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. - - This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. - - for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. - # Relevant terms and definitions - - * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. - - # API functionality - - This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). - - - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -externalDocs: - description: Product documentation at CAMARA. - url: https://github.com/camaraproject/UserExperienceInsights - -servers: - - url: "{apiRoot}/user-experience-insights/" - variables: - apiRoot: - default: http://localhost:9091 - description: | - API root, defined by service provider, e.g. - `api.example.com` or `api.example.com/somepath` - -tags: - - name: User Experience Insights - description: | - read User Experience Insights - -paths: - /userexperienceinsights: - post: - tags: - - User Experience Insights - description: "read a User Experience Insights for a device" - summary: "read a User Experience Insights for a device" - operationId: readSubscription - parameters: - - $ref: "#/components/parameters/x-correlator" - security: - - openId: - - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:read - - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionRequest" - required: true - responses: - "200": - description: OK - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/UserExperienceInsightsResponse" - "400": - $ref: "#/components/responses/CreateSubscriptionBadRequest400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/SubscriptionPermissionDenied403" - "422": - $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" - "429": - $ref: "#/components/responses/Generic429" -components: - securitySchemes: - openId: - type: openIdConnect - description: Common security scheme for all CAMARA APIs - openIdConnectUrl: https://example.com/.well-known/openid-configuration - notificationsBearerAuth: - description: Bearer authorization for notifications - type: http - scheme: bearer - bearerFormat: "{$request.body#/sinkCredential.credentialType}" - parameters: - SubscriptionId: - name: subscriptionId - in: path - description: | - Subscription identifier that was obtained from the create event - subscription operation - required: true - schema: - $ref: "#/components/schemas/SubscriptionId" - x-correlator: - name: x-correlator - in: header - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - headers: - x-correlator: - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - schemas: - XCorrelator: - type: string - pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ - example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" - Subscription: - description: Represents a event-type subscription. - type: object - required: - - sink - - protocol - - config - - types - - id - - startsAt - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - pattern: ^https:\/\/.+$ - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - config: - $ref: "#/components/schemas/Config" - subscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - startsAt: - type: string - format: date-time - description: Date when the event subscription will begin/began - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - expiresAt: - type: string - format: date-time - description: | - Date when the event subscription will expire. Only provided when - `subscriptionExpireTime` is indicated by API client or Telco - Operator has specific policy about that. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - status: - type: string - description: |- - Current status of the subscription - Management of Subscription - State engine is not mandatory for now. Note not all statuses may - be considered to be implemented. Details: - - `ACTIVATION_REQUESTED`: Subscription creation (POST) is - triggered but subscription creation process is not finished - yet. - - `ACTIVE`: Subscription creation process is completed. - Subscription is fully operative. - - `DEACTIVE`: Subscription is temporarily inactive, but its - workflow logic is not deleted. - - `EXPIRED`: Subscription is ended (no longer active). - This status applies when subscription is ended due to - `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. - - `DELETED`: Subscription is ended as deleted (no longer - active). This status applies when subscription information is - kept (i.e. subscription workflow is no longer active but its - metainformation is kept). - enum: - - ACTIVATION_REQUESTED - - ACTIVE - - EXPIRED - - DEACTIVE - - DELETED - discriminator: - propertyName: protocol - mapping: - HTTP: "#/components/schemas/HTTPSubscriptionResponse" - MQTT3: "#/components/schemas/MQTTSubscriptionResponse" - MQTT5: "#/components/schemas/MQTTSubscriptionResponse" - AMQP: "#/components/schemas/AMQPSubscriptionResponse" - NATS: "#/components/schemas/NATSSubscriptionResponse" - KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" - - SubscriptionAsync: - description: | - Response for a event-type subscription request managed asynchronously - (Creation or Deletion) - type: object - properties: - subscriptionId: - $ref: "#/components/schemas/SubscriptionId" - - SubscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - Device: - description: | - End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. - The developer can choose to provide the below specified device identifiers: - * `ipv4Address` - * `ipv6Address` - * `phoneNumber` - * `networkAccessIdentifier` - NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. - NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. - type: object - properties: - phoneNumber: - $ref: "#/components/schemas/PhoneNumber" - networkAccessIdentifier: - $ref: "#/components/schemas/NetworkAccessIdentifier" - ipv4Address: - $ref: "#/components/schemas/DeviceIpv4Addr" - ipv6Address: - $ref: "#/components/schemas/DeviceIpv6Address" - minProperties: 1 - - NetworkAccessIdentifier: - description: | - A public identifier addressing a subscription in a mobile network. In - 3GPP terminology, it corresponds to the GPSI formatted with the - External Identifier ({Local Identifier}@{Domain Identifier}). Unlike - the telephone number, the network access identifier is not subjected - to portability ruling in force, and is individually managed by each - operator. - type: string - example: "123456789@domain.com" - - PhoneNumber: - description: | - A public identifier addressing a telephone subscription. In mobile - networks it corresponds to the MSISDN (Mobile Station International - Subscriber Directory Number). In order to be globally unique it has to - be formatted in international format, according to E.164 standard, - prefixed with '+'. - type: string - pattern: '^\+[1-9][0-9]{4,14}$' - example: "+123456789" - - DeviceIpv4Addr: - type: object - description: | - The device should be identified by either the public (observed) IP - address and port as seen by the application server, or the private - (local) and any public (observed) IP addresses in use by the device - (this information can be obtained by various means, for example from - some DNS servers). - - If the allocated and observed IP addresses are the same (i.e. NAT is - not in use) then the same address should be specified for both - publicAddress and privateAddress. - - If NAT64 is in use, the device should be identified by its - publicAddress and publicPort, or separately by its allocated IPv6 - address (field ipv6Address of the Device object) - - In all cases, publicAddress must be specified, along with at least one - of either privateAddress or publicPort, dependent upon which is known. - In general, mobile devices cannot be identified by their public IPv4 - address alone. - properties: - publicAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - privateAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - publicPort: - $ref: "#/components/schemas/Port" - anyOf: - - required: [publicAddress, privateAddress] - - required: [publicAddress, publicPort] - example: {"publicAddress":"84.125.93.10", "publicPort":59765} - - SingleIpv4Addr: - description: A single IPv4 address with no subnet mask - type: string - format: ipv4 - example: "84.125.93.10" - - DeviceIpv6Address: - description: | - The device should be identified by the observed IPv6 address, or by any - single IPv6 address from within the subnet allocated to the device - (e.g. adding ::0 to the /64 prefix). - - The session shall apply to all IP flows between the device subnet and - the specified application server, unless further restricted by the - optional parameters devicePorts or applicationServerPorts. - type: string - format: ipv6 - example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 - - Port: - description: TCP or UDP port number - type: integer - minimum: 0 - maximum: 65535 - Protocol: - type: string - enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] - description: | - Identifier of a delivery protocol. Only HTTP is allowed for now - example: "HTTP" - Config: - description: | - Implementation-specific configuration parameters needed by the - subscription manager for acquiring events. - In CAMARA we have predefined attributes like `subscriptionExpireTime`. - Specific event type attributes must be defined in `subscriptionDetail` - Note: if a request is performed for several event type, all subscribed - event will use same `config` parameters. - type: object - required: - - subscriptionDetail - properties: - subscriptionDetail: - $ref: "#/components/schemas/CreateSubscriptionDetail" - subscriptionExpireTime: - type: string - format: date-time - description: | - The subscription expiration time (in date-time format) requested by - the API consumer. Up to API project decision to keep it. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - SinkCredential: - type: object - description: | - A sink credential provides authentication or authorization information - properties: - credentialType: - type: string - enum: - - PLAIN - - ACCESSTOKEN - - REFRESHTOKEN - description: | - The type of the credential. - Note: Type of the credential - MUST be set to ACCESSTOKEN for now - discriminator: - propertyName: credentialType - mapping: - PLAIN: "#/components/schemas/PlainCredential" - ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" - REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" - required: - - credentialType - - CreateSubscriptionDetail: - description: The detail of the requested event subscription - type: object - properties: - device: - description: | - This API need to carry the subscriber's GPSI/MSISDN. - $ref: "#/components/schemas/Device" - applicationId: - description: | - Indicates the Application Identifier. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. - $ref: "#/components/schemas/ApplicationId" - appcationType: - description: | - Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. - $ref: "#/components/schemas/AppcationType" - required: - - device - - SubscriptionRequest: - description: The request for creating a event-type event subscription - type: object - required: - - sink - - protocol - - config - - types - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - sinkCredential: - $ref: "#/components/schemas/SinkCredential" - config: - $ref: "#/components/schemas/Config" - BitRate: - type: string - description: | - String representing a bit rate that shall be formatted as follows: - pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" - Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". - TrafficVolume: - type: string - description: | - String representing a traffic volume measured in bytes that shall be formatted as follows: - Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' - Examples:"125 MB", "0.125 GB", "125000 kB" - Dnn: - type: string - description: | - String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; - it shall contain either a DNN Network Identifier, or a full DNN with both the Network - Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. - It shall be coded as string in which the labels are separated by dots - (e.g. "Label1.Label2.Label3"). - QciOr5qi: - type: integer - description: | - It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). - NetType: - type: string - description: Indicates the type of network accessed. SA/EPC - AppSignalingData: - type: object - description: | - Basic . - properties: - dnn: - $ref: '#/components/schemas/Dnn' - qciOr5qi: - $ref: "#/components/schemas/QciOr5qi" - netType: - $ref: '#/components/schemas/NetType' - VolumeMeasurement: - type: object - description: | - Application-level traffic statistics. - properties: - totalVolume: - description: total running traffic statistics. - $ref: "#/components/schemas/TrafficVolume" - ulVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. - $ref: "#/components/schemas/TrafficVolume" - dlVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. - $ref: "#/components/schemas/TrafficVolume" - ApplicationIndicatorStatistics: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - subAppStartTime: - $ref: "#/components/schemas/DateTime" - subAppEffDur: - type: integer - description: | - Unsigned integer identifying a period of time in units of seconds - avgBwUl: - description: Average uplink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - avgBwDl: - description: Average downlink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - maxBwUl: - description: Maximum uplink bandwidth of the application - $ref: "#/components/schemas/BitRate" - maxBwDl: - description: Maximum downlink bandwidth of the application - $ref: "#/components/schemas/BitRate" - subAppVol: - $ref: "#/components/schemas/VolumeMeasurement" - maxDelayAn: - type: integer - description: | - Maximum wireless-side latency of an application. - maxDelayDn: - type: integer - description: | - Maximum wired-side latency of an application. - ApplicationExperienceAnalysis: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - avgQoe: - type: integer - description: | - Average score of experience analysis.Value range: 1 to 100 points. - maxResolution: - type: string - description: | - Maximum resolution in the experience analysis period. - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - mostResolution: - type: string - description: | - The resolution with the highest duration ratio within the experience analysis perio - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - maxBitRateUl: - description: Maximum uplink bit rate (kbit/s). - $ref: "#/components/schemas/BitRate" - avgBitRateUl: - description: Average uplink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - maxBitRateDl: - description: Maximum downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - avgBitRateDl: - description: Average downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - stallSec: - type: integer - description: Frame freezing duration, in seconds. - stallNum: - type: integer - description: Number of frame freezing times. The detection period is 5 seconds. - serviceDelay: - type: integer - description: Service latency, in seconds. - initialDur: - type: integer - description: | - Initial service buffering duration, in seconds. The options are as follows: - AreaData: - type: object - description: | - Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. - properties: - city: - type: string - description: user's city of residence. - district: - type: string - description: areas or streets within a city. - AppSignalingAndStatisticsAnalysisRecord: - type: object - description: | - the network's confidence level at being able to meet the network - demands of a given application for a given terminal device. - properties: - starttime: - $ref: "#/components/schemas/DateTime" - endtime: - $ref: "#/components/schemas/DateTime" - appcationType: - $ref: "#/components/schemas/AppcationType" - applicationId: - $ref: "#/components/schemas/ApplicationId" - areaData: - $ref: "#/components/schemas/AreaData" - appSignalingData: - $ref: "#/components/schemas/AppSignalingData" - applicationIndicatorStatistics: - $ref: "#/components/schemas/ApplicationIndicatorStatistics" - applicationExperienceAnalysis: - $ref: "#/components/schemas/ApplicationExperienceAnalysis" - UserExperienceInsightsRecords: - type: object - description: | - Application Network Collection and Recording - properties: - appSignalingAndStatisticsAnalysisRecords: - type: array - items: - $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' - minItems: 1 - ApplicationId: - description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - format: uuid - AppcationType: - description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - example: video/game/Live Video - Source: - type: string - format: uri-reference - minLength: 1 - description: | - Identifies the context in which an event happened, as a non-empty - `URI-reference` like: - - URI with a DNS authority: - * https://github.com/cloudevents - * mailto:cncf-wg-serverless@lists.cncf.io - - Universally-unique URN with a UUID: - * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 - - Application-specific identifier: - * /cloudevents/spec/pull/123 - * 1-555-123-4567 - example: "https://notificationSendServer12.supertelco.com" - TerminationReason: - type: string - description: | - - NETWORK_TERMINATED - API server stopped sending notification - - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by - the requester) has been reached - - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the - requester) has been reached - - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by - the requester) expiration time has been reached - - SUBSCRIPTION_DELETED - Subscription was deleted by the requester - enum: - - MAX_EVENTS_REACHED - - NETWORK_TERMINATED - - SUBSCRIPTION_EXPIRED - - ACCESS_TOKEN_EXPIRED - - SUBSCRIPTION_DELETED - - DateTime: - type: string - format: date-time - description: | - Timestamp of when the occurrence happened. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - - EventTypeNotification: - type: string - description: | - event-type - Event triggered when an event-type event occurred - subscription-ended: Event triggered when the subscription ends - enum: - - org.camaraproject.user-experience-insights.v0.network-quality - - org.camaraproject.user-experience-insights.v0.subscription-ended - ErrorInfo: - type: object - description: Error information - required: - - status - - code - - message - properties: - status: - type: integer - description: HTTP response status code - code: - type: string - description: A human-readable code to describe the error - message: - type: string - description: A human-readable description of what the event represents - UserExperienceInsightsResponse: - type: object - description: user experience insights result - required: - - UserExperienceInsightsRecords - properties: - device: - $ref: '#/components/schemas/Device' - UserExperienceInsightsRecords: - type: array - items: - $ref: "#/components/schemas/UserExperienceInsightsRecords" - minItems: 1 - responses: - CreateSubscriptionBadRequest400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - - OUT_OF_RANGE - - INVALID_PROTOCOL - - INVALID_CREDENTIAL - - INVALID_TOKEN - - INVALID_SINK - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_OUT_OF_RANGE: - description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested - value: - status: 400 - code: OUT_OF_RANGE - message: Client specified an invalid range. - GENERIC_400_INVALID_PROTOCOL: - description: Invalid protocol for events subscription management - value: - status: 400 - code: INVALID_PROTOCOL - message: Only HTTP is supported - GENERIC_400_INVALID_CREDENTIAL: - description: Invalid sink credential type - value: - status: 400 - code: INVALID_CREDENTIAL - message: Only Access token is supported - GENERIC_400_INVALID_TOKEN: - description: Invalid token type for sink credential of type ACCESSTOKEN - value: - status: 400 - code: INVALID_TOKEN - message: Only bearer token is supported - GENERIC_400_INVALID_SINK: - description: Invalid sink value - value: - status: 400 - code: INVALID_SINK - message: sink not valid for the specified protocol - Generic400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - SubscriptionIdRequired400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_SUBSCRIPTION_ID_REQUIRED: - description: subscription id is required - value: - status: 400 - code: INVALID_ARGUMENT - message: "Expected property is missing: subscriptionId" - Generic401: - description: Authentication problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 401 - code: - enum: - - UNAUTHENTICATED - - examples: - GENERIC_401_UNAUTHENTICATED: - description: Request cannot be authenticated and a new authentication is required - value: - status: 401 - code: UNAUTHENTICATED - message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. - - Generic403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - SubscriptionPermissionDenied403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - - SUBSCRIPTION_MISMATCH - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - GENERIC_403_SUBSCRIPTION_MISMATCH: - description: Inconsistent access token for requested subscription - value: - status: 403 - code: "SUBSCRIPTION_MISMATCH" - message: "Inconsistent access token for requested events subscription" - Generic404: - description: Resource Not Found - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 404 - code: - enum: - - NOT_FOUND - examples: - GENERIC_404_NOT_FOUND: - description: Resource is not found - value: - status: 404 - code: NOT_FOUND - message: The specified resource is not found. - Generic410: - description: Gone - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 410 - code: - enum: - - GONE - examples: - GENERIC_410_GONE: - description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available - value: - status: 410 - code: GONE - message: Access to the target resource is no longer available. - CreateSubscriptionUnprocessableEntity422: - description: Unprocessable Entity - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 422 - code: - enum: - - SERVICE_NOT_APPLICABLE - - MISSING_IDENTIFIER - - UNNECESSARY_IDENTIFIER - examples: - GENERIC_422_SERVICE_NOT_APPLICABLE: - description: Service not applicable for the provided identifier - value: - status: 422 - code: SERVICE_NOT_APPLICABLE - message: The service is not available for the provided identifier. - GENERIC_422_MISSING_IDENTIFIER: - description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token - value: - status: 422 - code: MISSING_IDENTIFIER - message: The device cannot be identified. - GENERIC_422_UNNECESSARY_IDENTIFIER: - description: An explicit identifier is provided when a device or phone number has already been identified from the access token - value: - status: 422 - code: UNNECESSARY_IDENTIFIER - message: The device is already identified by the access token. - Generic429: - description: Too Many Requests - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 429 - code: - enum: - - QUOTA_EXCEEDED - - TOO_MANY_REQUESTS - examples: - GENERIC_429_QUOTA_EXCEEDED: - description: Request is rejected due to exceeding a business quota limit - value: - status: 429 - code: QUOTA_EXCEEDED - message: Out of resource quota. - GENERIC_429_TOO_MANY_REQUESTS: - description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached - value: - status: 429 - code: TOO_MANY_REQUESTS - message: Rate limit reached. \ No newline at end of file diff --git a/documentation/API-proposal-user experience insights.md b/documentation/API-proposal-user experience insights.md deleted file mode 100644 index 6c6a724..0000000 --- a/documentation/API-proposal-user experience insights.md +++ /dev/null @@ -1,48 +0,0 @@ -# API Proposal Template -This template captures all the information that a partner should fill out when proposing a new API (or API family) to CAMARA. - - -### API family name -User Experience Insights (UEI) - -### API family owner -China Mobile Hong Kong, Huawei - -### API summary -This API allows Application Functions (AF) to subscribe to real-time network experience notifications for specific users. The API leverages the analytics capabilities of the NWDAF (Network Data Analytics Function) and exposes them through the NEF (Network Exposure Function). When a user's network experience (e.g., throughput, latency, or reliability) falls below a predefined threshold or changes significantly, the network proactively notifies the AF. - -In-scope business cases: - -VIP Customer Care & Proactive Intervention: Operator customer service systems can monitor high-value users' real-time experience. If a degradation is detected, the system can trigger automated "care" actions (e.g., issuing temporary vouchers or prioritizing technical support) before the user even files a complaint. - -Adaptive Application Logic: Streaming or gaming applications can use this API to receive proactive alerts about user experience trends, allowing them to adjust application-level parameters (like bitrates or buffering strategies) ahead of time. - -SLA Monitoring for Enterprise Services: Enterprises can subscribe to experience insights for their workforce to ensure critical remote-working applications meet the required performance standards. - -### Technical viability -This API is technically viable based on 3GPP 5G core network standards: - -3GPP TS 23.288 (NWDAF): Utilizes the "User Data Congestion" and "Service Experience" analytics ID. - -3GPP TS 23.502 / TS 29.522 (NEF): Requires NEF to support the exposure of analytics via Nnef_EventExposure or Nnef_AnalyticsExposure services. - -Maturity: These features are part of 3GPP Release 16/17, which are currently being deployed in commercial 5G SA networks. - -### Commercial viability -The underlying network capabilities (NEF and NWDAF) are now widely available as industrialized solutions. Many Tier-1 operators have already deployed NWDAF for internal network optimization and are moving towards external exposure of these insights to enhance ecosystem value. - -### YAML code available? -YES. - -### Validated in lab/productive environments? -YES. Validated in a lab environment simulating 5G SA core network signaling with actual NWDAF analytics triggers. - -### Validated with real customers? -No. - -### Validated with operators? -No. - -### Supporters in API Backlog Working Group -List of supporters. -*NOTE: That shall be added by the Working Group. Supporting an API proposal means that the supporting company must provide at least 1 (one) Maintainer at the time of the Sub Project creation.* diff --git a/documentation/SupportingDocuments/API-proposal-user experience insights.md b/documentation/SupportingDocuments/API-proposal-user experience insights.md deleted file mode 100644 index 6c6a724..0000000 --- a/documentation/SupportingDocuments/API-proposal-user experience insights.md +++ /dev/null @@ -1,48 +0,0 @@ -# API Proposal Template -This template captures all the information that a partner should fill out when proposing a new API (or API family) to CAMARA. - - -### API family name -User Experience Insights (UEI) - -### API family owner -China Mobile Hong Kong, Huawei - -### API summary -This API allows Application Functions (AF) to subscribe to real-time network experience notifications for specific users. The API leverages the analytics capabilities of the NWDAF (Network Data Analytics Function) and exposes them through the NEF (Network Exposure Function). When a user's network experience (e.g., throughput, latency, or reliability) falls below a predefined threshold or changes significantly, the network proactively notifies the AF. - -In-scope business cases: - -VIP Customer Care & Proactive Intervention: Operator customer service systems can monitor high-value users' real-time experience. If a degradation is detected, the system can trigger automated "care" actions (e.g., issuing temporary vouchers or prioritizing technical support) before the user even files a complaint. - -Adaptive Application Logic: Streaming or gaming applications can use this API to receive proactive alerts about user experience trends, allowing them to adjust application-level parameters (like bitrates or buffering strategies) ahead of time. - -SLA Monitoring for Enterprise Services: Enterprises can subscribe to experience insights for their workforce to ensure critical remote-working applications meet the required performance standards. - -### Technical viability -This API is technically viable based on 3GPP 5G core network standards: - -3GPP TS 23.288 (NWDAF): Utilizes the "User Data Congestion" and "Service Experience" analytics ID. - -3GPP TS 23.502 / TS 29.522 (NEF): Requires NEF to support the exposure of analytics via Nnef_EventExposure or Nnef_AnalyticsExposure services. - -Maturity: These features are part of 3GPP Release 16/17, which are currently being deployed in commercial 5G SA networks. - -### Commercial viability -The underlying network capabilities (NEF and NWDAF) are now widely available as industrialized solutions. Many Tier-1 operators have already deployed NWDAF for internal network optimization and are moving towards external exposure of these insights to enhance ecosystem value. - -### YAML code available? -YES. - -### Validated in lab/productive environments? -YES. Validated in a lab environment simulating 5G SA core network signaling with actual NWDAF analytics triggers. - -### Validated with real customers? -No. - -### Validated with operators? -No. - -### Supporters in API Backlog Working Group -List of supporters. -*NOTE: That shall be added by the Working Group. Supporting an API proposal means that the supporting company must provide at least 1 (one) Maintainer at the time of the Sub Project creation.* diff --git a/documentation/user-experience-insights-subscriptions.yaml b/documentation/user-experience-insights-subscriptions.yaml deleted file mode 100644 index 8722279..0000000 --- a/documentation/user-experience-insights-subscriptions.yaml +++ /dev/null @@ -1,1217 +0,0 @@ -openapi: 3.0.3 -info: - title: User Experience Insights - version: wip - x-camara-commonalities: 0.6 - description: | - With CAMARA User Experience Insights subscription service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. - - # Introduction - - The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. - - This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. - - This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. - - This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. - - for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. - # Relevant terms and definitions - - * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. - - # API functionality - The API provides the datatype parameter to report network quality at different granularities. Poor-QoE events are reported in real time when the network detects poor-QoE events. - - This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). - - This API provides the function of reporting poor-QoE data in real time or periodically reporting no poor-QoE data based on the datatype parameter. - POOR_QOE_REPORT Detects poor network experience and reports the collected statistical data. - PERIODIC_REPORT Periodically collecting and reporting data. - ALL Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. - - - ### Notification callback - - This endpoint describes the event notification received on subscription listener side when the event occurred. - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -externalDocs: - description: Product documentation at CAMARA. - url: https://github.com/camaraproject/UserExperienceInsights - -servers: - - url: "{apiRoot}/user-experience-insights" - variables: - apiRoot: - default: http://localhost:9091 - description: | - API root, defined by service provider, e.g. - `api.example.com` or `api.example.com/somepath` - -tags: - - name: User Experience Insights - description: | - Create and manage a subscription to receive periodic connectivity - insights - -paths: - /subscriptions: - post: - tags: - - User Experience Insights - description: "Create a User Experience Insights Subscription for a device" - summary: "Create a User Experience Insights Subscription for a device" - operationId: createSubscription - parameters: - - $ref: "#/components/parameters/x-correlator" - security: - - openId: - - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:create - - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionRequest" - required: true - callbacks: - notifications: - "{$request.body#/sink}": - post: - summary: "Subscription notification callback" - description: | - Important: this endpoint is to be implemented by the API - consumer.The User Experience Insights server will call this - endpoint whenever a connectivity event occurs that changes - the network's ability to meet the application's demands for - a given device. - operationId: postNotification - parameters: - - $ref: "#/components/parameters/x-correlator" - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/CloudEvent" - required: true - responses: - "201": - description: Successful notification - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - "400": - $ref: "#/components/responses/Generic400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/Generic403" - "410": - $ref: "#/components/responses/Generic410" - "429": - $ref: "#/components/responses/Generic429" - security: - - {} - - notificationsBearerAuth: [] - responses: - "201": - description: Created - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionAsync" - "400": - $ref: "#/components/responses/CreateSubscriptionBadRequest400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/SubscriptionPermissionDenied403" - "409": - $ref: "#/components/responses/Generic409" - "422": - $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" - "429": - $ref: "#/components/responses/Generic429" - /subscriptions/{subscriptionId}: - get: - tags: - - User Experience Insights - summary: "Operation to retrieve a subscription based on the provided ID" - operationId: getSubscription - description: Retrieve a given subscription by ID - security: - - openId: - - connectivity-insights-subscriptions:read - parameters: - - $ref: "#/components/parameters/SubscriptionId" - - $ref: "#/components/parameters/x-correlator" - responses: - "200": - description: OK - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/Subscription" - "400": - $ref: "#/components/responses/SubscriptionIdRequired400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/Generic403" - "404": - $ref: "#/components/responses/Generic404" - delete: - tags: - - User Experience Insights - summary: "Operation to delete a subscription" - operationId: deleteSubscription - description: Delete a given subscription by ID - security: - - openId: - - user-experience-insights:delete - parameters: - - $ref: "#/components/parameters/SubscriptionId" - - $ref: "#/components/parameters/x-correlator" - responses: - "204": - description: apiName subscription deleted - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - "202": - description: | - Request accepted to be processed. It applies for async deletion - process. - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionAsync" - "400": - $ref: "#/components/responses/SubscriptionIdRequired400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/Generic403" - "404": - $ref: "#/components/responses/Generic404" - -components: - securitySchemes: - openId: - type: openIdConnect - description: Common security scheme for all CAMARA APIs - openIdConnectUrl: https://example.com/.well-known/openid-configuration - notificationsBearerAuth: - description: Bearer authorization for notifications - type: http - scheme: bearer - bearerFormat: "{$request.body#/sinkCredential.credentialType}" - parameters: - SubscriptionId: - name: subscriptionId - in: path - description: | - Subscription identifier that was obtained from the create event - subscription operation - required: true - schema: - $ref: "#/components/schemas/SubscriptionId" - x-correlator: - name: x-correlator - in: header - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - headers: - x-correlator: - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - schemas: - XCorrelator: - type: string - pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ - example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" - Subscription: - description: Represents a event-type subscription. - type: object - required: - - sink - - protocol - - config - - types - - id - - startsAt - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - pattern: ^https:\/\/.+$ - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - config: - $ref: "#/components/schemas/Config" - subscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - startsAt: - type: string - format: date-time - description: Date when the event subscription will begin/began - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - expiresAt: - type: string - format: date-time - description: | - Date when the event subscription will expire. Only provided when - `subscriptionExpireTime` is indicated by API client or Telco - Operator has specific policy about that. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - status: - type: string - description: |- - Current status of the subscription - Management of Subscription - State engine is not mandatory for now. Note not all statuses may - be considered to be implemented. Details: - - `ACTIVATION_REQUESTED`: Subscription creation (POST) is - triggered but subscription creation process is not finished - yet. - - `ACTIVE`: Subscription creation process is completed. - Subscription is fully operative. - - `DEACTIVE`: Subscription is temporarily inactive, but its - workflow logic is not deleted. - - `EXPIRED`: Subscription is ended (no longer active). - This status applies when subscription is ended due to - `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. - - `DELETED`: Subscription is ended as deleted (no longer - active). This status applies when subscription information is - kept (i.e. subscription workflow is no longer active but its - metainformation is kept). - enum: - - ACTIVATION_REQUESTED - - ACTIVE - - EXPIRED - - DEACTIVE - - DELETED - discriminator: - propertyName: protocol - mapping: - HTTP: "#/components/schemas/HTTPSubscriptionResponse" - MQTT3: "#/components/schemas/MQTTSubscriptionResponse" - MQTT5: "#/components/schemas/MQTTSubscriptionResponse" - AMQP: "#/components/schemas/AMQPSubscriptionResponse" - NATS: "#/components/schemas/NATSSubscriptionResponse" - KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" - - SubscriptionAsync: - description: | - Response for a event-type subscription request managed asynchronously - (Creation or Deletion) - type: object - properties: - subscriptionId: - $ref: "#/components/schemas/SubscriptionId" - - SubscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - Device: - description: | - End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. - The developer can choose to provide the below specified device identifiers: - * `ipv4Address` - * `ipv6Address` - * `phoneNumber` - * `networkAccessIdentifier` - NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. - NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. - type: object - properties: - phoneNumber: - $ref: "#/components/schemas/PhoneNumber" - networkAccessIdentifier: - $ref: "#/components/schemas/NetworkAccessIdentifier" - ipv4Address: - $ref: "#/components/schemas/DeviceIpv4Addr" - ipv6Address: - $ref: "#/components/schemas/DeviceIpv6Address" - minProperties: 1 - - NetworkAccessIdentifier: - description: | - A public identifier addressing a subscription in a mobile network. In - 3GPP terminology, it corresponds to the GPSI formatted with the - External Identifier ({Local Identifier}@{Domain Identifier}). Unlike - the telephone number, the network access identifier is not subjected - to portability ruling in force, and is individually managed by each - operator. - type: string - example: "123456789@domain.com" - - PhoneNumber: - description: | - A public identifier addressing a telephone subscription. In mobile - networks it corresponds to the MSISDN (Mobile Station International - Subscriber Directory Number). In order to be globally unique it has to - be formatted in international format, according to E.164 standard, - prefixed with '+'. - type: string - pattern: '^\+[1-9][0-9]{4,14}$' - example: "+123456789" - - DeviceIpv4Addr: - type: object - description: | - The device should be identified by either the public (observed) IP - address and port as seen by the application server, or the private - (local) and any public (observed) IP addresses in use by the device - (this information can be obtained by various means, for example from - some DNS servers). - - If the allocated and observed IP addresses are the same (i.e. NAT is - not in use) then the same address should be specified for both - publicAddress and privateAddress. - - If NAT64 is in use, the device should be identified by its - publicAddress and publicPort, or separately by its allocated IPv6 - address (field ipv6Address of the Device object) - - In all cases, publicAddress must be specified, along with at least one - of either privateAddress or publicPort, dependent upon which is known. - In general, mobile devices cannot be identified by their public IPv4 - address alone. - properties: - publicAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - privateAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - publicPort: - $ref: "#/components/schemas/Port" - anyOf: - - required: [publicAddress, privateAddress] - - required: [publicAddress, publicPort] - example: {"publicAddress":"84.125.93.10", "publicPort":59765} - - SingleIpv4Addr: - description: A single IPv4 address with no subnet mask - type: string - format: ipv4 - example: "84.125.93.10" - - DeviceIpv6Address: - description: | - The device should be identified by the observed IPv6 address, or by any - single IPv6 address from within the subnet allocated to the device - (e.g. adding ::0 to the /64 prefix). - - The session shall apply to all IP flows between the device subnet and - the specified application server, unless further restricted by the - optional parameters devicePorts or applicationServerPorts. - type: string - format: ipv6 - example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 - - Port: - description: TCP or UDP port number - type: integer - minimum: 0 - maximum: 65535 - Protocol: - type: string - enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] - description: | - Identifier of a delivery protocol. Only HTTP is allowed for now - example: "HTTP" - Config: - description: | - Implementation-specific configuration parameters needed by the - subscription manager for acquiring events. - In CAMARA we have predefined attributes like `subscriptionExpireTime`. - Specific event type attributes must be defined in `subscriptionDetail` - Note: if a request is performed for several event type, all subscribed - event will use same `config` parameters. - type: object - required: - - subscriptionDetail - properties: - subscriptionDetail: - $ref: "#/components/schemas/CreateSubscriptionDetail" - subscriptionExpireTime: - type: string - format: date-time - description: | - The subscription expiration time (in date-time format) requested by - the API consumer. Up to API project decision to keep it. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - datatype: - type: string - description: | - POOR_QOE_REPORT: Detects poor network experience and reports the collected statistical data. - PERIODIC_REPORT: Periodically collecting and reporting data. - ALL: Detects data collected and reported by the poor network experience reporting function. If no poor quality is detected, the data is reported periodically. - enum: - - POOR_QOE_REPORT - - PERIODIC_REPORT - - ALL - SinkCredential: - type: object - description: | - A sink credential provides authentication or authorization information - properties: - credentialType: - type: string - enum: - - PLAIN - - ACCESSTOKEN - - REFRESHTOKEN - description: | - The type of the credential. - Note: Type of the credential - MUST be set to ACCESSTOKEN for now - discriminator: - propertyName: credentialType - mapping: - PLAIN: "#/components/schemas/PlainCredential" - ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" - REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" - required: - - credentialType - - CreateSubscriptionDetail: - description: The detail of the requested event subscription - type: object - properties: - device: - description: | - This API need to carry the subscriber's GPSI/MSISDN. - $ref: "#/components/schemas/Device" - appcationType: - description: | - Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. - $ref: "#/components/schemas/AppcationType" - required: - - device - - SubscriptionRequest: - description: The request for creating a event-type event subscription - type: object - required: - - sink - - protocol - - config - - types - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - sinkCredential: - $ref: "#/components/schemas/SinkCredential" - config: - $ref: "#/components/schemas/Config" - BitRate: - type: string - description: | - String representing a bit rate that shall be formatted as follows: - pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" - Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". - TrafficVolume: - type: string - description: | - String representing a traffic volume measured in bytes that shall be formatted as follows: - Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' - Examples:"125 MB", "0.125 GB", "125000 kB" - Dnn: - type: string - description: | - String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; - it shall contain either a DNN Network Identifier, or a full DNN with both the Network - Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. - It shall be coded as string in which the labels are separated by dots - (e.g. "Label1.Label2.Label3"). - QciOr5qi: - type: integer - description: | - It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). - NetType: - type: string - description: Indicates the type of network accessed. SA/EPC - AppSignalingData: - type: object - description: | - Basic . - properties: - dnn: - $ref: '#/components/schemas/Dnn' - qciOr5qi: - $ref: "#/components/schemas/QciOr5qi" - netType: - $ref: '#/components/schemas/NetType' - VolumeMeasurement: - type: object - description: | - Application-level traffic statistics. - properties: - totalVolume: - description: total running traffic statistics. - $ref: "#/components/schemas/TrafficVolume" - ulVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. - $ref: "#/components/schemas/TrafficVolume" - dlVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. - $ref: "#/components/schemas/TrafficVolume" - ApplicationIndicatorStatistics: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - subAppStartTime: - $ref: "#/components/schemas/DateTime" - subAppEffDur: - type: integer - description: | - Unsigned integer identifying a period of time in units of seconds - avgBwUl: - description: Average uplink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - avgBwDl: - description: Average downlink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - maxBwUl: - description: Maximum uplink bandwidth of the application - $ref: "#/components/schemas/BitRate" - maxBwDl: - description: Maximum downlink bandwidth of the application - $ref: "#/components/schemas/BitRate" - subAppVol: - $ref: "#/components/schemas/VolumeMeasurement" - maxDelayAn: - type: integer - description: | - Maximum wireless-side latency of an application. - maxDelayDn: - type: integer - description: | - Maximum wired-side latency of an application. - ApplicationExperienceAnalysis: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - avgQoe: - type: integer - description: | - Average score of experience analysis.Value range: 1 to 100 points. - maxResolution: - type: string - description: | - Maximum resolution in the experience analysis period. - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - mostResolution: - type: string - description: | - The resolution with the highest duration ratio within the experience analysis perio - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - maxBitRateUl: - description: Maximum uplink bit rate (kbit/s). - $ref: "#/components/schemas/BitRate" - avgBitRateUl: - description: Average uplink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - maxBitRateDl: - description: Maximum downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - avgBitRateDl: - description: Average downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - stallSec: - type: integer - description: Frame freezing duration, in seconds. - stallNum: - type: integer - description: Number of frame freezing times. The detection period is 5 seconds. - serviceDelay: - type: integer - description: Service latency, in seconds. - initialDur: - type: integer - description: | - Initial service buffering duration, in seconds. The options are as follows: - AreaData: - type: object - description: | - Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. - properties: - city: - type: string - description: user's city of residence. - district: - type: string - description: areas or streets within a city. - AppSignalingAndStatisticsAnalysisRecord: - type: object - description: | - the network's confidence level at being able to meet the network - demands of a given application for a given terminal device. - properties: - starttime: - $ref: "#/components/schemas/DateTime" - endtime: - $ref: "#/components/schemas/DateTime" - appcationType: - $ref: "#/components/schemas/AppcationType" - applicationId: - $ref: "#/components/schemas/ApplicationId" - areaData: - $ref: "#/components/schemas/AreaData" - appSignalingData: - $ref: "#/components/schemas/AppSignalingData" - applicationIndicatorStatistics: - $ref: "#/components/schemas/ApplicationIndicatorStatistics" - applicationExperienceAnalysis: - $ref: "#/components/schemas/ApplicationExperienceAnalysis" - UserExperienceInsightsRecords: - type: object - description: | - Application Network Collection and Recording - properties: - appSignalingAndStatisticsAnalysisRecords: - type: array - items: - $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' - minItems: 1 - ApplicationId: - description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - format: uuid - AppcationType: - description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - example: video/game/Live Video - Source: - type: string - format: uri-reference - minLength: 1 - description: | - Identifies the context in which an event happened, as a non-empty - `URI-reference` like: - - URI with a DNS authority: - * https://github.com/cloudevents - * mailto:cncf-wg-serverless@lists.cncf.io - - Universally-unique URN with a UUID: - * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 - - Application-specific identifier: - * /cloudevents/spec/pull/123 - * 1-555-123-4567 - example: "https://notificationSendServer12.supertelco.com" - CloudEvent: - description: The Cloud-Event used for the callback. - required: - - id - - source - - specversion - - type - - time - properties: - id: - type: string - description: | - identifier of this event, that must be unique in the source context. - source: - $ref: "#/components/schemas/Source" - type: - $ref: "#/components/schemas/EventTypeNotification" - specversion: - type: string - description: | - Version of the specification to which this event conforms (must be - 1.0 if it conforms to cloudevents 1.0.2 version) - enum: - - "1.0" - datacontenttype: - type: string - description: | - 'media-type that describes the event payload encoding, - must be "application/json" for CAMARA APIs' - enum: - - application/json - data: - $ref: "#/components/schemas/UserExperienceInsightsRecords" - time: - $ref: "#/components/schemas/DateTime" - discriminator: - propertyName: "type" - mapping: - org.camaraproject.user-experience-insights.v0.network-quality: - "#/components/schemas/EventNetworkQuality" - org.camaraproject.connectivityinsights.v0.eventSubscriptionEnded: - "#/components/schemas/EventSubscriptionEnded" - - EventNetworkQuality: - description: event structure for Network Quality - allOf: - - $ref: "#/components/schemas/CloudEvent" - - type: object - properties: - data: - $ref: "#/components/schemas/UserExperienceInsightsRecords" - - EventSubscriptionEnded: - description: event structure for event subscription ended - allOf: - - $ref: "#/components/schemas/CloudEvent" - - type: object - properties: - data: - $ref: "#/components/schemas/SubscriptionEnded" - - SubscriptionEnded: - description: Event detail structure for subscription ended event - type: object - required: - - terminationReason - - subscriptionId - properties: - terminationReason: - $ref: "#/components/schemas/TerminationReason" - subscriptionId: - $ref: "#/components/schemas/SubscriptionId" - terminationDescription: - description: Explanation why a subscription ended or had to end. - type: string - - TerminationReason: - type: string - description: | - - NETWORK_TERMINATED - API server stopped sending notification - - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by - the requester) has been reached - - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the - requester) has been reached - - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by - the requester) expiration time has been reached - - SUBSCRIPTION_DELETED - Subscription was deleted by the requester - enum: - - MAX_EVENTS_REACHED - - NETWORK_TERMINATED - - SUBSCRIPTION_EXPIRED - - ACCESS_TOKEN_EXPIRED - - SUBSCRIPTION_DELETED - - DateTime: - type: string - format: date-time - description: | - Timestamp of when the occurrence happened. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - - EventTypeNotification: - type: string - description: | - event-type - Event triggered when an event-type event occurred - subscription-ended: Event triggered when the subscription ends - enum: - - org.camaraproject.user-experience-insights.v0.network-quality - - org.camaraproject.user-experience-insights.v0.subscription-ended - ErrorInfo: - type: object - description: Error information - required: - - status - - code - - message - properties: - status: - type: integer - description: HTTP response status code - code: - type: string - description: A human-readable code to describe the error - message: - type: string - description: A human-readable description of what the event represents - - responses: - CreateSubscriptionBadRequest400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - - OUT_OF_RANGE - - INVALID_PROTOCOL - - INVALID_CREDENTIAL - - INVALID_TOKEN - - INVALID_SINK - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_OUT_OF_RANGE: - description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested - value: - status: 400 - code: OUT_OF_RANGE - message: Client specified an invalid range. - GENERIC_400_INVALID_PROTOCOL: - description: Invalid protocol for events subscription management - value: - status: 400 - code: INVALID_PROTOCOL - message: Only HTTP is supported - GENERIC_400_INVALID_CREDENTIAL: - description: Invalid sink credential type - value: - status: 400 - code: INVALID_CREDENTIAL - message: Only Access token is supported - GENERIC_400_INVALID_TOKEN: - description: Invalid token type for sink credential of type ACCESSTOKEN - value: - status: 400 - code: INVALID_TOKEN - message: Only bearer token is supported - GENERIC_400_INVALID_SINK: - description: Invalid sink value - value: - status: 400 - code: INVALID_SINK - message: sink not valid for the specified protocol - Generic400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - SubscriptionIdRequired400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_SUBSCRIPTION_ID_REQUIRED: - description: subscription id is required - value: - status: 400 - code: INVALID_ARGUMENT - message: "Expected property is missing: subscriptionId" - Generic401: - description: Authentication problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 401 - code: - enum: - - UNAUTHENTICATED - - examples: - GENERIC_401_UNAUTHENTICATED: - description: Request cannot be authenticated and a new authentication is required - value: - status: 401 - code: UNAUTHENTICATED - message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. - - Generic403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - SubscriptionPermissionDenied403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - - SUBSCRIPTION_MISMATCH - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - GENERIC_403_SUBSCRIPTION_MISMATCH: - description: Inconsistent access token for requested subscription - value: - status: 403 - code: "SUBSCRIPTION_MISMATCH" - message: "Inconsistent access token for requested events subscription" - Generic404: - description: Resource Not Found - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 404 - code: - enum: - - NOT_FOUND - examples: - GENERIC_404_NOT_FOUND: - description: Resource is not found - value: - status: 404 - code: NOT_FOUND - message: The specified resource is not found. - Generic409: - description: Conflict - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 409 - code: - enum: - - ABORTED - - ALREADY_EXISTS - examples: - GENERIC_409_ABORTED: - description: Concurreny of processes of the same nature/scope - value: - status: 409 - code: ABORTED - message: Concurrency conflict. - GENERIC_409_ALREADY_EXISTS: - description: Trying to create an existing resource - value: - status: 409 - code: ALREADY_EXISTS - message: The resource that a client tried to create already exists. - Generic410: - description: Gone - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 410 - code: - enum: - - GONE - examples: - GENERIC_410_GONE: - description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available - value: - status: 410 - code: GONE - message: Access to the target resource is no longer available. - CreateSubscriptionUnprocessableEntity422: - description: Unprocessable Entity - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 422 - code: - enum: - - SERVICE_NOT_APPLICABLE - - MISSING_IDENTIFIER - - UNNECESSARY_IDENTIFIER - examples: - GENERIC_422_SERVICE_NOT_APPLICABLE: - description: Service not applicable for the provided identifier - value: - status: 422 - code: SERVICE_NOT_APPLICABLE - message: The service is not available for the provided identifier. - GENERIC_422_MISSING_IDENTIFIER: - description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token - value: - status: 422 - code: MISSING_IDENTIFIER - message: The device cannot be identified. - GENERIC_422_UNNECESSARY_IDENTIFIER: - description: An explicit identifier is provided when a device or phone number has already been identified from the access token - value: - status: 422 - code: UNNECESSARY_IDENTIFIER - message: The device is already identified by the access token. - Generic429: - description: Too Many Requests - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 429 - code: - enum: - - QUOTA_EXCEEDED - - TOO_MANY_REQUESTS - examples: - GENERIC_429_QUOTA_EXCEEDED: - description: Request is rejected due to exceeding a business quota limit - value: - status: 429 - code: QUOTA_EXCEEDED - message: Out of resource quota. - GENERIC_429_TOO_MANY_REQUESTS: - description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached - value: - status: 429 - code: TOO_MANY_REQUESTS - message: Rate limit reached. \ No newline at end of file diff --git a/documentation/user-experience-insights.yaml b/documentation/user-experience-insights.yaml deleted file mode 100644 index f8421f7..0000000 --- a/documentation/user-experience-insights.yaml +++ /dev/null @@ -1,995 +0,0 @@ -openapi: 3.0.3 -info: - title: User Experience Insights - version: wip - x-camara-commonalities: 0.6 - description: | - With CAMARA User Experience Insights service, application developers can obtain detailed usage statistics and network experience ratings for network quality. By tracking users' network status and the usage status of different applications in real time, it is possible to accurately identify users and application services with poor quality. This allows for recommending applications with better experiences or improving user experience through single-user assurance. - - # Introduction - - The User Experience Insights API allows application developers to subscribe to the network to achieve the following functions. - - This information helps application providers monitor the quality of service (QoS) of applications, identify areas with poor QoS, and deploy distributed network services accordingly. - - This information can be used to monitor the network quality on the paths of VIP users, detect quality problems in a timely manner, and take protective measures to prevent user complaints and improve user satisfaction. - - This information can be used to monitor the poor experience of similar applications in roaming areas and recommend the application with the optimal experience in different roaming areas. - - for Example, An application vendor wants to gain insights into and assess the network quality of its application in a specific region. The application service identifies a group of users who frequently use the application in that region and uses this API to monitor the application's performance. Through sample evaluation, if the network quality is found to be poor, the vendor can recommend deploying new devices or offering a premium package to improve network quality, thereby enhancing user retention. - # Relevant terms and definitions - - * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. - - # API functionality - - This API provides detailed data reporting, including basic application statistics (such as uplink statistics, downlink statistics, number of lost packets, valid uplink bandwidth, valid downlink bandwidth, average uplink bandwidth, and statistical summaries of periodic applications) and experience analysis data (such as application rating, maximum resolution, duration at maximum resolution, uplink bit rate, downlink bit rate, stalling duration, latency, and application creation latency). - - - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.html - -externalDocs: - description: Product documentation at CAMARA. - url: https://github.com/camaraproject/UserExperienceInsights - -servers: - - url: "{apiRoot}/user-experience-insights/" - variables: - apiRoot: - default: http://localhost:9091 - description: | - API root, defined by service provider, e.g. - `api.example.com` or `api.example.com/somepath` - -tags: - - name: User Experience Insights - description: | - read User Experience Insights - -paths: - /userexperienceinsights: - post: - tags: - - User Experience Insights - description: "read a User Experience Insights for a device" - summary: "read a User Experience Insights for a device" - operationId: readSubscription - parameters: - - $ref: "#/components/parameters/x-correlator" - security: - - openId: - - user-experience-insights:org.camaraproject.user-experience-insights.v0.network-quality:read - - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/SubscriptionRequest" - required: true - responses: - "200": - description: OK - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - $ref: "#/components/schemas/UserExperienceInsightsResponse" - "400": - $ref: "#/components/responses/CreateSubscriptionBadRequest400" - "401": - $ref: "#/components/responses/Generic401" - "403": - $ref: "#/components/responses/SubscriptionPermissionDenied403" - "422": - $ref: "#/components/responses/CreateSubscriptionUnprocessableEntity422" - "429": - $ref: "#/components/responses/Generic429" -components: - securitySchemes: - openId: - type: openIdConnect - description: Common security scheme for all CAMARA APIs - openIdConnectUrl: https://example.com/.well-known/openid-configuration - notificationsBearerAuth: - description: Bearer authorization for notifications - type: http - scheme: bearer - bearerFormat: "{$request.body#/sinkCredential.credentialType}" - parameters: - SubscriptionId: - name: subscriptionId - in: path - description: | - Subscription identifier that was obtained from the create event - subscription operation - required: true - schema: - $ref: "#/components/schemas/SubscriptionId" - x-correlator: - name: x-correlator - in: header - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - headers: - x-correlator: - description: Correlation id for the different services - schema: - $ref: "#/components/schemas/XCorrelator" - schemas: - XCorrelator: - type: string - pattern: ^[a-zA-Z0-9-_:;.\/<>{}]{0,256}$ - example: "b4333c46-49c0-4f62-80d7-f0ef930f1c46" - Subscription: - description: Represents a event-type subscription. - type: object - required: - - sink - - protocol - - config - - types - - id - - startsAt - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - pattern: ^https:\/\/.+$ - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - config: - $ref: "#/components/schemas/Config" - subscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - startsAt: - type: string - format: date-time - description: Date when the event subscription will begin/began - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - expiresAt: - type: string - format: date-time - description: | - Date when the event subscription will expire. Only provided when - `subscriptionExpireTime` is indicated by API client or Telco - Operator has specific policy about that. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - status: - type: string - description: |- - Current status of the subscription - Management of Subscription - State engine is not mandatory for now. Note not all statuses may - be considered to be implemented. Details: - - `ACTIVATION_REQUESTED`: Subscription creation (POST) is - triggered but subscription creation process is not finished - yet. - - `ACTIVE`: Subscription creation process is completed. - Subscription is fully operative. - - `DEACTIVE`: Subscription is temporarily inactive, but its - workflow logic is not deleted. - - `EXPIRED`: Subscription is ended (no longer active). - This status applies when subscription is ended due to - `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event. - - `DELETED`: Subscription is ended as deleted (no longer - active). This status applies when subscription information is - kept (i.e. subscription workflow is no longer active but its - metainformation is kept). - enum: - - ACTIVATION_REQUESTED - - ACTIVE - - EXPIRED - - DEACTIVE - - DELETED - discriminator: - propertyName: protocol - mapping: - HTTP: "#/components/schemas/HTTPSubscriptionResponse" - MQTT3: "#/components/schemas/MQTTSubscriptionResponse" - MQTT5: "#/components/schemas/MQTTSubscriptionResponse" - AMQP: "#/components/schemas/AMQPSubscriptionResponse" - NATS: "#/components/schemas/NATSSubscriptionResponse" - KAFKA: "#/components/schemas/ApacheKafkaSubscriptionResponse" - - SubscriptionAsync: - description: | - Response for a event-type subscription request managed asynchronously - (Creation or Deletion) - type: object - properties: - subscriptionId: - $ref: "#/components/schemas/SubscriptionId" - - SubscriptionId: - type: string - description: | - When this information is contained within an event notification, it SHALL be referred to as `subscriptionId` as per the Commonalities Event Notification Model. - example: qs15-h556-rt89-1298 - Device: - description: | - End-user equipment able to connect to a mobile network. Examples of devices include smartphones or IoT sensors/actuators. - The developer can choose to provide the below specified device identifiers: - * `ipv4Address` - * `ipv6Address` - * `phoneNumber` - * `networkAccessIdentifier` - NOTE1: the network operator might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different network operators. In this case the identifiers MUST belong to the same device. - NOTE2: as for this Commonalities release, we are enforcing that the networkAccessIdentifier is only part of the schema for future-proofing, and CAMARA does not currently allow its use. After the CAMARA meta-release work is concluded and the relevant issues are resolved, its use will need to be explicitly documented in the guidelines. - type: object - properties: - phoneNumber: - $ref: "#/components/schemas/PhoneNumber" - networkAccessIdentifier: - $ref: "#/components/schemas/NetworkAccessIdentifier" - ipv4Address: - $ref: "#/components/schemas/DeviceIpv4Addr" - ipv6Address: - $ref: "#/components/schemas/DeviceIpv6Address" - minProperties: 1 - - NetworkAccessIdentifier: - description: | - A public identifier addressing a subscription in a mobile network. In - 3GPP terminology, it corresponds to the GPSI formatted with the - External Identifier ({Local Identifier}@{Domain Identifier}). Unlike - the telephone number, the network access identifier is not subjected - to portability ruling in force, and is individually managed by each - operator. - type: string - example: "123456789@domain.com" - - PhoneNumber: - description: | - A public identifier addressing a telephone subscription. In mobile - networks it corresponds to the MSISDN (Mobile Station International - Subscriber Directory Number). In order to be globally unique it has to - be formatted in international format, according to E.164 standard, - prefixed with '+'. - type: string - pattern: '^\+[1-9][0-9]{4,14}$' - example: "+123456789" - - DeviceIpv4Addr: - type: object - description: | - The device should be identified by either the public (observed) IP - address and port as seen by the application server, or the private - (local) and any public (observed) IP addresses in use by the device - (this information can be obtained by various means, for example from - some DNS servers). - - If the allocated and observed IP addresses are the same (i.e. NAT is - not in use) then the same address should be specified for both - publicAddress and privateAddress. - - If NAT64 is in use, the device should be identified by its - publicAddress and publicPort, or separately by its allocated IPv6 - address (field ipv6Address of the Device object) - - In all cases, publicAddress must be specified, along with at least one - of either privateAddress or publicPort, dependent upon which is known. - In general, mobile devices cannot be identified by their public IPv4 - address alone. - properties: - publicAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - privateAddress: - $ref: "#/components/schemas/SingleIpv4Addr" - publicPort: - $ref: "#/components/schemas/Port" - anyOf: - - required: [publicAddress, privateAddress] - - required: [publicAddress, publicPort] - example: {"publicAddress":"84.125.93.10", "publicPort":59765} - - SingleIpv4Addr: - description: A single IPv4 address with no subnet mask - type: string - format: ipv4 - example: "84.125.93.10" - - DeviceIpv6Address: - description: | - The device should be identified by the observed IPv6 address, or by any - single IPv6 address from within the subnet allocated to the device - (e.g. adding ::0 to the /64 prefix). - - The session shall apply to all IP flows between the device subnet and - the specified application server, unless further restricted by the - optional parameters devicePorts or applicationServerPorts. - type: string - format: ipv6 - example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 - - Port: - description: TCP or UDP port number - type: integer - minimum: 0 - maximum: 65535 - Protocol: - type: string - enum: ["HTTP", "MQTT3", "MQTT5", "AMQP", "NATS", "KAFKA"] - description: | - Identifier of a delivery protocol. Only HTTP is allowed for now - example: "HTTP" - Config: - description: | - Implementation-specific configuration parameters needed by the - subscription manager for acquiring events. - In CAMARA we have predefined attributes like `subscriptionExpireTime`. - Specific event type attributes must be defined in `subscriptionDetail` - Note: if a request is performed for several event type, all subscribed - event will use same `config` parameters. - type: object - required: - - subscriptionDetail - properties: - subscriptionDetail: - $ref: "#/components/schemas/CreateSubscriptionDetail" - subscriptionExpireTime: - type: string - format: date-time - description: | - The subscription expiration time (in date-time format) requested by - the API consumer. Up to API project decision to keep it. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - SinkCredential: - type: object - description: | - A sink credential provides authentication or authorization information - properties: - credentialType: - type: string - enum: - - PLAIN - - ACCESSTOKEN - - REFRESHTOKEN - description: | - The type of the credential. - Note: Type of the credential - MUST be set to ACCESSTOKEN for now - discriminator: - propertyName: credentialType - mapping: - PLAIN: "#/components/schemas/PlainCredential" - ACCESSTOKEN: "#/components/schemas/AccessTokenCredential" - REFRESHTOKEN: "#/components/schemas/RefreshTokenCredential" - required: - - credentialType - - CreateSubscriptionDetail: - description: The detail of the requested event subscription - type: object - properties: - device: - description: | - This API need to carry the subscriber's GPSI/MSISDN. - $ref: "#/components/schemas/Device" - applicationId: - description: | - Indicates the Application Identifier. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. - $ref: "#/components/schemas/ApplicationId" - appcationType: - description: | - Indicates the Application type. If not carried, the carrier configures mainstream application types (video, games, live streaming) locally. - $ref: "#/components/schemas/AppcationType" - required: - - device - - SubscriptionRequest: - description: The request for creating a event-type event subscription - type: object - required: - - sink - - protocol - - config - - types - properties: - protocol: - $ref: "#/components/schemas/Protocol" - sink: - type: string - format: uri - description: | - The address to which events shall be delivered using the selected - protocol. - example: "https://endpoint.example.com/sink" - sinkCredential: - $ref: "#/components/schemas/SinkCredential" - config: - $ref: "#/components/schemas/Config" - BitRate: - type: string - description: | - String representing a bit rate that shall be formatted as follows: - pattern: "^\d+(\.\d+)? (bps|Kbps|Mbps|Gbps|Tbps)$" - Examples: "125 Mbps", "0.125 Gbps", "125000 Kbps". - TrafficVolume: - type: string - description: | - String representing a traffic volume measured in bytes that shall be formatted as follows: - Pattern: '^\d+(\.\d+)? (B|kB|MB|GB|TB)$' - Examples:"125 MB", "0.125 GB", "125000 kB" - Dnn: - type: string - description: | - String representing a Data Network as defined in clause 9A of 3GPP TS 23.003; - it shall contain either a DNN Network Identifier, or a full DNN with both the Network - Identifier and Operator Identifier, as specified in 3GPP TS 23.003 clause 9.1.1 and 9.1.2. - It shall be coded as string in which the labels are separated by dots - (e.g. "Label1.Label2.Label3"). - QciOr5qi: - type: integer - description: | - It is provided to service data flows as a reference level for specific packet forwarding behaviors (such as packet loss rate and delay). - NetType: - type: string - description: Indicates the type of network accessed. SA/EPC - AppSignalingData: - type: object - description: | - Basic . - properties: - dnn: - $ref: '#/components/schemas/Dnn' - qciOr5qi: - $ref: "#/components/schemas/QciOr5qi" - netType: - $ref: '#/components/schemas/NetType' - VolumeMeasurement: - type: object - description: | - Application-level traffic statistics. - properties: - totalVolume: - description: total running traffic statistics. - $ref: "#/components/schemas/TrafficVolume" - ulVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the uplink direction. - $ref: "#/components/schemas/TrafficVolume" - dlVolume: - description: this shall indicate the volume (bytes) of user plane traffic for the downlink direction. - $ref: "#/components/schemas/TrafficVolume" - ApplicationIndicatorStatistics: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - subAppStartTime: - $ref: "#/components/schemas/DateTime" - subAppEffDur: - type: integer - description: | - Unsigned integer identifying a period of time in units of seconds - avgBwUl: - description: Average uplink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - avgBwDl: - description: Average downlink bandwidth of an application. - $ref: "#/components/schemas/BitRate" - maxBwUl: - description: Maximum uplink bandwidth of the application - $ref: "#/components/schemas/BitRate" - maxBwDl: - description: Maximum downlink bandwidth of the application - $ref: "#/components/schemas/BitRate" - subAppVol: - $ref: "#/components/schemas/VolumeMeasurement" - maxDelayAn: - type: integer - description: | - Maximum wireless-side latency of an application. - maxDelayDn: - type: integer - description: | - Maximum wired-side latency of an application. - ApplicationExperienceAnalysis: - type: object - description: | - Basic statistics on the application during the application use period. - properties: - avgQoe: - type: integer - description: | - Average score of experience analysis.Value range: 1 to 100 points. - maxResolution: - type: string - description: | - Maximum resolution in the experience analysis period. - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - mostResolution: - type: string - description: | - The resolution with the highest duration ratio within the experience analysis perio - example: The value can be 2160, 1080, 720, or 480. 1080 indicates 1080p (1920 x 1080). - maxBitRateUl: - description: Maximum uplink bit rate (kbit/s). - $ref: "#/components/schemas/BitRate" - avgBitRateUl: - description: Average uplink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - maxBitRateDl: - description: Maximum downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - avgBitRateDl: - description: Average downlink bit rate (kbit/s) - $ref: "#/components/schemas/BitRate" - stallSec: - type: integer - description: Frame freezing duration, in seconds. - stallNum: - type: integer - description: Number of frame freezing times. The detection period is 5 seconds. - serviceDelay: - type: integer - description: Service latency, in seconds. - initialDur: - type: integer - description: | - Initial service buffering duration, in seconds. The options are as follows: - AreaData: - type: object - description: | - Information about the area where a user is located. The area information can be used to monitor the quality of the network in the area. - properties: - city: - type: string - description: user's city of residence. - district: - type: string - description: areas or streets within a city. - AppSignalingAndStatisticsAnalysisRecord: - type: object - description: | - the network's confidence level at being able to meet the network - demands of a given application for a given terminal device. - properties: - starttime: - $ref: "#/components/schemas/DateTime" - endtime: - $ref: "#/components/schemas/DateTime" - appcationType: - $ref: "#/components/schemas/AppcationType" - applicationId: - $ref: "#/components/schemas/ApplicationId" - areaData: - $ref: "#/components/schemas/AreaData" - appSignalingData: - $ref: "#/components/schemas/AppSignalingData" - applicationIndicatorStatistics: - $ref: "#/components/schemas/ApplicationIndicatorStatistics" - applicationExperienceAnalysis: - $ref: "#/components/schemas/ApplicationExperienceAnalysis" - UserExperienceInsightsRecords: - type: object - description: | - Application Network Collection and Recording - properties: - appSignalingAndStatisticsAnalysisRecords: - type: array - items: - $ref: '#/components/schemas/AppSignalingAndStatisticsAnalysisRecord' - minItems: 1 - ApplicationId: - description: Indicates the Application Identifier. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - format: uuid - AppcationType: - description: Indicates the Application type. Negotiated by the carrier and application vendor and configured on the carrier network. - type: string - example: video/game/Live Video - Source: - type: string - format: uri-reference - minLength: 1 - description: | - Identifies the context in which an event happened, as a non-empty - `URI-reference` like: - - URI with a DNS authority: - * https://github.com/cloudevents - * mailto:cncf-wg-serverless@lists.cncf.io - - Universally-unique URN with a UUID: - * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 - - Application-specific identifier: - * /cloudevents/spec/pull/123 - * 1-555-123-4567 - example: "https://notificationSendServer12.supertelco.com" - TerminationReason: - type: string - description: | - - NETWORK_TERMINATED - API server stopped sending notification - - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by - the requester) has been reached - - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the - requester) has been reached - - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by - the requester) expiration time has been reached - - SUBSCRIPTION_DELETED - Subscription was deleted by the requester - enum: - - MAX_EVENTS_REACHED - - NETWORK_TERMINATED - - SUBSCRIPTION_EXPIRED - - ACCESS_TOKEN_EXPIRED - - SUBSCRIPTION_DELETED - - DateTime: - type: string - format: date-time - description: | - Timestamp of when the occurrence happened. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. - example: "2023-07-03T12:27:08.312Z" - - EventTypeNotification: - type: string - description: | - event-type - Event triggered when an event-type event occurred - subscription-ended: Event triggered when the subscription ends - enum: - - org.camaraproject.user-experience-insights.v0.network-quality - - org.camaraproject.user-experience-insights.v0.subscription-ended - ErrorInfo: - type: object - description: Error information - required: - - status - - code - - message - properties: - status: - type: integer - description: HTTP response status code - code: - type: string - description: A human-readable code to describe the error - message: - type: string - description: A human-readable description of what the event represents - UserExperienceInsightsResponse: - type: object - description: user experience insights result - required: - - UserExperienceInsightsRecords - properties: - device: - $ref: '#/components/schemas/Device' - UserExperienceInsightsRecords: - type: array - items: - $ref: "#/components/schemas/UserExperienceInsightsRecords" - minItems: 1 - responses: - CreateSubscriptionBadRequest400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - - OUT_OF_RANGE - - INVALID_PROTOCOL - - INVALID_CREDENTIAL - - INVALID_TOKEN - - INVALID_SINK - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_OUT_OF_RANGE: - description: Out of Range. Specific Syntax Exception used when a given field has a pre-defined range or a invalid filter criteria combination is requested - value: - status: 400 - code: OUT_OF_RANGE - message: Client specified an invalid range. - GENERIC_400_INVALID_PROTOCOL: - description: Invalid protocol for events subscription management - value: - status: 400 - code: INVALID_PROTOCOL - message: Only HTTP is supported - GENERIC_400_INVALID_CREDENTIAL: - description: Invalid sink credential type - value: - status: 400 - code: INVALID_CREDENTIAL - message: Only Access token is supported - GENERIC_400_INVALID_TOKEN: - description: Invalid token type for sink credential of type ACCESSTOKEN - value: - status: 400 - code: INVALID_TOKEN - message: Only bearer token is supported - GENERIC_400_INVALID_SINK: - description: Invalid sink value - value: - status: 400 - code: INVALID_SINK - message: sink not valid for the specified protocol - Generic400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - SubscriptionIdRequired400: - description: Problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 400 - code: - enum: - - INVALID_ARGUMENT - examples: - GENERIC_400_INVALID_ARGUMENT: - description: Invalid Argument. Generic Syntax Exception - value: - status: 400 - code: INVALID_ARGUMENT - message: Client specified an invalid argument, request body or query param. - GENERIC_400_SUBSCRIPTION_ID_REQUIRED: - description: subscription id is required - value: - status: 400 - code: INVALID_ARGUMENT - message: "Expected property is missing: subscriptionId" - Generic401: - description: Authentication problem with the client request - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 401 - code: - enum: - - UNAUTHENTICATED - - examples: - GENERIC_401_UNAUTHENTICATED: - description: Request cannot be authenticated and a new authentication is required - value: - status: 401 - code: UNAUTHENTICATED - message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. - - Generic403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - SubscriptionPermissionDenied403: - description: Client does not have sufficient permission - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 403 - code: - enum: - - PERMISSION_DENIED - - SUBSCRIPTION_MISMATCH - examples: - GENERIC_403_PERMISSION_DENIED: - description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security - value: - status: 403 - code: PERMISSION_DENIED - message: Client does not have sufficient permissions to perform this action. - GENERIC_403_SUBSCRIPTION_MISMATCH: - description: Inconsistent access token for requested subscription - value: - status: 403 - code: "SUBSCRIPTION_MISMATCH" - message: "Inconsistent access token for requested events subscription" - Generic404: - description: Resource Not Found - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 404 - code: - enum: - - NOT_FOUND - examples: - GENERIC_404_NOT_FOUND: - description: Resource is not found - value: - status: 404 - code: NOT_FOUND - message: The specified resource is not found. - Generic410: - description: Gone - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 410 - code: - enum: - - GONE - examples: - GENERIC_410_GONE: - description: Use in notifications flow to allow API Consumer to indicate that its callback is no longer available - value: - status: 410 - code: GONE - message: Access to the target resource is no longer available. - CreateSubscriptionUnprocessableEntity422: - description: Unprocessable Entity - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 422 - code: - enum: - - SERVICE_NOT_APPLICABLE - - MISSING_IDENTIFIER - - UNNECESSARY_IDENTIFIER - examples: - GENERIC_422_SERVICE_NOT_APPLICABLE: - description: Service not applicable for the provided identifier - value: - status: 422 - code: SERVICE_NOT_APPLICABLE - message: The service is not available for the provided identifier. - GENERIC_422_MISSING_IDENTIFIER: - description: An identifier is not included in the request and the device or phone number identification cannot be derived from the 3-legged access token - value: - status: 422 - code: MISSING_IDENTIFIER - message: The device cannot be identified. - GENERIC_422_UNNECESSARY_IDENTIFIER: - description: An explicit identifier is provided when a device or phone number has already been identified from the access token - value: - status: 422 - code: UNNECESSARY_IDENTIFIER - message: The device is already identified by the access token. - Generic429: - description: Too Many Requests - headers: - x-correlator: - $ref: "#/components/headers/x-correlator" - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ErrorInfo" - - type: object - properties: - status: - enum: - - 429 - code: - enum: - - QUOTA_EXCEEDED - - TOO_MANY_REQUESTS - examples: - GENERIC_429_QUOTA_EXCEEDED: - description: Request is rejected due to exceeding a business quota limit - value: - status: 429 - code: QUOTA_EXCEEDED - message: Out of resource quota. - GENERIC_429_TOO_MANY_REQUESTS: - description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached - value: - status: 429 - code: TOO_MANY_REQUESTS - message: Rate limit reached. \ No newline at end of file