diff --git a/.gitignore b/.gitignore index dc1b0d6..7ca0807 100644 --- a/.gitignore +++ b/.gitignore @@ -40,15 +40,17 @@ node_modules/ tests/artifacts*/ tests/*_REPORT.md tests/*_FIX_SUGGESTIONS.md +tests/.fixture-resources.json -# Local example runners — contain real credentials, never commit +# Local example runners and credentials, never commit tests/examples/ +tests/.env # Local example helper script + its machine-specific classpath cache /run-example.sh /.example-classpath # Local working files (not part of the published SDK) -/fixed 7.yaml /CLAUDE.md -/fastpix-openai.yaml +/openapi.yaml +/spec_sync_check.* diff --git a/CHANGELOG.md b/CHANGELOG.md index fc80f9f..efcdd11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,38 @@ All notable changes to this project will be documented in this file. --- +## [1.1.0] + +### Breaking + +- Media `duration` is now a `Double` (seconds) instead of an `"HH:MM:SS"` string, + matching the updated API. Affects `manageVideos().get`, `manageVideos().list`, + `videos().updateMedia`, `manageVideos().updateSourceAccess`, + `videos().updateMp4Support`, `videos().listLiveClips`, `videos().getMediaClips`, + and every playlist operation that returns `mediaList`. Code reading `duration()` as + `Optional` no longer compiles. + +### Added + +- `enableRecording` on live stream creation (`InputMediaSettings`, the API + defaults it to true). +- `accessRestrictions` (domain and user-agent allow/deny policies) on live + playback ID create/get responses, `PlaybackIdRequest`, `PlaybackSettings`, + and the `playbackIds` items of live stream responses. +- `livePlayback().updateDomainRestrictions` for + `PATCH /live/streams/{streamId}/playback-ids/{playbackId}/domains`. +- `livePlayback().updateUserAgentRestrictions` for + `PATCH /live/streams/{streamId}/playback-ids/{playbackId}/user-agents`. +- Async variants of both on `livePlayback().async()`. +- Offline model contract tests and mocked endpoint tests under `src/test`. + +### Fixed + +- Async operation paths were audited for missing error propagation and + mismatched response types; none were found. + +--- + ## [1.0.5] ### Changed diff --git a/README.md b/README.md index 5790e9a..4cf1013 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Add the dependency to your `build.gradle`: ```groovy dependencies { - implementation 'io.fastpix:sdk:1.0.5' + implementation 'io.fastpix:sdk:1.1.0' } ``` @@ -77,7 +77,7 @@ Add the dependency to your `pom.xml`: io.fastpix sdk - 1.0.5 + 1.1.0 ``` @@ -369,6 +369,8 @@ For detailed documentation, see [FastPix Live Stream Overview](https://fastpix.c - [Create Playback ID](docs/sdks/liveplayback/README.md#createplaybackid) - Generate secure live playback access - [Delete Playback ID](docs/sdks/liveplayback/README.md#deleteplaybackid) - Revoke live playback access - [Get Playback ID](docs/sdks/liveplaybacks/README.md#getplaybackiddetails) - Retrieve live playback configuration +- [Update Domain Restrictions](docs/sdks/liveplayback/README.md#updatedomainrestrictions) - Allow or deny playback by domain +- [Update User-Agent Restrictions](docs/sdks/liveplayback/README.md#updateuseragentrestrictions) - Allow or deny playback by user agent #### Simulcast Stream - [Create Simulcast](docs/sdks/simulcaststream/README.md#create) - Set up multi-platform streaming diff --git a/docs/models/components/GetAllMediaResponse.md b/docs/models/components/GetAllMediaResponse.md index c9d479f..d83a8e2 100644 --- a/docs/models/components/GetAllMediaResponse.md +++ b/docs/models/components/GetAllMediaResponse.md @@ -28,7 +28,7 @@ | `moderation` | [Optional\](../../models/components/AiResponseRecord.md) | :heavy_minus_sign: | Represents an AI response record containing status and data for AI-generated features like summary, chapters, named entities, or moderation. | | | `isAudioOnly` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether the media contains only audio (no video track). | false | | `subtitleAvailable` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether subtitles are available for the media. | true | -| `duration` | *Optional\* | :heavy_minus_sign: | The length of the media in seconds, with a maximum allowed duration of 12 hours per individual media. | 00:00:10 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `frameRate` | *Optional\* | :heavy_minus_sign: | Frame rate quantifies the speed at which frames are displayed per second. It represents the range of frames available for a specific track. The indeterminable frame rate of the input file is indicated by a value of -1. | 30/1 | | `aspectRatio` | *JsonNullable\* | :heavy_minus_sign: | The aspect ratio of a video is a value that describes the relative shape of a video based on its width and height. | 16:9 | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was created, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | diff --git a/docs/models/components/GetMediaDetailResponse.md b/docs/models/components/GetMediaDetailResponse.md index 3fb4eb1..7ec265c 100644 --- a/docs/models/components/GetMediaDetailResponse.md +++ b/docs/models/components/GetMediaDetailResponse.md @@ -28,7 +28,7 @@ | `moderation` | [Optional\](../../models/components/AiResponseRecord.md) | :heavy_minus_sign: | Represents an AI response record containing status and data for AI-generated features like summary, chapters, named entities, or moderation. | | | `isAudioOnly` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether the media contains only audio (no video track). | false | | `subtitleAvailable` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether subtitles are available for the media. | true | -| `duration` | *Optional\* | :heavy_minus_sign: | The length of the media in seconds, with a maximum allowed duration of 12 hours per individual media. | 00:00:10 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `frameRate` | *Optional\* | :heavy_minus_sign: | Frame rate quantifies the speed at which frames are displayed per second. It represents the range of frames available for a specific track. The indeterminable frame rate of the input file is indicated by a value of -1. | 30/1 | | `aspectRatio` | *JsonNullable\* | :heavy_minus_sign: | The aspect ratio of a video is a value that describes the relative shape of a video based on its width and height. | 16:9 | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was created, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | diff --git a/docs/models/components/InputMediaSettings.md b/docs/models/components/InputMediaSettings.md index d2fa466..1bae988 100644 --- a/docs/models/components/InputMediaSettings.md +++ b/docs/models/components/InputMediaSettings.md @@ -11,4 +11,5 @@ Contains configuration details for input media settings. | `reconnectWindow` | *Optional\* | :heavy_minus_sign: | Time period (in seconds) FastPix waits to reconnect before ending the stream when disconnected.
| 60 | | `mediaPolicy` | [Optional\](../../models/components/BasicAccessPolicy.md) | :heavy_minus_sign: | Basic access policy for media content | | | `metadata` | Map\ | :heavy_minus_sign: | Custom key–value pairs for tagging livestreams.
Allows up to 10 entries with a maximum of 255 characters each.
| {
"livestream_name": "fastpix_livestream"
} | -| `enableDvrMode` | *Optional\* | :heavy_minus_sign: | Enables DVR (Digital Video Recorder) functionality, allowing viewers to pause, rewind, and resume live playback.
| | \ No newline at end of file +| `enableDvrMode` | *Optional\* | :heavy_minus_sign: | Enables DVR (Digital Video Recorder) functionality, allowing viewers to pause, rewind, and resume live playback.
| | +| `enableRecording` | *Optional\* | :heavy_minus_sign: | Controls whether the livestream is recorded to a VOD asset (Live-to-VOD). Defaults to true. | true | diff --git a/docs/models/components/LiveMediaClips.md b/docs/models/components/LiveMediaClips.md index cba583b..8ddb349 100644 --- a/docs/models/components/LiveMediaClips.md +++ b/docs/models/components/LiveMediaClips.md @@ -20,7 +20,7 @@ | `generatedSubtitles` | List\<[TracksSubtitles](../../models/components/TracksSubtitles.md)> | :heavy_minus_sign: | List of generated subtitle tracks associated with the media. | | | `isAudioOnly` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether the media contains only audio (no video track). | false | | `subtitleAvailable` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether subtitles are available for the media. | true | -| `duration` | *Optional\* | :heavy_minus_sign: | The length of the media in seconds, with a maximum allowed duration of 12 hours per individual media. | 00:00:10 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `aspectRatio` | *JsonNullable\* | :heavy_minus_sign: | The aspect ratio of a video is a value that describes the relative shape of a video based on its width and height. | 16:9 | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was created, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | | `updatedAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was updated, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | diff --git a/docs/models/components/Media.md b/docs/models/components/Media.md index 5758fe8..4d754fb 100644 --- a/docs/models/components/Media.md +++ b/docs/models/components/Media.md @@ -26,7 +26,7 @@ | `moderation` | [Optional\](../../models/components/AiResponseRecord.md) | :heavy_minus_sign: | Represents an AI response record containing status and data for AI-generated features like summary, chapters, named entities, or moderation. | | | `isAudioOnly` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether the media contains only audio (no video track). | false | | `subtitleAvailable` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether subtitles are available for the media. | true | -| `duration` | *Optional\* | :heavy_minus_sign: | The length of the media in seconds, with a maximum allowed duration of 12 hours per individual media. | 00:00:10 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `aspectRatio` | *JsonNullable\* | :heavy_minus_sign: | The aspect ratio of a video is a value that describes the relative shape of a video based on its width and height. | 16:9 | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was created, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | | `updatedAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was updated, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | diff --git a/docs/models/components/MediaClipResponseData.md b/docs/models/components/MediaClipResponseData.md index b7082f4..55b7756 100644 --- a/docs/models/components/MediaClipResponseData.md +++ b/docs/models/components/MediaClipResponseData.md @@ -6,7 +6,7 @@ | Field | Type | Required | Description | Example | | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | | `id` | *Optional\* | :heavy_minus_sign: | The unique identifier assigned to the media by FastPix. | your-media-id | -| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in HH:MM:SS format. | 00:00:13 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `status` | [Optional\](../../models/components/MediaClipResponseStatus.md) | :heavy_minus_sign: | The current processing status of the media. | Ready | | `thumbnail` | *Optional\* | :heavy_minus_sign: | A video thumbnail that acts as a preview image for the video. | https://images.fastpix.app/your-media-id/thumbnail.png | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Timestamp of when the media was created. | 2025-03-12T06:17:26.403017Z | diff --git a/docs/models/components/PlaybackIdRequest.md b/docs/models/components/PlaybackIdRequest.md index 33ba717..82fb65b 100644 --- a/docs/models/components/PlaybackIdRequest.md +++ b/docs/models/components/PlaybackIdRequest.md @@ -5,4 +5,5 @@ | Field | Type | Required | Description | | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -| `accessPolicy` | [Optional\](../../models/components/BasicAccessPolicy.md) | :heavy_minus_sign: | Basic access policy for media content | \ No newline at end of file +| `accessPolicy` | [Optional\](../../models/components/BasicAccessPolicy.md) | :heavy_minus_sign: | Basic access policy for media content | +| `accessRestrictions` | [Optional\](../../models/components/PlaybackIdAccessRestrictions.md)| :heavy_minus_sign: | Domain and user-agent access restrictions applied to the playback ID. | diff --git a/docs/models/components/PlaybackIdResponse.md b/docs/models/components/PlaybackIdResponse.md index b1ca4f2..9849fb4 100644 --- a/docs/models/components/PlaybackIdResponse.md +++ b/docs/models/components/PlaybackIdResponse.md @@ -8,4 +8,5 @@ A collection of Playback ID objects utilized for crafting HLS playback urls. | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | `id` | *Optional\* | :heavy_minus_sign: | Unique identifier for the playbackId | your-playback-id | -| `accessPolicy` | *Optional\* | :heavy_minus_sign: | Determines if access to the streamed content is kept private or available to all. | public | \ No newline at end of file +| `accessPolicy` | *Optional\* | :heavy_minus_sign: | Determines if access to the streamed content is kept private or available to all. | public | +| `accessRestrictions` | [Optional\](../../models/components/PlaybackIdAccessRestrictions.md)| :heavy_minus_sign: | Domain and user-agent access restrictions applied to the playback ID. | | diff --git a/docs/models/components/PlaybackIdSuccessResponseData.md b/docs/models/components/PlaybackIdSuccessResponseData.md index 7a26e74..54dda7b 100644 --- a/docs/models/components/PlaybackIdSuccessResponseData.md +++ b/docs/models/components/PlaybackIdSuccessResponseData.md @@ -6,4 +6,5 @@ | Field | Type | Required | Description | Example | | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | `id` | *Optional\* | :heavy_minus_sign: | Unique identifier for the playbackId | your-playback-id | -| `accessPolicy` | *Optional\* | :heavy_minus_sign: | Determines if access to the streamed content is kept private or available to all. | public | \ No newline at end of file +| `accessPolicy` | *Optional\* | :heavy_minus_sign: | Determines if access to the streamed content is kept private or available to all. | public | +| `accessRestrictions` | [Optional\](../../models/components/PlaybackIdAccessRestrictions.md)| :heavy_minus_sign: | Domain and user-agent access restrictions applied to the playback ID. | | diff --git a/docs/models/components/PlaybackSettings.md b/docs/models/components/PlaybackSettings.md index e2d6bf5..8141241 100644 --- a/docs/models/components/PlaybackSettings.md +++ b/docs/models/components/PlaybackSettings.md @@ -7,4 +7,5 @@ Displays the result of the playback settings. | Field | Type | Required | Description | | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -| `accessPolicy` | [Optional\](../../models/components/BasicAccessPolicy.md) | :heavy_minus_sign: | Basic access policy for media content | \ No newline at end of file +| `accessPolicy` | [Optional\](../../models/components/BasicAccessPolicy.md) | :heavy_minus_sign: | Basic access policy for media content | +| `accessRestrictions` | [Optional\](../../models/components/PlaybackIdAccessRestrictions.md)| :heavy_minus_sign: | Domain and user-agent access restrictions applied to the playback ID. | diff --git a/docs/models/components/PlaylistByIdResponseMediaListItem.md b/docs/models/components/PlaylistByIdResponseMediaListItem.md index 254bff7..c719da2 100644 --- a/docs/models/components/PlaylistByIdResponseMediaListItem.md +++ b/docs/models/components/PlaylistByIdResponseMediaListItem.md @@ -7,7 +7,7 @@ | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Timestamp of media creation in the workspace. | 2025-03-21T05:58:38.000708Z | | `creatorId` | *JsonNullable\* | :heavy_minus_sign: | Creator ID of the media. | FastPix@14612 | -| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in hh:mm:ss format. | 00:00:10 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `id` | *Optional\* | :heavy_minus_sign: | unique id of the particular media. | your-playlist-id | | `sourceResolution` | *Optional\* | :heavy_minus_sign: | source resolution of the media. | 1080p | | `status` | *Optional\* | :heavy_minus_sign: | status of the media, only media with ready status is added to playlist. | Ready | diff --git a/docs/models/components/SourceAccessMedia.md b/docs/models/components/SourceAccessMedia.md index ea25ca0..4e0e506 100644 --- a/docs/models/components/SourceAccessMedia.md +++ b/docs/models/components/SourceAccessMedia.md @@ -25,7 +25,7 @@ | `moderation` | [Optional\](../../models/components/AiResponseRecord.md) | :heavy_minus_sign: | Represents an AI response record containing status and data for AI-generated features like summary, chapters, named entities, or moderation. | | | `isAudioOnly` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether the media contains only audio (no video track). | false | | `subtitleAvailable` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether subtitles are available for the media. | true | -| `duration` | *Optional\* | :heavy_minus_sign: | The length of the media in seconds, with a maximum allowed duration of 12 hours per individual media. | 00:00:10 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `aspectRatio` | *JsonNullable\* | :heavy_minus_sign: | The aspect ratio of a video describes its shape based on the relationship between its width and height. | 16:9 | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was created, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | | `updatedAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was updated, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | diff --git a/docs/models/components/UpdateMedia.md b/docs/models/components/UpdateMedia.md index 27dde8e..1b8b63a 100644 --- a/docs/models/components/UpdateMedia.md +++ b/docs/models/components/UpdateMedia.md @@ -25,7 +25,7 @@ | `moderation` | [Optional\](../../models/components/AiResponseRecord.md) | :heavy_minus_sign: | Represents an AI response record containing status and data for AI-generated features like summary, chapters, named entities, or moderation. | | | `isAudioOnly` | *JsonNullable\* | :heavy_minus_sign: | Indicates whether the media contains only audio (no video track). | false | | `subtitleAvailable` | *Optional\* | :heavy_minus_sign: | Specifies whether subtitle tracks are available for the media. | false | -| `duration` | *Optional\* | :heavy_minus_sign: | The length of the media in seconds, with a maximum allowed duration of 12 hours per individual media. | 00:00:10 | +| `duration` | *Optional\* | :heavy_minus_sign: | Duration of the media in seconds. | 145.82 | | `aspectRatio` | *Optional\* | :heavy_minus_sign: | The aspect ratio of a video is a value that describes the relative shape of a video based on its width and height. | 16:9 | | `createdAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was created, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | | `updatedAt` | [OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) | :heavy_minus_sign: | Time the media was updated, defined as a localDateTime (UTC Time). | 2023-10-20T10:50:34.594302Z | diff --git a/docs/models/operations/UpdateLiveStreamDomainRestrictionsData.md b/docs/models/operations/UpdateLiveStreamDomainRestrictionsData.md new file mode 100644 index 0000000..664c4b7 --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamDomainRestrictionsData.md @@ -0,0 +1,10 @@ +# UpdateLiveStreamDomainRestrictionsData + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `defaultPolicy` | *Optional\* | :heavy_minus_sign: | Specify the fallback behavior for domains that are not listed in the allow or deny lists. | allow | +| `allow` | List\<*String*> | :heavy_minus_sign: | List of domains explicitly allowed to play the media. | [
"yourdomain.com",
"yourworkdomain.com"
] | +| `deny` | List\<*String*> | :heavy_minus_sign: | List of domains explicitly denied from accessing the media. | [
"sampledomain.com"
] | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamDomainRestrictionsDefaultPolicy.md b/docs/models/operations/UpdateLiveStreamDomainRestrictionsDefaultPolicy.md new file mode 100644 index 0000000..ae7ef76 --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamDomainRestrictionsDefaultPolicy.md @@ -0,0 +1,11 @@ +# UpdateLiveStreamDomainRestrictionsDefaultPolicy + +Specify the fallback behavior for domains that are not listed in the `allow` or `deny` lists. + + +## Values + +| Name | Value | +| ------- | ------- | +| `ALLOW` | allow | +| `DENY` | deny | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamDomainRestrictionsRequest.md b/docs/models/operations/UpdateLiveStreamDomainRestrictionsRequest.md new file mode 100644 index 0000000..8a14a39 --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamDomainRestrictionsRequest.md @@ -0,0 +1,10 @@ +# UpdateLiveStreamDomainRestrictionsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `streamId` | *String* | :heavy_check_mark: | N/A | your-media-id | +| `playbackId` | *String* | :heavy_check_mark: | N/A | your-playback-id | +| `body` | [UpdateLiveStreamDomainRestrictionsRequestBody](../../models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.md b/docs/models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.md new file mode 100644 index 0000000..459b979 --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.md @@ -0,0 +1,10 @@ +# UpdateLiveStreamDomainRestrictionsRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| `defaultPolicy` | [Optional\](../../models/operations/UpdateLiveStreamDomainRestrictionsDefaultPolicy.md) | :heavy_minus_sign: | Specify the fallback behavior for domains that are not listed in the `allow` or `deny` lists. | allow | +| `allow` | List\<*String*> | :heavy_minus_sign: | List of domains explicitly allowed to play the media. | [
"yourdomain.com",
"sampledomain.com"
] | +| `deny` | List\<*String*> | :heavy_minus_sign: | List of domains explicitly denied from accessing the media. | [
"yourworkdomain.com"
] | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamDomainRestrictionsResponse.md b/docs/models/operations/UpdateLiveStreamDomainRestrictionsResponse.md new file mode 100644 index 0000000..4b85412 --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamDomainRestrictionsResponse.md @@ -0,0 +1,12 @@ +# UpdateLiveStreamDomainRestrictionsResponse + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| `contentType` | *String* | :heavy_check_mark: | HTTP response content type for this operation | +| `statusCode` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `rawResponse` | [HttpResponse\](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.html) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | +| `object` | [Optional\](../../models/operations/UpdateLiveStreamDomainRestrictionsResponseBody.md) | :heavy_minus_sign: | Successfully updated domain restrictions | +| `defaultError` | [Optional\](../../models/components/DefaultError.md) | :heavy_minus_sign: | See the range of possible error responses and their status codes. | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamDomainRestrictionsResponseBody.md b/docs/models/operations/UpdateLiveStreamDomainRestrictionsResponseBody.md new file mode 100644 index 0000000..e46a6be --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamDomainRestrictionsResponseBody.md @@ -0,0 +1,11 @@ +# UpdateLiveStreamDomainRestrictionsResponseBody + +Successfully updated domain restrictions + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| `success` | *Optional\* | :heavy_minus_sign: | Shows the request status. Returns true for success and false for failure. | true | +| `data` | [Optional\](../../models/operations/UpdateLiveStreamDomainRestrictionsData.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsData.md b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsData.md new file mode 100644 index 0000000..5e728ca --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsData.md @@ -0,0 +1,10 @@ +# UpdateLiveStreamUserAgentRestrictionsData + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `defaultPolicy` | *Optional\* | :heavy_minus_sign: | Specifies the default behavior for user agents not listed in the allow or deny lists. | allow | +| `allow` | List\<*String*> | :heavy_minus_sign: | List of user-agent substrings explicitly allowed. | [
"Mozilla/55.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
] | +| `deny` | List\<*String*> | :heavy_minus_sign: | List of user-agent substrings explicitly denied. | [
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/53745.36 (KHTML, like Gecko) Chrome/138.0.0.0 Mobile Safari/537.36"
] | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.md b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.md new file mode 100644 index 0000000..5e8bdbb --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.md @@ -0,0 +1,11 @@ +# UpdateLiveStreamUserAgentRestrictionsDefaultPolicy + +The default behavior when a user-agent is not listed in `allow` or `deny`. + + +## Values + +| Name | Value | +| ------- | ------- | +| `ALLOW` | allow | +| `DENY` | deny | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsRequest.md b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsRequest.md new file mode 100644 index 0000000..9b60a86 --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsRequest.md @@ -0,0 +1,10 @@ +# UpdateLiveStreamUserAgentRestrictionsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `streamId` | *String* | :heavy_check_mark: | N/A | your-media-id | +| `playbackId` | *String* | :heavy_check_mark: | N/A | your-playback-id | +| `body` | [UpdateLiveStreamUserAgentRestrictionsRequestBody](../../models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.md) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.md b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.md new file mode 100644 index 0000000..520a8c8 --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.md @@ -0,0 +1,10 @@ +# UpdateLiveStreamUserAgentRestrictionsRequestBody + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `defaultPolicy` | [Optional\](../../models/operations/UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.md) | :heavy_minus_sign: | The default behavior when a user-agent is not listed in `allow` or `deny`. | allow | +| `allow` | List\<*String*> | :heavy_minus_sign: | List of user-agent substrings explicitly allowed. | [
"Mozilla/55.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
] | +| `deny` | List\<*String*> | :heavy_minus_sign: | List of user-agent substrings explicitly denied. | [
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/53745.36 (KHTML, like Gecko) Chrome/138.0.0.0 Mobile Safari/537.36"
] | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsResponse.md b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsResponse.md new file mode 100644 index 0000000..0e53d3f --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsResponse.md @@ -0,0 +1,12 @@ +# UpdateLiveStreamUserAgentRestrictionsResponse + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| `contentType` | *String* | :heavy_check_mark: | HTTP response content type for this operation | +| `statusCode` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `rawResponse` | [HttpResponse\](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.html) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | +| `object` | [Optional\](../../models/operations/UpdateLiveStreamUserAgentRestrictionsResponseBody.md) | :heavy_minus_sign: | Successfully updated user-agent restrictions | +| `defaultError` | [Optional\](../../models/components/DefaultError.md) | :heavy_minus_sign: | See the range of possible error responses and their status codes. | \ No newline at end of file diff --git a/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsResponseBody.md b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsResponseBody.md new file mode 100644 index 0000000..6050ffc --- /dev/null +++ b/docs/models/operations/UpdateLiveStreamUserAgentRestrictionsResponseBody.md @@ -0,0 +1,11 @@ +# UpdateLiveStreamUserAgentRestrictionsResponseBody + +Successfully updated user-agent restrictions + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `success` | *Optional\* | :heavy_minus_sign: | Shows the request status. Returns true for success and false for failure. | true | +| `data` | [Optional\](../../models/operations/UpdateLiveStreamUserAgentRestrictionsData.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/sdks/liveplayback/README.md b/docs/sdks/liveplayback/README.md index 2259f2e..3c05e68 100644 --- a/docs/sdks/liveplayback/README.md +++ b/docs/sdks/liveplayback/README.md @@ -6,6 +6,8 @@ * [createPlaybackId](#createplaybackid) - Create a playbackId * [deletePlaybackId](#deleteplaybackid) - Delete a playbackId +* [updateDomainRestrictions](#updatedomainrestrictions) - Update domain restrictions for a live playback ID +* [updateUserAgentRestrictions](#updateuseragentrestrictions) - Update user-agent restrictions for a live playback ID ## createPlaybackId @@ -28,9 +30,13 @@ package hello.world; // Import required classes from the FastPix SDK import java.lang.Exception; +import java.util.List; import com.fasterxml.jackson.databind.SerializationFeature; import io.fastpix.sdk.FastPixSDK; +import io.fastpix.sdk.models.components.PlaybackIdAccessRestrictions; +import io.fastpix.sdk.models.components.PlaybackIdDomains; import io.fastpix.sdk.models.components.PlaybackIdRequest; +import io.fastpix.sdk.models.components.PolicyAction; import io.fastpix.sdk.models.components.Security; import io.fastpix.sdk.models.operations.CreatePlaybackIdOfStreamResponse; import io.fastpix.sdk.utils.JSON; @@ -49,6 +55,12 @@ public class Application { CreatePlaybackIdOfStreamResponse res = sdk.livePlayback().createPlaybackId() .streamId("your-stream-id") .body(PlaybackIdRequest.builder() + .accessRestrictions(PlaybackIdAccessRestrictions.builder() + .domains(PlaybackIdDomains.builder() + .defaultPolicy(PolicyAction.DENY) + .allow(List.of("example.com")) + .build()) + .build()) .build()) .call(); @@ -140,4 +152,165 @@ public class Application { | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| models/errors/APIException | 4XX, 5XX | \*/\* | \ No newline at end of file +| models/errors/APIException | 4XX, 5XX | \*/\* | + +## updateDomainRestrictions + +This endpoint updates domain-level restrictions for a specific playback ID associated with a live stream. +It allows you to restrict playback to specific domains or block known unauthorized domains. + +**How it works:** +1. Make a `PATCH` request to this endpoint with your desired domain access configuration. +2. Set a default policy (`allow` or `deny`) and specify domain names in the `allow` or `deny` lists. +3. This is commonly used to restrict video playback to your website or approved client domains. + +**Example:** +A streaming service can allow playback only from `example.com` and deny all others by setting: `"defaultPolicy": "deny"` and `"allow": ["example.com"]`. + + +### Example Usage + + +```java +// Package declaration - adjust to match your project's directory structure +package hello.world; + +// Import required classes from the FastPix SDK +import java.lang.Exception; +import java.util.List; +import com.fasterxml.jackson.databind.SerializationFeature; +import io.fastpix.sdk.FastPixSDK; +import io.fastpix.sdk.models.components.Security; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsResponse; +import io.fastpix.sdk.utils.JSON; + +public class Application { + + public static void main(String[] args) throws Exception { + + FastPixSDK sdk = FastPixSDK.builder() + .security(Security.builder() + .username("your-access-token") + .password("your-secret-key") + .build()) + .build(); + + UpdateLiveStreamDomainRestrictionsResponse res = sdk.livePlayback().updateDomainRestrictions() + .streamId("your-stream-id") + .playbackId("your-playback-id") + .body(UpdateLiveStreamDomainRestrictionsRequestBody.builder() + .allow(List.of( + "yourdomain.com", + "sampledomain.com")) + .deny(List.of( + "yourworkdomain.com")) + .build()) + .call(); + + if (res.object().isPresent()) { + var mapper = JSON.getMapper(); + mapper.enable(SerializationFeature.INDENT_OUTPUT); + System.out.println(mapper.writeValueAsString(res.object().get())); + } + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `streamId` | *String* | :heavy_check_mark: | N/A | your-stream-id | +| `playbackId` | *String* | :heavy_check_mark: | N/A | your-playback-id | +| `body` | [UpdateLiveStreamDomainRestrictionsRequestBody](../../models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.md) | :heavy_check_mark: | N/A | | + +### Response + +**[UpdateLiveStreamDomainRestrictionsResponse](../../models/operations/UpdateLiveStreamDomainRestrictionsResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| models/errors/APIException | 4XX, 5XX | \*/\* | + +## updateUserAgentRestrictions + +This endpoint allows updating user-agent restrictions for a specific playback ID associated with a live stream. +It can be used to allow or deny specific user-agents during playback request evaluation. + +**How it works:** +1. Make a `PATCH` request to this endpoint with your desired user-agent access configuration. +2. Specify a default policy (`allow` or `deny`) and provide specific `allow` or `deny` lists. +3. Use this to restrict access to specific browsers, devices, or bots. + +**Example:** +A developer may configure a playback ID to deny access from known scraping user-agents while allowing all others by default. + + +### Example Usage + + +```java +// Package declaration - adjust to match your project's directory structure +package hello.world; + +// Import required classes from the FastPix SDK +import java.lang.Exception; +import java.util.List; +import com.fasterxml.jackson.databind.SerializationFeature; +import io.fastpix.sdk.FastPixSDK; +import io.fastpix.sdk.models.components.Security; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsResponse; +import io.fastpix.sdk.utils.JSON; + +public class Application { + + public static void main(String[] args) throws Exception { + + FastPixSDK sdk = FastPixSDK.builder() + .security(Security.builder() + .username("your-access-token") + .password("your-secret-key") + .build()) + .build(); + + UpdateLiveStreamUserAgentRestrictionsResponse res = sdk.livePlayback().updateUserAgentRestrictions() + .streamId("your-stream-id") + .playbackId("your-playback-id") + .body(UpdateLiveStreamUserAgentRestrictionsRequestBody.builder() + .allow(List.of( + "Mozilla/55.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36")) + .deny(List.of( + "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/53745.36 (KHTML, like Gecko) Chrome/138.0.0.0 Mobile Safari/537.36")) + .build()) + .call(); + + if (res.object().isPresent()) { + var mapper = JSON.getMapper(); + mapper.enable(SerializationFeature.INDENT_OUTPUT); + System.out.println(mapper.writeValueAsString(res.object().get())); + } + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `streamId` | *String* | :heavy_check_mark: | N/A | your-stream-id | +| `playbackId` | *String* | :heavy_check_mark: | N/A | your-playback-id | +| `body` | [UpdateLiveStreamUserAgentRestrictionsRequestBody](../../models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.md) | :heavy_check_mark: | N/A | | + +### Response + +**[UpdateLiveStreamUserAgentRestrictionsResponse](../../models/operations/UpdateLiveStreamUserAgentRestrictionsResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| models/errors/APIException | 4XX, 5XX | \*/\* | diff --git a/docs/sdks/streams/README.md b/docs/sdks/streams/README.md index fb331d8..f07c6a9 100644 --- a/docs/sdks/streams/README.md +++ b/docs/sdks/streams/README.md @@ -64,6 +64,7 @@ public class Application { .inputMediaSettings(InputMediaSettings.builder() .metadata(Map.ofEntries( Map.entry("livestream_name", "fastpix_livestream"))) + .enableRecording(true) .build()) .build(); diff --git a/examples/build.gradle b/examples/build.gradle index 0be67f6..eeafc5c 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -3,7 +3,7 @@ plugins { } group = 'com.fastpix' -version = '1.0.5' +version = '1.1.0' java { sourceCompatibility = JavaVersion.VERSION_11 @@ -18,7 +18,7 @@ repositories { dependencies { // jackson-databind arrives transitively at compile scope from the SDK, // which exposes ObjectMapper and JsonNode in its public API. - implementation 'io.fastpix:sdk:1.0.5' + implementation 'io.fastpix:sdk:1.1.0' runtimeOnly 'org.slf4j:slf4j-simple:2.0.9' testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2' diff --git a/examples/spring-boot/build.gradle b/examples/spring-boot/build.gradle index 47638d2..ea66332 100644 --- a/examples/spring-boot/build.gradle +++ b/examples/spring-boot/build.gradle @@ -3,7 +3,7 @@ plugins { } group = 'com.fastpix' -version = '1.0.5' +version = '1.1.0' java { sourceCompatibility = JavaVersion.VERSION_17 @@ -19,7 +19,7 @@ def springBootVersion = '3.2.0' dependencies { implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" - implementation 'io.fastpix:sdk:1.0.5' + implementation 'io.fastpix:sdk:1.1.0' } // Run the app with `./gradlew bootRun` (reads FASTPIX_* from the environment). diff --git a/examples/src/main/java/com/fastpix/example/LiveStreamingExample.java b/examples/src/main/java/com/fastpix/example/LiveStreamingExample.java index 742e4e0..16922af 100644 --- a/examples/src/main/java/com/fastpix/example/LiveStreamingExample.java +++ b/examples/src/main/java/com/fastpix/example/LiveStreamingExample.java @@ -1,5 +1,6 @@ package com.fastpix.example; +import java.util.List; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; @@ -10,14 +11,19 @@ import io.fastpix.sdk.models.components.CreateLiveStreamRequest; import io.fastpix.sdk.models.components.InputMediaSettings; import io.fastpix.sdk.models.components.PatchLiveStreamRequest; +import io.fastpix.sdk.models.components.PlaybackIdAccessRestrictions; +import io.fastpix.sdk.models.components.PlaybackIdDomains; import io.fastpix.sdk.models.components.PlaybackIdRequest; import io.fastpix.sdk.models.components.PlaybackSettings; +import io.fastpix.sdk.models.components.PolicyAction; import io.fastpix.sdk.models.components.Security; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; import io.fastpix.sdk.utils.JSON; /** - * Live streaming lifecycle: create a live stream, give it a playback id, read - * and update it, toggle its state, then delete it. New streams start enabled, + * Live streaming lifecycle: create a live stream (with recording enabled), give + * it a domain-restricted playback id, tighten those restrictions, read and + * update the stream, toggle its state, then delete it. New streams start enabled, * so this disables before re-enabling and cleans up the stream at the end. */ public class LiveStreamingExample { @@ -37,26 +43,45 @@ public static void main(String[] args) throws Exception { ObjectMapper mapper = JSON.getMapper().enable(SerializationFeature.INDENT_OUTPUT); - // 1. Create a live stream. + // 1. Create a live stream. enableRecording keeps a VOD copy (the API default). var stream = sdk.streams().create(CreateLiveStreamRequest.builder() .playbackSettings(PlaybackSettings.builder() .accessPolicy(BasicAccessPolicy.PUBLIC) .build()) .inputMediaSettings(InputMediaSettings.builder() .metadata(Map.of("livestream_name", "fastpix_livestream")) + .enableRecording(true) .build()) .build()); System.out.println("=== create stream ==="); System.out.println(mapper.writeValueAsString(stream.liveStreamResponseDTO().get())); String streamId = stream.liveStreamResponseDTO().get().data().get().streamId().orElseThrow(); - // 2. Give it a playback id. + // 2. Give it a playback id that only example.com may embed. System.out.println("\n=== create playback id ==="); - System.out.println(mapper.writeValueAsString(sdk.livePlayback() + var playbackId = sdk.livePlayback() .createPlaybackId(streamId, PlaybackIdRequest.builder() .accessPolicy(BasicAccessPolicy.PUBLIC) + .accessRestrictions(PlaybackIdAccessRestrictions.builder() + .domains(PlaybackIdDomains.builder() + .defaultPolicy(PolicyAction.DENY) + .allow(List.of("example.com")) + .build()) + .build()) .build()) - .playbackIdSuccessResponse().get())); + .playbackIdSuccessResponse().get(); + System.out.println(mapper.writeValueAsString(playbackId)); + String playbackIdValue = playbackId.data().get().id().orElseThrow(); + + // 2b. Tighten the domain restrictions on that playback id. + System.out.println("\n=== update domain restrictions ==="); + System.out.println(mapper.writeValueAsString(sdk.livePlayback() + .updateDomainRestrictions(streamId, playbackIdValue, + UpdateLiveStreamDomainRestrictionsRequestBody.builder() + .allow(List.of("example.com", "*.example.com")) + .deny(List.of("malicioussite.io")) + .build()) + .object().get())); // 3. Read + update the stream. System.out.println("\n=== get stream ==="); diff --git a/gradle.properties b/gradle.properties index af3e507..c0c66cf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ groupId=io.fastpix artifactId=sdk -version=1.0.5 +version=1.1.0 springBootVersion=3.2.0 org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g diff --git a/src/main/java/io/fastpix/sdk/AsyncLivePlayback.java b/src/main/java/io/fastpix/sdk/AsyncLivePlayback.java index a406cf3..a89dc70 100644 --- a/src/main/java/io/fastpix/sdk/AsyncLivePlayback.java +++ b/src/main/java/io/fastpix/sdk/AsyncLivePlayback.java @@ -14,6 +14,16 @@ import io.fastpix.sdk.models.operations.async.DeletePlaybackIdOfStreamResponse; import io.fastpix.sdk.operations.CreatePlaybackIdOfStream; import io.fastpix.sdk.operations.DeletePlaybackIdOfStream; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.async.UpdateLiveStreamDomainRestrictionsRequestBuilder; +import io.fastpix.sdk.models.operations.async.UpdateLiveStreamDomainRestrictionsResponse; +import io.fastpix.sdk.operations.UpdateLiveStreamDomainRestrictions; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.async.UpdateLiveStreamUserAgentRestrictionsRequestBuilder; +import io.fastpix.sdk.models.operations.async.UpdateLiveStreamUserAgentRestrictionsResponse; +import io.fastpix.sdk.operations.UpdateLiveStreamUserAgentRestrictions; import io.fastpix.sdk.utils.Headers; import io.fastpix.sdk.utils.Options; @@ -176,4 +186,175 @@ public CompletableFuture deletePlaybackId( .thenCompose(operation::handleResponse); } + + /** + * Update domain restrictions for a playback ID + * + *

This endpoint updates domain-level restrictions for a specific playback ID associated with a live + * stream. + * It allows you to restrict playback to specific domains or block known unauthorized domains. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired domain access configuration. + * 2. Set a default policy (`allow` or `deny`) and specify domain names in the `allow` or `deny` lists. + * 3. This is commonly used to restrict video playback to your website or approved client domains. + * + *

**Example:** + * A streaming service can allow playback only from `example.com` and deny all others by setting: + * `"defaultPolicy": "deny"` and `"allow": ["example.com"]`. + * + * @return The async call builder + */ + public UpdateLiveStreamDomainRestrictionsRequestBuilder updateDomainRestrictions() { + return new UpdateLiveStreamDomainRestrictionsRequestBuilder(sdkConfiguration); + } + + /** + * Update domain restrictions for a playback ID + * + *

This endpoint updates domain-level restrictions for a specific playback ID associated with a live + * stream. + * It allows you to restrict playback to specific domains or block known unauthorized domains. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired domain access configuration. + * 2. Set a default policy (`allow` or `deny`) and specify domain names in the `allow` or `deny` lists. + * 3. This is commonly used to restrict video playback to your website or approved client domains. + * + *

**Example:** + * A streaming service can allow playback only from `example.com` and deny all others by setting: + * `"defaultPolicy": "deny"` and `"allow": ["example.com"]`. + * + * @param streamId + * @param playbackId + * @param body + * @return {@code CompletableFuture} - The async response + */ + public CompletableFuture updateDomainRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body) { + return updateDomainRestrictions( + streamId, playbackId, body, + null); + } + + /** + * Update domain restrictions for a playback ID + * + *

This endpoint updates domain-level restrictions for a specific playback ID associated with a live + * stream. + * It allows you to restrict playback to specific domains or block known unauthorized domains. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired domain access configuration. + * 2. Set a default policy (`allow` or `deny`) and specify domain names in the `allow` or `deny` lists. + * 3. This is commonly used to restrict video playback to your website or approved client domains. + * + *

**Example:** + * A streaming service can allow playback only from `example.com` and deny all others by setting: + * `"defaultPolicy": "deny"` and `"allow": ["example.com"]`. + * + * @param streamId + * @param playbackId + * @param body + * @param options additional options + * @return {@code CompletableFuture} - The async response + */ + public CompletableFuture updateDomainRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body, @Nullable Options options) { + UpdateLiveStreamDomainRestrictionsRequest request = new UpdateLiveStreamDomainRestrictionsRequest(streamId, playbackId, body); + AsyncRequestOperation operation + = new UpdateLiveStreamDomainRestrictions.Async( + sdkConfiguration, options, sdkConfiguration.retryScheduler(), + _headers); + return operation.doRequest(request) + .thenCompose(operation::handleResponse); + } + + + /** + * Update user-agent restrictions for a playback ID + * + *

This endpoint allows updating user-agent restrictions for a specific playback ID associated with a + * live stream. + * It can be used to allow or deny specific user-agents during playback request evaluation. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired user-agent access configuration. + * 2. Specify a default policy (`allow` or `deny`) and provide specific `allow` or `deny` lists. + * 3. Use this to restrict access to specific browsers, devices, or bots. + * + *

**Example:** + * A developer may configure a playback ID to deny access from known scraping user-agents while + * allowing all others by default. + * + * @return The async call builder + */ + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder updateUserAgentRestrictions() { + return new UpdateLiveStreamUserAgentRestrictionsRequestBuilder(sdkConfiguration); + } + + /** + * Update user-agent restrictions for a playback ID + * + *

This endpoint allows updating user-agent restrictions for a specific playback ID associated with a + * live stream. + * It can be used to allow or deny specific user-agents during playback request evaluation. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired user-agent access configuration. + * 2. Specify a default policy (`allow` or `deny`) and provide specific `allow` or `deny` lists. + * 3. Use this to restrict access to specific browsers, devices, or bots. + * + *

**Example:** + * A developer may configure a playback ID to deny access from known scraping user-agents while + * allowing all others by default. + * + * @param streamId + * @param playbackId + * @param body + * @return {@code CompletableFuture} - The async response + */ + public CompletableFuture updateUserAgentRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body) { + return updateUserAgentRestrictions( + streamId, playbackId, body, + null); + } + + /** + * Update user-agent restrictions for a playback ID + * + *

This endpoint allows updating user-agent restrictions for a specific playback ID associated with a + * live stream. + * It can be used to allow or deny specific user-agents during playback request evaluation. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired user-agent access configuration. + * 2. Specify a default policy (`allow` or `deny`) and provide specific `allow` or `deny` lists. + * 3. Use this to restrict access to specific browsers, devices, or bots. + * + *

**Example:** + * A developer may configure a playback ID to deny access from known scraping user-agents while + * allowing all others by default. + * + * @param streamId + * @param playbackId + * @param body + * @param options additional options + * @return {@code CompletableFuture} - The async response + */ + public CompletableFuture updateUserAgentRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body, @Nullable Options options) { + UpdateLiveStreamUserAgentRestrictionsRequest request = new UpdateLiveStreamUserAgentRestrictionsRequest(streamId, playbackId, body); + AsyncRequestOperation operation + = new UpdateLiveStreamUserAgentRestrictions.Async( + sdkConfiguration, options, sdkConfiguration.retryScheduler(), + _headers); + return operation.doRequest(request) + .thenCompose(operation::handleResponse); + } } diff --git a/src/main/java/io/fastpix/sdk/LivePlayback.java b/src/main/java/io/fastpix/sdk/LivePlayback.java index 9972356..26743e1 100644 --- a/src/main/java/io/fastpix/sdk/LivePlayback.java +++ b/src/main/java/io/fastpix/sdk/LivePlayback.java @@ -13,6 +13,16 @@ import io.fastpix.sdk.models.operations.DeletePlaybackIdOfStreamResponse; import io.fastpix.sdk.operations.CreatePlaybackIdOfStream; import io.fastpix.sdk.operations.DeletePlaybackIdOfStream; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBuilder; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsResponse; +import io.fastpix.sdk.operations.UpdateLiveStreamDomainRestrictions; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBuilder; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsResponse; +import io.fastpix.sdk.operations.UpdateLiveStreamUserAgentRestrictions; import io.fastpix.sdk.utils.Headers; import io.fastpix.sdk.utils.Options; @@ -171,4 +181,170 @@ public DeletePlaybackIdOfStreamResponse deletePlaybackId( return operation.handleResponse(operation.doRequest(request)); } + + /** + * Update domain restrictions for a playback ID + * + *

This endpoint updates domain-level restrictions for a specific playback ID associated with a live + * stream. + * It allows you to restrict playback to specific domains or block known unauthorized domains. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired domain access configuration. + * 2. Set a default policy (`allow` or `deny`) and specify domain names in the `allow` or `deny` lists. + * 3. This is commonly used to restrict video playback to your website or approved client domains. + * + *

**Example:** + * A streaming service can allow playback only from `example.com` and deny all others by setting: + * `"defaultPolicy": "deny"` and `"allow": ["example.com"]`. + * + * @return The call builder + */ + public UpdateLiveStreamDomainRestrictionsRequestBuilder updateDomainRestrictions() { + return new UpdateLiveStreamDomainRestrictionsRequestBuilder(sdkConfiguration); + } + + /** + * Update domain restrictions for a playback ID + * + *

This endpoint updates domain-level restrictions for a specific playback ID associated with a live + * stream. + * It allows you to restrict playback to specific domains or block known unauthorized domains. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired domain access configuration. + * 2. Set a default policy (`allow` or `deny`) and specify domain names in the `allow` or `deny` lists. + * 3. This is commonly used to restrict video playback to your website or approved client domains. + * + *

**Example:** + * A streaming service can allow playback only from `example.com` and deny all others by setting: + * `"defaultPolicy": "deny"` and `"allow": ["example.com"]`. + * + * @param streamId + * @param playbackId + * @param body + * @return The response from the API call + * @throws RuntimeException subclass if the API call fails + */ + public UpdateLiveStreamDomainRestrictionsResponse updateDomainRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body) { + return updateDomainRestrictions(streamId, playbackId, body, + null); + } + + /** + * Update domain restrictions for a playback ID + * + *

This endpoint updates domain-level restrictions for a specific playback ID associated with a live + * stream. + * It allows you to restrict playback to specific domains or block known unauthorized domains. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired domain access configuration. + * 2. Set a default policy (`allow` or `deny`) and specify domain names in the `allow` or `deny` lists. + * 3. This is commonly used to restrict video playback to your website or approved client domains. + * + *

**Example:** + * A streaming service can allow playback only from `example.com` and deny all others by setting: + * `"defaultPolicy": "deny"` and `"allow": ["example.com"]`. + * + * @param streamId + * @param playbackId + * @param body + * @param options additional options + * @return The response from the API call + * @throws RuntimeException subclass if the API call fails + */ + public UpdateLiveStreamDomainRestrictionsResponse updateDomainRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body, @Nullable Options options) { + UpdateLiveStreamDomainRestrictionsRequest request = new UpdateLiveStreamDomainRestrictionsRequest(streamId, playbackId, body); + RequestOperation operation + = new UpdateLiveStreamDomainRestrictions.Sync(sdkConfiguration, options, _headers); + return operation.handleResponse(operation.doRequest(request)); + } + + /** + * Update user-agent restrictions for a playback ID + * + *

This endpoint allows updating user-agent restrictions for a specific playback ID associated with a + * live stream. + * It can be used to allow or deny specific user-agents during playback request evaluation. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired user-agent access configuration. + * 2. Specify a default policy (`allow` or `deny`) and provide specific `allow` or `deny` lists. + * 3. Use this to restrict access to specific browsers, devices, or bots. + * + *

**Example:** + * A developer may configure a playback ID to deny access from known scraping user-agents while + * allowing all others by default. + * + * @return The call builder + */ + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder updateUserAgentRestrictions() { + return new UpdateLiveStreamUserAgentRestrictionsRequestBuilder(sdkConfiguration); + } + + /** + * Update user-agent restrictions for a playback ID + * + *

This endpoint allows updating user-agent restrictions for a specific playback ID associated with a + * live stream. + * It can be used to allow or deny specific user-agents during playback request evaluation. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired user-agent access configuration. + * 2. Specify a default policy (`allow` or `deny`) and provide specific `allow` or `deny` lists. + * 3. Use this to restrict access to specific browsers, devices, or bots. + * + *

**Example:** + * A developer may configure a playback ID to deny access from known scraping user-agents while + * allowing all others by default. + * + * @param streamId + * @param playbackId + * @param body + * @return The response from the API call + * @throws RuntimeException subclass if the API call fails + */ + public UpdateLiveStreamUserAgentRestrictionsResponse updateUserAgentRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body) { + return updateUserAgentRestrictions(streamId, playbackId, body, + null); + } + + /** + * Update user-agent restrictions for a playback ID + * + *

This endpoint allows updating user-agent restrictions for a specific playback ID associated with a + * live stream. + * It can be used to allow or deny specific user-agents during playback request evaluation. + * + *

**How it works:** + * 1. Make a `PATCH` request to this endpoint with your desired user-agent access configuration. + * 2. Specify a default policy (`allow` or `deny`) and provide specific `allow` or `deny` lists. + * 3. Use this to restrict access to specific browsers, devices, or bots. + * + *

**Example:** + * A developer may configure a playback ID to deny access from known scraping user-agents while + * allowing all others by default. + * + * @param streamId + * @param playbackId + * @param body + * @param options additional options + * @return The response from the API call + * @throws RuntimeException subclass if the API call fails + */ + public UpdateLiveStreamUserAgentRestrictionsResponse updateUserAgentRestrictions( + @Nonnull String streamId, @Nonnull String playbackId, + @Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body, @Nullable Options options) { + UpdateLiveStreamUserAgentRestrictionsRequest request = new UpdateLiveStreamUserAgentRestrictionsRequest(streamId, playbackId, body); + RequestOperation operation + = new UpdateLiveStreamUserAgentRestrictions.Sync(sdkConfiguration, options, _headers); + return operation.handleResponse(operation.doRequest(request)); + } } diff --git a/src/main/java/io/fastpix/sdk/SDKConfiguration.java b/src/main/java/io/fastpix/sdk/SDKConfiguration.java index a608e1b..9c73324 100644 --- a/src/main/java/io/fastpix/sdk/SDKConfiguration.java +++ b/src/main/java/io/fastpix/sdk/SDKConfiguration.java @@ -19,7 +19,7 @@ public class SDKConfiguration { private static final String LANGUAGE = "java"; public static final String OPENAPI_DOC_VERSION = "1.0.1"; - public static final String SDK_VERSION = "1.0.5"; + public static final String SDK_VERSION = "1.1.0"; private static final String BASE_PACKAGE = "io.fastpix.sdk"; public static final String USER_AGENT = String.format("fastpix-sdk/%s %s %s %s", diff --git a/src/main/java/io/fastpix/sdk/models/components/GetAllMediaResponse.java b/src/main/java/io/fastpix/sdk/models/components/GetAllMediaResponse.java index ee439c9..de16323 100644 --- a/src/main/java/io/fastpix/sdk/models/components/GetAllMediaResponse.java +++ b/src/main/java/io/fastpix/sdk/models/components/GetAllMediaResponse.java @@ -190,12 +190,11 @@ public class GetAllMediaResponse { private JsonNullable subtitleAvailable; /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * Frame rate quantifies the speed at which frames are displayed per second. It represents the range of @@ -260,7 +259,7 @@ public GetAllMediaResponse( @JsonProperty("moderation") @Nullable AiResponseRecord moderation, @JsonProperty("isAudioOnly") @Nullable JsonNullable isAudioOnly, @JsonProperty("subtitleAvailable") @Nullable JsonNullable subtitleAvailable, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("frameRate") @Nullable String frameRate, @JsonProperty("aspectRatio") @Nullable JsonNullable aspectRatio, @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @@ -494,10 +493,9 @@ public JsonNullable subtitleAvailable() { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -763,10 +761,9 @@ public GetAllMediaResponse withSubtitleAvailable(@Nullable Boolean subtitleAvail /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public GetAllMediaResponse withDuration(@Nullable String duration) { + public GetAllMediaResponse withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -959,7 +956,7 @@ public static final class Builder { private JsonNullable subtitleAvailable; - private String duration; + private Double duration; private String frameRate; @@ -1171,10 +1168,9 @@ public Builder subtitleAvailable(@Nullable Boolean subtitleAvailable) { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/components/GetMediaDetailResponse.java b/src/main/java/io/fastpix/sdk/models/components/GetMediaDetailResponse.java index d0caddf..14ebe97 100644 --- a/src/main/java/io/fastpix/sdk/models/components/GetMediaDetailResponse.java +++ b/src/main/java/io/fastpix/sdk/models/components/GetMediaDetailResponse.java @@ -191,12 +191,11 @@ public class GetMediaDetailResponse { private JsonNullable subtitleAvailable; /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * Frame rate quantifies the speed at which frames are displayed per second. It represents the range of @@ -261,7 +260,7 @@ public GetMediaDetailResponse( @JsonProperty("moderation") @Nullable AiResponseRecord moderation, @JsonProperty("isAudioOnly") @Nullable JsonNullable isAudioOnly, @JsonProperty("subtitleAvailable") @Nullable JsonNullable subtitleAvailable, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("frameRate") @Nullable String frameRate, @JsonProperty("aspectRatio") @Nullable JsonNullable aspectRatio, @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @@ -495,10 +494,9 @@ public JsonNullable subtitleAvailable() { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -764,10 +762,9 @@ public GetMediaDetailResponse withSubtitleAvailable(@Nullable Boolean subtitleAv /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public GetMediaDetailResponse withDuration(@Nullable String duration) { + public GetMediaDetailResponse withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -960,7 +957,7 @@ public static final class Builder { private JsonNullable subtitleAvailable; - private String duration; + private Double duration; private String frameRate; @@ -1172,10 +1169,9 @@ public Builder subtitleAvailable(@Nullable Boolean subtitleAvailable) { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/components/InputMediaSettings.java b/src/main/java/io/fastpix/sdk/models/components/InputMediaSettings.java index d5b7d49..6f584d3 100644 --- a/src/main/java/io/fastpix/sdk/models/components/InputMediaSettings.java +++ b/src/main/java/io/fastpix/sdk/models/components/InputMediaSettings.java @@ -54,13 +54,21 @@ public class InputMediaSettings { @JsonProperty("enableDvrMode") private Boolean enableDvrMode; + /** + * Controls whether the livestream is recorded to a VOD asset (Live-to-VOD). Defaults to true. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("enableRecording") + private Boolean enableRecording; + @JsonCreator public InputMediaSettings( @JsonProperty("maxResolution") @Nullable CreateLiveStreamRequestMaxResolution maxResolution, @JsonProperty("reconnectWindow") @Nullable Long reconnectWindow, @JsonProperty("mediaPolicy") @Nullable BasicAccessPolicy mediaPolicy, @JsonProperty("metadata") @Nullable Map metadata, - @JsonProperty("enableDvrMode") @Nullable Boolean enableDvrMode) { + @JsonProperty("enableDvrMode") @Nullable Boolean enableDvrMode, + @JsonProperty("enableRecording") @Nullable Boolean enableRecording) { this.maxResolution = Optional.ofNullable(maxResolution) .orElse(Builder._SINGLETON_VALUE_MaxResolution.value()); this.reconnectWindow = Optional.ofNullable(reconnectWindow) @@ -69,11 +77,12 @@ public InputMediaSettings( .orElse(Builder._SINGLETON_VALUE_MediaPolicy.value()); this.metadata = metadata; this.enableDvrMode = enableDvrMode; + this.enableRecording = enableRecording; } public InputMediaSettings() { this(null, null, null, - null, null); + null, null, null); } /** @@ -113,6 +122,13 @@ public Optional enableDvrMode() { return Optional.ofNullable(this.enableDvrMode); } + /** + * Controls whether the livestream is recorded to a VOD asset (Live-to-VOD). Defaults to true. + */ + public Optional enableRecording() { + return Optional.ofNullable(this.enableRecording); + } + public static Builder builder() { return new Builder(); } @@ -165,6 +181,14 @@ public InputMediaSettings withEnableDvrMode(@Nullable Boolean enableDvrMode) { } + /** + * Controls whether the livestream is recorded to a VOD asset (Live-to-VOD). Defaults to true. + */ + public InputMediaSettings withEnableRecording(@Nullable Boolean enableRecording) { + this.enableRecording = enableRecording; + return this; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { @@ -179,14 +203,15 @@ public boolean equals(java.lang.Object o) { Utils.enhancedDeepEquals(this.reconnectWindow, other.reconnectWindow) && Utils.enhancedDeepEquals(this.mediaPolicy, other.mediaPolicy) && Utils.enhancedDeepEquals(this.metadata, other.metadata) && - Utils.enhancedDeepEquals(this.enableDvrMode, other.enableDvrMode); + Utils.enhancedDeepEquals(this.enableDvrMode, other.enableDvrMode) && + Utils.enhancedDeepEquals(this.enableRecording, other.enableRecording); } @Override public int hashCode() { return Utils.enhancedHash( maxResolution, reconnectWindow, mediaPolicy, - metadata, enableDvrMode); + metadata, enableDvrMode, enableRecording); } @Override @@ -196,7 +221,8 @@ public String toString() { "reconnectWindow", reconnectWindow, "mediaPolicy", mediaPolicy, "metadata", metadata, - "enableDvrMode", enableDvrMode); + "enableDvrMode", enableDvrMode, + "enableRecording", enableRecording); } @SuppressWarnings("UnusedReturnValue") @@ -212,6 +238,8 @@ public static final class Builder { private Boolean enableDvrMode; + private Boolean enableRecording; + private Builder() { // force use of static builder() method } @@ -258,10 +286,18 @@ public Builder enableDvrMode(@Nullable Boolean enableDvrMode) { return this; } + /** + * Controls whether the livestream is recorded to a VOD asset (Live-to-VOD). Defaults to true. + */ + public Builder enableRecording(@Nullable Boolean enableRecording) { + this.enableRecording = enableRecording; + return this; + } + public InputMediaSettings build() { return new InputMediaSettings( maxResolution, reconnectWindow, mediaPolicy, - metadata, enableDvrMode); + metadata, enableDvrMode, enableRecording); } diff --git a/src/main/java/io/fastpix/sdk/models/components/LiveMediaClips.java b/src/main/java/io/fastpix/sdk/models/components/LiveMediaClips.java index 7e40c30..d708558 100644 --- a/src/main/java/io/fastpix/sdk/models/components/LiveMediaClips.java +++ b/src/main/java/io/fastpix/sdk/models/components/LiveMediaClips.java @@ -123,12 +123,11 @@ public class LiveMediaClips { private JsonNullable subtitleAvailable; /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * The aspect ratio of a video is a value that describes the relative shape of a video based on its @@ -183,7 +182,7 @@ public LiveMediaClips( @JsonProperty("generatedSubtitles") @Nullable JsonNullable> generatedSubtitles, @JsonProperty("isAudioOnly") @Nullable JsonNullable isAudioOnly, @JsonProperty("subtitleAvailable") @Nullable JsonNullable subtitleAvailable, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("aspectRatio") @Nullable JsonNullable aspectRatio, @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @JsonProperty("updatedAt") @Nullable OffsetDateTime updatedAt, @@ -338,10 +337,9 @@ public JsonNullable subtitleAvailable() { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -523,10 +521,9 @@ public LiveMediaClips withSubtitleAvailable(@Nullable Boolean subtitleAvailable) /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public LiveMediaClips withDuration(@Nullable String duration) { + public LiveMediaClips withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -682,7 +679,7 @@ public static final class Builder { private JsonNullable subtitleAvailable; - private String duration; + private Double duration; private JsonNullable aspectRatio; @@ -820,10 +817,9 @@ public Builder subtitleAvailable(@Nullable Boolean subtitleAvailable) { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/components/Media.java b/src/main/java/io/fastpix/sdk/models/components/Media.java index bc6ac65..dd20032 100644 --- a/src/main/java/io/fastpix/sdk/models/components/Media.java +++ b/src/main/java/io/fastpix/sdk/models/components/Media.java @@ -176,12 +176,11 @@ public class Media { private JsonNullable subtitleAvailable; /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * The aspect ratio of a video is a value that describes the relative shape of a video based on its @@ -235,7 +234,7 @@ public Media( @JsonProperty("moderation") @Nullable AiResponseRecord moderation, @JsonProperty("isAudioOnly") @Nullable JsonNullable isAudioOnly, @JsonProperty("subtitleAvailable") @Nullable JsonNullable subtitleAvailable, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("aspectRatio") @Nullable JsonNullable aspectRatio, @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @JsonProperty("updatedAt") @Nullable OffsetDateTime updatedAt, @@ -450,10 +449,9 @@ public JsonNullable subtitleAvailable() { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -692,10 +690,9 @@ public Media withSubtitleAvailable(@Nullable Boolean subtitleAvailable) { /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Media withDuration(@Nullable String duration) { + public Media withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -866,7 +863,7 @@ public static final class Builder { private JsonNullable subtitleAvailable; - private String duration; + private Double duration; private JsonNullable aspectRatio; @@ -1060,10 +1057,9 @@ public Builder subtitleAvailable(@Nullable Boolean subtitleAvailable) { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/components/MediaClipResponseData.java b/src/main/java/io/fastpix/sdk/models/components/MediaClipResponseData.java index 999a132..094e335 100644 --- a/src/main/java/io/fastpix/sdk/models/components/MediaClipResponseData.java +++ b/src/main/java/io/fastpix/sdk/models/components/MediaClipResponseData.java @@ -20,11 +20,11 @@ public class MediaClipResponseData { private String id; /** - * Duration of the media in HH:MM:SS format. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * The current processing status of the media. @@ -55,7 +55,7 @@ public class MediaClipResponseData { @JsonCreator public MediaClipResponseData( @JsonProperty("id") @Nullable String id, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("status") @Nullable MediaClipResponseStatus status, @JsonProperty("thumbnail") @Nullable String thumbnail, @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @@ -81,9 +81,9 @@ public Optional id() { } /** - * Duration of the media in HH:MM:SS format. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -127,9 +127,9 @@ public MediaClipResponseData withId(@Nullable String id) { /** - * Duration of the media in HH:MM:SS format. + * Duration of the media in seconds. */ - public MediaClipResponseData withDuration(@Nullable String duration) { + public MediaClipResponseData withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -209,7 +209,7 @@ public static final class Builder { private String id; - private String duration; + private Double duration; private MediaClipResponseStatus status; @@ -232,9 +232,9 @@ public Builder id(@Nullable String id) { } /** - * Duration of the media in HH:MM:SS format. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/components/PlaybackIdRequest.java b/src/main/java/io/fastpix/sdk/models/components/PlaybackIdRequest.java index 43c9954..f6c21cb 100644 --- a/src/main/java/io/fastpix/sdk/models/components/PlaybackIdRequest.java +++ b/src/main/java/io/fastpix/sdk/models/components/PlaybackIdRequest.java @@ -19,15 +19,24 @@ public class PlaybackIdRequest { @JsonProperty("accessPolicy") private BasicAccessPolicy accessPolicy; + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("accessRestrictions") + private PlaybackIdAccessRestrictions accessRestrictions; + @JsonCreator public PlaybackIdRequest( - @JsonProperty("accessPolicy") @Nullable BasicAccessPolicy accessPolicy) { + @JsonProperty("accessPolicy") @Nullable BasicAccessPolicy accessPolicy, + @JsonProperty("accessRestrictions") @Nullable PlaybackIdAccessRestrictions accessRestrictions) { this.accessPolicy = Optional.ofNullable(accessPolicy) .orElse(Builder._SINGLETON_VALUE_AccessPolicy.value()); + this.accessRestrictions = accessRestrictions; } public PlaybackIdRequest() { - this(null); + this(null, null); } /** @@ -37,6 +46,13 @@ public Optional accessPolicy() { return Optional.ofNullable(this.accessPolicy); } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Optional accessRestrictions() { + return Optional.ofNullable(this.accessRestrictions); + } + public static Builder builder() { return new Builder(); } @@ -51,6 +67,14 @@ public PlaybackIdRequest withAccessPolicy(@Nullable BasicAccessPolicy accessPoli } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public PlaybackIdRequest withAccessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { @@ -61,19 +85,21 @@ public boolean equals(java.lang.Object o) { } PlaybackIdRequest other = (PlaybackIdRequest) o; return - Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy); + Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy) && + Utils.enhancedDeepEquals(this.accessRestrictions, other.accessRestrictions); } @Override public int hashCode() { return Utils.enhancedHash( - accessPolicy); + accessPolicy, accessRestrictions); } @Override public String toString() { return Utils.toString(PlaybackIdRequest.class, - "accessPolicy", accessPolicy); + "accessPolicy", accessPolicy, + "accessRestrictions", accessRestrictions); } @SuppressWarnings("UnusedReturnValue") @@ -81,6 +107,8 @@ public static final class Builder { private BasicAccessPolicy accessPolicy; + private PlaybackIdAccessRestrictions accessRestrictions; + private Builder() { // force use of static builder() method } @@ -93,9 +121,17 @@ public Builder accessPolicy(@Nullable BasicAccessPolicy accessPolicy) { return this; } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Builder accessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + public PlaybackIdRequest build() { return new PlaybackIdRequest( - accessPolicy); + accessPolicy, accessRestrictions); } diff --git a/src/main/java/io/fastpix/sdk/models/components/PlaybackIdResponse.java b/src/main/java/io/fastpix/sdk/models/components/PlaybackIdResponse.java index 0f4305d..80e8d3e 100644 --- a/src/main/java/io/fastpix/sdk/models/components/PlaybackIdResponse.java +++ b/src/main/java/io/fastpix/sdk/models/components/PlaybackIdResponse.java @@ -28,16 +28,25 @@ public class PlaybackIdResponse { @JsonProperty("accessPolicy") private String accessPolicy; + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("accessRestrictions") + private PlaybackIdAccessRestrictions accessRestrictions; + @JsonCreator public PlaybackIdResponse( @JsonProperty("id") @Nullable String id, - @JsonProperty("accessPolicy") @Nullable String accessPolicy) { + @JsonProperty("accessPolicy") @Nullable String accessPolicy, + @JsonProperty("accessRestrictions") @Nullable PlaybackIdAccessRestrictions accessRestrictions) { this.id = id; this.accessPolicy = accessPolicy; + this.accessRestrictions = accessRestrictions; } public PlaybackIdResponse() { - this(null, null); + this(null, null, null); } /** @@ -54,6 +63,13 @@ public Optional accessPolicy() { return Optional.ofNullable(this.accessPolicy); } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Optional accessRestrictions() { + return Optional.ofNullable(this.accessRestrictions); + } + public static Builder builder() { return new Builder(); } @@ -77,6 +93,14 @@ public PlaybackIdResponse withAccessPolicy(@Nullable String accessPolicy) { } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public PlaybackIdResponse withAccessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { @@ -88,20 +112,22 @@ public boolean equals(java.lang.Object o) { PlaybackIdResponse other = (PlaybackIdResponse) o; return Utils.enhancedDeepEquals(this.id, other.id) && - Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy); + Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy) && + Utils.enhancedDeepEquals(this.accessRestrictions, other.accessRestrictions); } @Override public int hashCode() { return Utils.enhancedHash( - id, accessPolicy); + id, accessPolicy, accessRestrictions); } @Override public String toString() { return Utils.toString(PlaybackIdResponse.class, "id", id, - "accessPolicy", accessPolicy); + "accessPolicy", accessPolicy, + "accessRestrictions", accessRestrictions); } @SuppressWarnings("UnusedReturnValue") @@ -111,6 +137,8 @@ public static final class Builder { private String accessPolicy; + private PlaybackIdAccessRestrictions accessRestrictions; + private Builder() { // force use of static builder() method } @@ -131,9 +159,17 @@ public Builder accessPolicy(@Nullable String accessPolicy) { return this; } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Builder accessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + public PlaybackIdResponse build() { return new PlaybackIdResponse( - id, accessPolicy); + id, accessPolicy, accessRestrictions); } } diff --git a/src/main/java/io/fastpix/sdk/models/components/PlaybackIdSuccessResponseData.java b/src/main/java/io/fastpix/sdk/models/components/PlaybackIdSuccessResponseData.java index 20038dd..1af36c6 100644 --- a/src/main/java/io/fastpix/sdk/models/components/PlaybackIdSuccessResponseData.java +++ b/src/main/java/io/fastpix/sdk/models/components/PlaybackIdSuccessResponseData.java @@ -24,16 +24,25 @@ public class PlaybackIdSuccessResponseData { @JsonProperty("accessPolicy") private String accessPolicy; + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("accessRestrictions") + private PlaybackIdAccessRestrictions accessRestrictions; + @JsonCreator public PlaybackIdSuccessResponseData( @JsonProperty("id") @Nullable String id, - @JsonProperty("accessPolicy") @Nullable String accessPolicy) { + @JsonProperty("accessPolicy") @Nullable String accessPolicy, + @JsonProperty("accessRestrictions") @Nullable PlaybackIdAccessRestrictions accessRestrictions) { this.id = id; this.accessPolicy = accessPolicy; + this.accessRestrictions = accessRestrictions; } public PlaybackIdSuccessResponseData() { - this(null, null); + this(null, null, null); } /** @@ -50,6 +59,13 @@ public Optional accessPolicy() { return Optional.ofNullable(this.accessPolicy); } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Optional accessRestrictions() { + return Optional.ofNullable(this.accessRestrictions); + } + public static Builder builder() { return new Builder(); } @@ -73,6 +89,14 @@ public PlaybackIdSuccessResponseData withAccessPolicy(@Nullable String accessPol } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public PlaybackIdSuccessResponseData withAccessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { @@ -84,20 +108,22 @@ public boolean equals(java.lang.Object o) { PlaybackIdSuccessResponseData other = (PlaybackIdSuccessResponseData) o; return Utils.enhancedDeepEquals(this.id, other.id) && - Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy); + Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy) && + Utils.enhancedDeepEquals(this.accessRestrictions, other.accessRestrictions); } @Override public int hashCode() { return Utils.enhancedHash( - id, accessPolicy); + id, accessPolicy, accessRestrictions); } @Override public String toString() { return Utils.toString(PlaybackIdSuccessResponseData.class, "id", id, - "accessPolicy", accessPolicy); + "accessPolicy", accessPolicy, + "accessRestrictions", accessRestrictions); } @SuppressWarnings("UnusedReturnValue") @@ -107,6 +133,8 @@ public static final class Builder { private String accessPolicy; + private PlaybackIdAccessRestrictions accessRestrictions; + private Builder() { // force use of static builder() method } @@ -127,9 +155,17 @@ public Builder accessPolicy(@Nullable String accessPolicy) { return this; } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Builder accessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + public PlaybackIdSuccessResponseData build() { return new PlaybackIdSuccessResponseData( - id, accessPolicy); + id, accessPolicy, accessRestrictions); } } diff --git a/src/main/java/io/fastpix/sdk/models/components/PlaybackSettings.java b/src/main/java/io/fastpix/sdk/models/components/PlaybackSettings.java index e419cec..df3a8f5 100644 --- a/src/main/java/io/fastpix/sdk/models/components/PlaybackSettings.java +++ b/src/main/java/io/fastpix/sdk/models/components/PlaybackSettings.java @@ -23,15 +23,24 @@ public class PlaybackSettings { @JsonProperty("accessPolicy") private BasicAccessPolicy accessPolicy; + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("accessRestrictions") + private PlaybackIdAccessRestrictions accessRestrictions; + @JsonCreator public PlaybackSettings( - @JsonProperty("accessPolicy") @Nullable BasicAccessPolicy accessPolicy) { + @JsonProperty("accessPolicy") @Nullable BasicAccessPolicy accessPolicy, + @JsonProperty("accessRestrictions") @Nullable PlaybackIdAccessRestrictions accessRestrictions) { this.accessPolicy = Optional.ofNullable(accessPolicy) .orElse(Builder._SINGLETON_VALUE_AccessPolicy.value()); + this.accessRestrictions = accessRestrictions; } public PlaybackSettings() { - this(null); + this(null, null); } /** @@ -41,6 +50,13 @@ public Optional accessPolicy() { return Optional.ofNullable(this.accessPolicy); } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Optional accessRestrictions() { + return Optional.ofNullable(this.accessRestrictions); + } + public static Builder builder() { return new Builder(); } @@ -55,6 +71,14 @@ public PlaybackSettings withAccessPolicy(@Nullable BasicAccessPolicy accessPolic } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public PlaybackSettings withAccessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + @Override public boolean equals(java.lang.Object o) { if (this == o) { @@ -65,19 +89,21 @@ public boolean equals(java.lang.Object o) { } PlaybackSettings other = (PlaybackSettings) o; return - Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy); + Utils.enhancedDeepEquals(this.accessPolicy, other.accessPolicy) && + Utils.enhancedDeepEquals(this.accessRestrictions, other.accessRestrictions); } @Override public int hashCode() { return Utils.enhancedHash( - accessPolicy); + accessPolicy, accessRestrictions); } @Override public String toString() { return Utils.toString(PlaybackSettings.class, - "accessPolicy", accessPolicy); + "accessPolicy", accessPolicy, + "accessRestrictions", accessRestrictions); } @SuppressWarnings("UnusedReturnValue") @@ -85,6 +111,8 @@ public static final class Builder { private BasicAccessPolicy accessPolicy; + private PlaybackIdAccessRestrictions accessRestrictions; + private Builder() { // force use of static builder() method } @@ -97,9 +125,17 @@ public Builder accessPolicy(@Nullable BasicAccessPolicy accessPolicy) { return this; } + /** + * Domain and user-agent access restrictions applied to the playback ID. + */ + public Builder accessRestrictions(@Nullable PlaybackIdAccessRestrictions accessRestrictions) { + this.accessRestrictions = accessRestrictions; + return this; + } + public PlaybackSettings build() { return new PlaybackSettings( - accessPolicy); + accessPolicy, accessRestrictions); } diff --git a/src/main/java/io/fastpix/sdk/models/components/PlaylistByIdResponseMediaListItem.java b/src/main/java/io/fastpix/sdk/models/components/PlaylistByIdResponseMediaListItem.java index ed39ccd..8879fd0 100644 --- a/src/main/java/io/fastpix/sdk/models/components/PlaylistByIdResponseMediaListItem.java +++ b/src/main/java/io/fastpix/sdk/models/components/PlaylistByIdResponseMediaListItem.java @@ -27,11 +27,11 @@ public class PlaylistByIdResponseMediaListItem { private JsonNullable creatorId; /** - * Duration of the media in hh:mm:ss format. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * unique id of the particular media. @@ -72,7 +72,7 @@ public class PlaylistByIdResponseMediaListItem { public PlaylistByIdResponseMediaListItem( @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @JsonProperty("creatorId") @Nullable JsonNullable creatorId, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("id") @Nullable String id, @JsonProperty("sourceResolution") @Nullable String sourceResolution, @JsonProperty("status") @Nullable String status, @@ -111,9 +111,9 @@ public JsonNullable creatorId() { } /** - * Duration of the media in hh:mm:ss format. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -176,9 +176,9 @@ public PlaylistByIdResponseMediaListItem withCreatorId(@Nullable String creatorI /** - * Duration of the media in hh:mm:ss format. + * Duration of the media in seconds. */ - public PlaylistByIdResponseMediaListItem withDuration(@Nullable String duration) { + public PlaylistByIdResponseMediaListItem withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -277,7 +277,7 @@ public static final class Builder { private JsonNullable creatorId; - private String duration; + private Double duration; private String id; @@ -310,9 +310,9 @@ public Builder creatorId(@Nullable String creatorId) { } /** - * Duration of the media in hh:mm:ss format. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/components/SourceAccessMedia.java b/src/main/java/io/fastpix/sdk/models/components/SourceAccessMedia.java index 6104a37..b4ce20b 100644 --- a/src/main/java/io/fastpix/sdk/models/components/SourceAccessMedia.java +++ b/src/main/java/io/fastpix/sdk/models/components/SourceAccessMedia.java @@ -165,12 +165,11 @@ public class SourceAccessMedia { private JsonNullable subtitleAvailable; /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * The aspect ratio of a video describes its shape based on the relationship between its width and @@ -230,7 +229,7 @@ public SourceAccessMedia( @JsonProperty("moderation") @Nullable AiResponseRecord moderation, @JsonProperty("isAudioOnly") @Nullable JsonNullable isAudioOnly, @JsonProperty("subtitleAvailable") @Nullable JsonNullable subtitleAvailable, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("aspectRatio") @Nullable JsonNullable aspectRatio, @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @JsonProperty("updatedAt") @Nullable OffsetDateTime updatedAt, @@ -434,10 +433,9 @@ public JsonNullable subtitleAvailable() { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -670,10 +668,9 @@ public SourceAccessMedia withSubtitleAvailable(@Nullable Boolean subtitleAvailab /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public SourceAccessMedia withDuration(@Nullable String duration) { + public SourceAccessMedia withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -850,7 +847,7 @@ public static final class Builder { private JsonNullable subtitleAvailable; - private String duration; + private Double duration; private JsonNullable aspectRatio; @@ -1034,10 +1031,9 @@ public Builder subtitleAvailable(@Nullable Boolean subtitleAvailable) { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/components/UpdateMedia.java b/src/main/java/io/fastpix/sdk/models/components/UpdateMedia.java index 7770c44..d47e037 100644 --- a/src/main/java/io/fastpix/sdk/models/components/UpdateMedia.java +++ b/src/main/java/io/fastpix/sdk/models/components/UpdateMedia.java @@ -165,12 +165,11 @@ public class UpdateMedia { private Boolean subtitleAvailable; /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ @JsonInclude(Include.NON_ABSENT) @JsonProperty("duration") - private String duration; + private Double duration; /** * The aspect ratio of a video is a value that describes the relative shape of a video based on its @@ -230,7 +229,7 @@ public UpdateMedia( @JsonProperty("moderation") @Nullable AiResponseRecord moderation, @JsonProperty("isAudioOnly") @Nullable JsonNullable isAudioOnly, @JsonProperty("subtitleAvailable") @Nullable Boolean subtitleAvailable, - @JsonProperty("duration") @Nullable String duration, + @JsonProperty("duration") @Nullable Double duration, @JsonProperty("aspectRatio") @Nullable String aspectRatio, @JsonProperty("createdAt") @Nullable OffsetDateTime createdAt, @JsonProperty("updatedAt") @Nullable OffsetDateTime updatedAt, @@ -431,10 +430,9 @@ public Optional subtitleAvailable() { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Optional duration() { + public Optional duration() { return Optional.ofNullable(this.duration); } @@ -667,10 +665,9 @@ public UpdateMedia withSubtitleAvailable(@Nullable Boolean subtitleAvailable) { /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public UpdateMedia withDuration(@Nullable String duration) { + public UpdateMedia withDuration(@Nullable Double duration) { this.duration = duration; return this; } @@ -847,7 +844,7 @@ public static final class Builder { private Boolean subtitleAvailable; - private String duration; + private Double duration; private String aspectRatio; @@ -1031,10 +1028,9 @@ public Builder subtitleAvailable(@Nullable Boolean subtitleAvailable) { } /** - * The length of the media in seconds, with a maximum allowed duration of 12 hours per individual - * media. + * Duration of the media in seconds. */ - public Builder duration(@Nullable String duration) { + public Builder duration(@Nullable Double duration) { this.duration = duration; return this; } diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsData.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsData.java new file mode 100644 index 0000000..62318df --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsData.java @@ -0,0 +1,174 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamDomainRestrictionsData { + /** + * Specify the fallback behavior for domains that are not listed in the allow or deny lists. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("defaultPolicy") + private String defaultPolicy; + + /** + * List of domains explicitly allowed to play the media. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("allow") + private List allow; + + /** + * List of domains explicitly denied from accessing the media. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("deny") + private List deny; + + @JsonCreator + public UpdateLiveStreamDomainRestrictionsData( + @JsonProperty("defaultPolicy") @Nullable String defaultPolicy, + @JsonProperty("allow") @Nullable List allow, + @JsonProperty("deny") @Nullable List deny) { + this.defaultPolicy = defaultPolicy; + this.allow = allow; + this.deny = deny; + } + + public UpdateLiveStreamDomainRestrictionsData() { + this(null, null, null); + } + + /** + * Specify the fallback behavior for domains that are not listed in the allow or deny lists. + */ + public Optional defaultPolicy() { + return Optional.ofNullable(this.defaultPolicy); + } + + /** + * List of domains explicitly allowed to play the media. + */ + public Optional> allow() { + return Optional.ofNullable(this.allow); + } + + /** + * List of domains explicitly denied from accessing the media. + */ + public Optional> deny() { + return Optional.ofNullable(this.deny); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * Specify the fallback behavior for domains that are not listed in the allow or deny lists. + */ + public UpdateLiveStreamDomainRestrictionsData withDefaultPolicy(@Nullable String defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + + /** + * List of domains explicitly allowed to play the media. + */ + public UpdateLiveStreamDomainRestrictionsData withAllow(@Nullable List allow) { + this.allow = allow; + return this; + } + + + /** + * List of domains explicitly denied from accessing the media. + */ + public UpdateLiveStreamDomainRestrictionsData withDeny(@Nullable List deny) { + this.deny = deny; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamDomainRestrictionsData other = (UpdateLiveStreamDomainRestrictionsData) o; + return + Utils.enhancedDeepEquals(this.defaultPolicy, other.defaultPolicy) && + Utils.enhancedDeepEquals(this.allow, other.allow) && + Utils.enhancedDeepEquals(this.deny, other.deny); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + defaultPolicy, allow, deny); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamDomainRestrictionsData.class, + "defaultPolicy", defaultPolicy, + "allow", allow, + "deny", deny); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String defaultPolicy; + + private List allow; + + private List deny; + + private Builder() { + // force use of static builder() method + } + + /** + * Specify the fallback behavior for domains that are not listed in the allow or deny lists. + */ + public Builder defaultPolicy(@Nullable String defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + /** + * List of domains explicitly allowed to play the media. + */ + public Builder allow(@Nullable List allow) { + this.allow = allow; + return this; + } + + /** + * List of domains explicitly denied from accessing the media. + */ + public Builder deny(@Nullable List deny) { + this.deny = deny; + return this; + } + + public UpdateLiveStreamDomainRestrictionsData build() { + return new UpdateLiveStreamDomainRestrictionsData( + defaultPolicy, allow, deny); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsDefaultPolicy.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsDefaultPolicy.java new file mode 100644 index 0000000..f9932fe --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsDefaultPolicy.java @@ -0,0 +1,36 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Objects; +import java.util.Optional; + +/** + * UpdateLiveStreamDomainRestrictionsDefaultPolicy + * + *

Specify the fallback behavior for domains that are not listed in the `allow` or `deny` lists. + */ +public enum UpdateLiveStreamDomainRestrictionsDefaultPolicy { + ALLOW("allow"), + DENY("deny"); + + @JsonValue + private final String value; + + UpdateLiveStreamDomainRestrictionsDefaultPolicy(String value) { + this.value = value; + } + + public String value() { + return value; + } + + public static Optional fromValue(String value) { + for (UpdateLiveStreamDomainRestrictionsDefaultPolicy o: UpdateLiveStreamDomainRestrictionsDefaultPolicy.values()) { + if (Objects.deepEquals(o.value, value)) { + return Optional.of(o); + } + } + return Optional.empty(); + } +} + diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequest.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequest.java new file mode 100644 index 0000000..116e4f7 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequest.java @@ -0,0 +1,138 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import jakarta.annotation.Nonnull; +import java.util.Optional; +import io.fastpix.sdk.utils.FastpixMetadata; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamDomainRestrictionsRequest { + + private static final String MEDIA_ID = "streamId"; + private static final String PLAYBACK_ID = "playbackId"; + private static final String BODY_NAME = "body"; + + @FastpixMetadata("pathParam:style=simple,explode=false,name=streamId") + private String streamId; + + + @FastpixMetadata("pathParam:style=simple,explode=false,name=playbackId") + private String playbackId; + + + @FastpixMetadata("request:mediaType=application/json") + private UpdateLiveStreamDomainRestrictionsRequestBody body; + + @JsonCreator + public UpdateLiveStreamDomainRestrictionsRequest( + @Nonnull String streamId, + @Nonnull String playbackId, + @Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body) { + this.streamId = Optional.ofNullable(streamId) + .orElseThrow(() -> new IllegalArgumentException("streamId cannot be null")); + this.playbackId = Optional.ofNullable(playbackId) + .orElseThrow(() -> new IllegalArgumentException("playbackId cannot be null")); + this.body = Optional.ofNullable(body) + .orElseThrow(() -> new IllegalArgumentException("body cannot be null")); + } + + public String streamId() { + return this.streamId; + } + + public String playbackId() { + return this.playbackId; + } + + public UpdateLiveStreamDomainRestrictionsRequestBody body() { + return this.body; + } + + public static Builder builder() { + return new Builder(); + } + + + public UpdateLiveStreamDomainRestrictionsRequest withStreamId(@Nonnull String streamId) { + this.streamId = Utils.checkNotNull(streamId, MEDIA_ID); + return this; + } + + + public UpdateLiveStreamDomainRestrictionsRequest withPlaybackId(@Nonnull String playbackId) { + this.playbackId = Utils.checkNotNull(playbackId, PLAYBACK_ID); + return this; + } + + + public UpdateLiveStreamDomainRestrictionsRequest withBody(@Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body) { + this.body = Utils.checkNotNull(body, BODY_NAME); + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamDomainRestrictionsRequest other = (UpdateLiveStreamDomainRestrictionsRequest) o; + return + Utils.enhancedDeepEquals(this.streamId, other.streamId) && + Utils.enhancedDeepEquals(this.playbackId, other.playbackId) && + Utils.enhancedDeepEquals(this.body, other.body); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + streamId, playbackId, body); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamDomainRestrictionsRequest.class, + MEDIA_ID, streamId, + PLAYBACK_ID, playbackId, + BODY_NAME, body); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String streamId; + + private String playbackId; + + private UpdateLiveStreamDomainRestrictionsRequestBody body; + + private Builder() { + // force use of static builder() method + } + + public Builder streamId(@Nonnull String streamId) { + this.streamId = Utils.checkNotNull(streamId, MEDIA_ID); + return this; + } + + public Builder playbackId(@Nonnull String playbackId) { + this.playbackId = Utils.checkNotNull(playbackId, PLAYBACK_ID); + return this; + } + + public Builder body(@Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body) { + this.body = Utils.checkNotNull(body, BODY_NAME); + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequest build() { + return new UpdateLiveStreamDomainRestrictionsRequest( + streamId, playbackId, body); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.java new file mode 100644 index 0000000..8b87c84 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequestBody.java @@ -0,0 +1,183 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import io.fastpix.sdk.utils.LazySingletonValue; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamDomainRestrictionsRequestBody { + /** + * Specify the fallback behavior for domains that are not listed in the `allow` or `deny` lists. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("defaultPolicy") + private UpdateLiveStreamDomainRestrictionsDefaultPolicy defaultPolicy; + + /** + * List of domains explicitly allowed to play the media. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("allow") + private List allow; + + /** + * List of domains explicitly denied from accessing the media. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("deny") + private List deny; + + @JsonCreator + public UpdateLiveStreamDomainRestrictionsRequestBody( + @JsonProperty("defaultPolicy") @Nullable UpdateLiveStreamDomainRestrictionsDefaultPolicy defaultPolicy, + @JsonProperty("allow") @Nullable List allow, + @JsonProperty("deny") @Nullable List deny) { + this.defaultPolicy = Optional.ofNullable(defaultPolicy) + .orElse(Builder._SINGLETON_VALUE_DefaultPolicy.value()); + this.allow = allow; + this.deny = deny; + } + + public UpdateLiveStreamDomainRestrictionsRequestBody() { + this(null, null, null); + } + + /** + * Specify the fallback behavior for domains that are not listed in the `allow` or `deny` lists. + */ + public Optional defaultPolicy() { + return Optional.ofNullable(this.defaultPolicy); + } + + /** + * List of domains explicitly allowed to play the media. + */ + public Optional> allow() { + return Optional.ofNullable(this.allow); + } + + /** + * List of domains explicitly denied from accessing the media. + */ + public Optional> deny() { + return Optional.ofNullable(this.deny); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * Specify the fallback behavior for domains that are not listed in the `allow` or `deny` lists. + */ + public UpdateLiveStreamDomainRestrictionsRequestBody withDefaultPolicy(@Nullable UpdateLiveStreamDomainRestrictionsDefaultPolicy defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + + /** + * List of domains explicitly allowed to play the media. + */ + public UpdateLiveStreamDomainRestrictionsRequestBody withAllow(@Nullable List allow) { + this.allow = allow; + return this; + } + + + /** + * List of domains explicitly denied from accessing the media. + */ + public UpdateLiveStreamDomainRestrictionsRequestBody withDeny(@Nullable List deny) { + this.deny = deny; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamDomainRestrictionsRequestBody other = (UpdateLiveStreamDomainRestrictionsRequestBody) o; + return + Utils.enhancedDeepEquals(this.defaultPolicy, other.defaultPolicy) && + Utils.enhancedDeepEquals(this.allow, other.allow) && + Utils.enhancedDeepEquals(this.deny, other.deny); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + defaultPolicy, allow, deny); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamDomainRestrictionsRequestBody.class, + "defaultPolicy", defaultPolicy, + "allow", allow, + "deny", deny); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private UpdateLiveStreamDomainRestrictionsDefaultPolicy defaultPolicy; + + private List allow; + + private List deny; + + private Builder() { + // force use of static builder() method + } + + /** + * Specify the fallback behavior for domains that are not listed in the `allow` or `deny` lists. + */ + public Builder defaultPolicy(@Nullable UpdateLiveStreamDomainRestrictionsDefaultPolicy defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + /** + * List of domains explicitly allowed to play the media. + */ + public Builder allow(@Nullable List allow) { + this.allow = allow; + return this; + } + + /** + * List of domains explicitly denied from accessing the media. + */ + public Builder deny(@Nullable List deny) { + this.deny = deny; + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequestBody build() { + return new UpdateLiveStreamDomainRestrictionsRequestBody( + defaultPolicy, allow, deny); + } + + + private static final LazySingletonValue _SINGLETON_VALUE_DefaultPolicy = + new LazySingletonValue<>( + "defaultPolicy", + "\"allow\"", + new TypeReference() {}); + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequestBuilder.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequestBuilder.java new file mode 100644 index 0000000..5af3a29 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsRequestBuilder.java @@ -0,0 +1,80 @@ +package io.fastpix.sdk.models.operations; + +import static io.fastpix.sdk.operations.Operations.RequestOperation; + +import jakarta.annotation.Nonnull; +import io.fastpix.sdk.SDKConfiguration; +import io.fastpix.sdk.operations.UpdateLiveStreamDomainRestrictions; +import io.fastpix.sdk.utils.Headers; +import io.fastpix.sdk.utils.Options; +import io.fastpix.sdk.utils.RetryConfig; +import io.fastpix.sdk.utils.Utils; + +// Leading-underscore field/method names (_headers, _setterCalled, _buildRequest) are an +// intentional generated convention that avoids clashing with the user-facing builder +// setters (header(), body(), ...); renaming would be inconsistent across all +// *RequestBuilder classes and could reintroduce those clashes. +@SuppressWarnings({"java:S116", "java:S100"}) +public class UpdateLiveStreamDomainRestrictionsRequestBuilder { + private final SDKConfiguration sdkConfiguration; + private final Headers _headers = new Headers(); + private final UpdateLiveStreamDomainRestrictionsRequest.Builder pojoBuilder; + private UpdateLiveStreamDomainRestrictionsRequest request; + private final Options.Builder optionsBuilder; + private boolean _setterCalled; + + public UpdateLiveStreamDomainRestrictionsRequestBuilder(SDKConfiguration sdkConfiguration) { + this.sdkConfiguration = sdkConfiguration; + this.pojoBuilder = UpdateLiveStreamDomainRestrictionsRequest.builder(); + this.optionsBuilder = Options.builder(); + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder streamId(@Nonnull String streamId) { + this.pojoBuilder.streamId(streamId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder playbackId(@Nonnull String playbackId) { + this.pojoBuilder.playbackId(playbackId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder body(@Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body) { + this.pojoBuilder.body(body); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder retryConfig(RetryConfig retryConfig) { + this.optionsBuilder.retryConfig(retryConfig); + return this; + } + + private UpdateLiveStreamDomainRestrictionsRequest _buildRequest() { + if (this._setterCalled) { + this.request = this.pojoBuilder.build(); + } + return this.request; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder header(String name, String value) { + Utils.checkNotNull(name, "name"); + Utils.checkNotNull(value, "value"); + this._headers.add(name, value); + return this; + } + + /** + * Executes the request and returns the response. + * + * @return The response from the server. + */ + public UpdateLiveStreamDomainRestrictionsResponse call() { + Options options = optionsBuilder.build(); + RequestOperation operation + = new UpdateLiveStreamDomainRestrictions.Sync(sdkConfiguration, options, _headers); + return operation.handleResponse(operation.doRequest(this._buildRequest())); + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsResponse.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsResponse.java new file mode 100644 index 0000000..7c937ef --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsResponse.java @@ -0,0 +1,254 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import java.io.InputStream; +import java.net.http.HttpResponse; +import java.util.Optional; +import io.fastpix.sdk.models.components.DefaultError; +import io.fastpix.sdk.utils.Response; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamDomainRestrictionsResponse implements Response { + + private static final String CONTENT_TYPE = "contentType"; + private static final String RAW_RESPONSE = "rawResponse"; + /** + * HTTP response content type for this operation + */ + private String contentType; + + /** + * HTTP response status code for this operation + */ + private int statusCode; + + /** + * Raw HTTP response; suitable for custom response parsing + */ + private HttpResponse rawResponse; + + /** + * Successfully updated domain restrictions + */ + private UpdateLiveStreamDomainRestrictionsResponseBody object; + + /** + * See the range of possible error + * responses and their status codes. + */ + private DefaultError defaultError; + + @JsonCreator + public UpdateLiveStreamDomainRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse, + @Nullable UpdateLiveStreamDomainRestrictionsResponseBody object, + @Nullable DefaultError defaultError) { + this.contentType = Optional.ofNullable(contentType) + .orElseThrow(() -> new IllegalArgumentException("contentType cannot be null")); + this.statusCode = statusCode; + this.rawResponse = Optional.ofNullable(rawResponse) + .orElseThrow(() -> new IllegalArgumentException("rawResponse cannot be null")); + this.object = object; + this.defaultError = defaultError; + } + + public UpdateLiveStreamDomainRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse) { + this(contentType, statusCode, rawResponse, + null, null); + } + + /** + * HTTP response content type for this operation + */ + public String contentType() { + return this.contentType; + } + + /** + * HTTP response status code for this operation + */ + public int statusCode() { + return this.statusCode; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public HttpResponse rawResponse() { + return this.rawResponse; + } + + /** + * Successfully updated domain restrictions + */ + public Optional object() { + return Optional.ofNullable(this.object); + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Optional defaultError() { + return Optional.ofNullable(this.defaultError); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * HTTP response content type for this operation + */ + public UpdateLiveStreamDomainRestrictionsResponse withContentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + + /** + * HTTP response status code for this operation + */ + public UpdateLiveStreamDomainRestrictionsResponse withStatusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public UpdateLiveStreamDomainRestrictionsResponse withRawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + + /** + * Successfully updated domain restrictions + */ + public UpdateLiveStreamDomainRestrictionsResponse withObject(@Nullable UpdateLiveStreamDomainRestrictionsResponseBody object) { + this.object = object; + return this; + } + + + /** + * See the range of possible error + * responses and their status codes. + */ + public UpdateLiveStreamDomainRestrictionsResponse withDefaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamDomainRestrictionsResponse other = (UpdateLiveStreamDomainRestrictionsResponse) o; + return + Utils.enhancedDeepEquals(this.contentType, other.contentType) && + Utils.enhancedDeepEquals(this.statusCode, other.statusCode) && + Utils.enhancedDeepEquals(this.rawResponse, other.rawResponse) && + Utils.enhancedDeepEquals(this.object, other.object) && + Utils.enhancedDeepEquals(this.defaultError, other.defaultError); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + contentType, statusCode, rawResponse, + object, defaultError); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamDomainRestrictionsResponse.class, + CONTENT_TYPE, contentType, + "statusCode", statusCode, + RAW_RESPONSE, rawResponse, + "object", object, + "defaultError", defaultError); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String contentType; + + private int statusCode; + + private HttpResponse rawResponse; + + private UpdateLiveStreamDomainRestrictionsResponseBody object; + + private DefaultError defaultError; + + private Builder() { + // force use of static builder() method + } + + /** + * HTTP response content type for this operation + */ + public Builder contentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + /** + * HTTP response status code for this operation + */ + public Builder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public Builder rawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + /** + * Successfully updated domain restrictions + */ + public Builder object(@Nullable UpdateLiveStreamDomainRestrictionsResponseBody object) { + this.object = object; + return this; + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Builder defaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + public UpdateLiveStreamDomainRestrictionsResponse build() { + return new UpdateLiveStreamDomainRestrictionsResponse( + contentType, statusCode, rawResponse, + object, defaultError); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsResponseBody.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsResponseBody.java new file mode 100644 index 0000000..c6207c9 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamDomainRestrictionsResponseBody.java @@ -0,0 +1,129 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.annotation.Nullable; +import java.util.Optional; +import io.fastpix.sdk.utils.Utils; + +/** + * UpdateLiveStreamDomainRestrictionsResponseBody + * + *

Successfully updated domain restrictions + */ +public class UpdateLiveStreamDomainRestrictionsResponseBody { + /** + * Shows the request status. Returns true for success and false for failure. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("success") + private Boolean success; + + + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("data") + private UpdateLiveStreamDomainRestrictionsData data; + + @JsonCreator + public UpdateLiveStreamDomainRestrictionsResponseBody( + @JsonProperty("success") @Nullable Boolean success, + @JsonProperty("data") @Nullable UpdateLiveStreamDomainRestrictionsData data) { + this.success = success; + this.data = data; + } + + public UpdateLiveStreamDomainRestrictionsResponseBody() { + this(null, null); + } + + /** + * Shows the request status. Returns true for success and false for failure. + */ + public Optional success() { + return Optional.ofNullable(this.success); + } + + public Optional data() { + return Optional.ofNullable(this.data); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * Shows the request status. Returns true for success and false for failure. + */ + public UpdateLiveStreamDomainRestrictionsResponseBody withSuccess(@Nullable Boolean success) { + this.success = success; + return this; + } + + + public UpdateLiveStreamDomainRestrictionsResponseBody withData(@Nullable UpdateLiveStreamDomainRestrictionsData data) { + this.data = data; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamDomainRestrictionsResponseBody other = (UpdateLiveStreamDomainRestrictionsResponseBody) o; + return + Utils.enhancedDeepEquals(this.success, other.success) && + Utils.enhancedDeepEquals(this.data, other.data); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + success, data); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamDomainRestrictionsResponseBody.class, + "success", success, + "data", data); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private Boolean success; + + private UpdateLiveStreamDomainRestrictionsData data; + + private Builder() { + // force use of static builder() method + } + + /** + * Shows the request status. Returns true for success and false for failure. + */ + public Builder success(@Nullable Boolean success) { + this.success = success; + return this; + } + + public Builder data(@Nullable UpdateLiveStreamDomainRestrictionsData data) { + this.data = data; + return this; + } + + public UpdateLiveStreamDomainRestrictionsResponseBody build() { + return new UpdateLiveStreamDomainRestrictionsResponseBody( + success, data); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsData.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsData.java new file mode 100644 index 0000000..2373b3f --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsData.java @@ -0,0 +1,174 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamUserAgentRestrictionsData { + /** + * Specifies the default behavior for user agents not listed in the allow or deny lists. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("defaultPolicy") + private String defaultPolicy; + + /** + * List of user-agent substrings explicitly allowed. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("allow") + private List allow; + + /** + * List of user-agent substrings explicitly denied. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("deny") + private List deny; + + @JsonCreator + public UpdateLiveStreamUserAgentRestrictionsData( + @JsonProperty("defaultPolicy") @Nullable String defaultPolicy, + @JsonProperty("allow") @Nullable List allow, + @JsonProperty("deny") @Nullable List deny) { + this.defaultPolicy = defaultPolicy; + this.allow = allow; + this.deny = deny; + } + + public UpdateLiveStreamUserAgentRestrictionsData() { + this(null, null, null); + } + + /** + * Specifies the default behavior for user agents not listed in the allow or deny lists. + */ + public Optional defaultPolicy() { + return Optional.ofNullable(this.defaultPolicy); + } + + /** + * List of user-agent substrings explicitly allowed. + */ + public Optional> allow() { + return Optional.ofNullable(this.allow); + } + + /** + * List of user-agent substrings explicitly denied. + */ + public Optional> deny() { + return Optional.ofNullable(this.deny); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * Specifies the default behavior for user agents not listed in the allow or deny lists. + */ + public UpdateLiveStreamUserAgentRestrictionsData withDefaultPolicy(@Nullable String defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + + /** + * List of user-agent substrings explicitly allowed. + */ + public UpdateLiveStreamUserAgentRestrictionsData withAllow(@Nullable List allow) { + this.allow = allow; + return this; + } + + + /** + * List of user-agent substrings explicitly denied. + */ + public UpdateLiveStreamUserAgentRestrictionsData withDeny(@Nullable List deny) { + this.deny = deny; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamUserAgentRestrictionsData other = (UpdateLiveStreamUserAgentRestrictionsData) o; + return + Utils.enhancedDeepEquals(this.defaultPolicy, other.defaultPolicy) && + Utils.enhancedDeepEquals(this.allow, other.allow) && + Utils.enhancedDeepEquals(this.deny, other.deny); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + defaultPolicy, allow, deny); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamUserAgentRestrictionsData.class, + "defaultPolicy", defaultPolicy, + "allow", allow, + "deny", deny); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String defaultPolicy; + + private List allow; + + private List deny; + + private Builder() { + // force use of static builder() method + } + + /** + * Specifies the default behavior for user agents not listed in the allow or deny lists. + */ + public Builder defaultPolicy(@Nullable String defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + /** + * List of user-agent substrings explicitly allowed. + */ + public Builder allow(@Nullable List allow) { + this.allow = allow; + return this; + } + + /** + * List of user-agent substrings explicitly denied. + */ + public Builder deny(@Nullable List deny) { + this.deny = deny; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsData build() { + return new UpdateLiveStreamUserAgentRestrictionsData( + defaultPolicy, allow, deny); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.java new file mode 100644 index 0000000..5cfc2c7 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.java @@ -0,0 +1,36 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Objects; +import java.util.Optional; + +/** + * UpdateLiveStreamUserAgentRestrictionsDefaultPolicy + * + *

The default behavior when a user-agent is not listed in `allow` or `deny`. + */ +public enum UpdateLiveStreamUserAgentRestrictionsDefaultPolicy { + ALLOW("allow"), + DENY("deny"); + + @JsonValue + private final String value; + + UpdateLiveStreamUserAgentRestrictionsDefaultPolicy(String value) { + this.value = value; + } + + public String value() { + return value; + } + + public static Optional fromValue(String value) { + for (UpdateLiveStreamUserAgentRestrictionsDefaultPolicy o: UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.values()) { + if (Objects.deepEquals(o.value, value)) { + return Optional.of(o); + } + } + return Optional.empty(); + } +} + diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequest.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequest.java new file mode 100644 index 0000000..1e864fc --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequest.java @@ -0,0 +1,138 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import jakarta.annotation.Nonnull; +import java.util.Optional; +import io.fastpix.sdk.utils.FastpixMetadata; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamUserAgentRestrictionsRequest { + + private static final String MEDIA_ID = "streamId"; + private static final String PLAYBACK_ID = "playbackId"; + private static final String BODY_NAME = "body"; + + @FastpixMetadata("pathParam:style=simple,explode=false,name=streamId") + private String streamId; + + + @FastpixMetadata("pathParam:style=simple,explode=false,name=playbackId") + private String playbackId; + + + @FastpixMetadata("request:mediaType=application/json") + private UpdateLiveStreamUserAgentRestrictionsRequestBody body; + + @JsonCreator + public UpdateLiveStreamUserAgentRestrictionsRequest( + @Nonnull String streamId, + @Nonnull String playbackId, + @Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body) { + this.streamId = Optional.ofNullable(streamId) + .orElseThrow(() -> new IllegalArgumentException("streamId cannot be null")); + this.playbackId = Optional.ofNullable(playbackId) + .orElseThrow(() -> new IllegalArgumentException("playbackId cannot be null")); + this.body = Optional.ofNullable(body) + .orElseThrow(() -> new IllegalArgumentException("body cannot be null")); + } + + public String streamId() { + return this.streamId; + } + + public String playbackId() { + return this.playbackId; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBody body() { + return this.body; + } + + public static Builder builder() { + return new Builder(); + } + + + public UpdateLiveStreamUserAgentRestrictionsRequest withStreamId(@Nonnull String streamId) { + this.streamId = Utils.checkNotNull(streamId, MEDIA_ID); + return this; + } + + + public UpdateLiveStreamUserAgentRestrictionsRequest withPlaybackId(@Nonnull String playbackId) { + this.playbackId = Utils.checkNotNull(playbackId, PLAYBACK_ID); + return this; + } + + + public UpdateLiveStreamUserAgentRestrictionsRequest withBody(@Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body) { + this.body = Utils.checkNotNull(body, BODY_NAME); + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamUserAgentRestrictionsRequest other = (UpdateLiveStreamUserAgentRestrictionsRequest) o; + return + Utils.enhancedDeepEquals(this.streamId, other.streamId) && + Utils.enhancedDeepEquals(this.playbackId, other.playbackId) && + Utils.enhancedDeepEquals(this.body, other.body); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + streamId, playbackId, body); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamUserAgentRestrictionsRequest.class, + MEDIA_ID, streamId, + PLAYBACK_ID, playbackId, + BODY_NAME, body); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String streamId; + + private String playbackId; + + private UpdateLiveStreamUserAgentRestrictionsRequestBody body; + + private Builder() { + // force use of static builder() method + } + + public Builder streamId(@Nonnull String streamId) { + this.streamId = Utils.checkNotNull(streamId, MEDIA_ID); + return this; + } + + public Builder playbackId(@Nonnull String playbackId) { + this.playbackId = Utils.checkNotNull(playbackId, PLAYBACK_ID); + return this; + } + + public Builder body(@Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body) { + this.body = Utils.checkNotNull(body, BODY_NAME); + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequest build() { + return new UpdateLiveStreamUserAgentRestrictionsRequest( + streamId, playbackId, body); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.java new file mode 100644 index 0000000..14f7720 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBody.java @@ -0,0 +1,183 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import io.fastpix.sdk.utils.LazySingletonValue; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamUserAgentRestrictionsRequestBody { + /** + * The default behavior when a user-agent is not listed in `allow` or `deny`. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("defaultPolicy") + private UpdateLiveStreamUserAgentRestrictionsDefaultPolicy defaultPolicy; + + /** + * List of user-agent substrings explicitly allowed. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("allow") + private List allow; + + /** + * List of user-agent substrings explicitly denied. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("deny") + private List deny; + + @JsonCreator + public UpdateLiveStreamUserAgentRestrictionsRequestBody( + @JsonProperty("defaultPolicy") @Nullable UpdateLiveStreamUserAgentRestrictionsDefaultPolicy defaultPolicy, + @JsonProperty("allow") @Nullable List allow, + @JsonProperty("deny") @Nullable List deny) { + this.defaultPolicy = Optional.ofNullable(defaultPolicy) + .orElse(Builder._SINGLETON_VALUE_DefaultPolicy.value()); + this.allow = allow; + this.deny = deny; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBody() { + this(null, null, null); + } + + /** + * The default behavior when a user-agent is not listed in `allow` or `deny`. + */ + public Optional defaultPolicy() { + return Optional.ofNullable(this.defaultPolicy); + } + + /** + * List of user-agent substrings explicitly allowed. + */ + public Optional> allow() { + return Optional.ofNullable(this.allow); + } + + /** + * List of user-agent substrings explicitly denied. + */ + public Optional> deny() { + return Optional.ofNullable(this.deny); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * The default behavior when a user-agent is not listed in `allow` or `deny`. + */ + public UpdateLiveStreamUserAgentRestrictionsRequestBody withDefaultPolicy(@Nullable UpdateLiveStreamUserAgentRestrictionsDefaultPolicy defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + + /** + * List of user-agent substrings explicitly allowed. + */ + public UpdateLiveStreamUserAgentRestrictionsRequestBody withAllow(@Nullable List allow) { + this.allow = allow; + return this; + } + + + /** + * List of user-agent substrings explicitly denied. + */ + public UpdateLiveStreamUserAgentRestrictionsRequestBody withDeny(@Nullable List deny) { + this.deny = deny; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamUserAgentRestrictionsRequestBody other = (UpdateLiveStreamUserAgentRestrictionsRequestBody) o; + return + Utils.enhancedDeepEquals(this.defaultPolicy, other.defaultPolicy) && + Utils.enhancedDeepEquals(this.allow, other.allow) && + Utils.enhancedDeepEquals(this.deny, other.deny); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + defaultPolicy, allow, deny); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamUserAgentRestrictionsRequestBody.class, + "defaultPolicy", defaultPolicy, + "allow", allow, + "deny", deny); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private UpdateLiveStreamUserAgentRestrictionsDefaultPolicy defaultPolicy; + + private List allow; + + private List deny; + + private Builder() { + // force use of static builder() method + } + + /** + * The default behavior when a user-agent is not listed in `allow` or `deny`. + */ + public Builder defaultPolicy(@Nullable UpdateLiveStreamUserAgentRestrictionsDefaultPolicy defaultPolicy) { + this.defaultPolicy = defaultPolicy; + return this; + } + + /** + * List of user-agent substrings explicitly allowed. + */ + public Builder allow(@Nullable List allow) { + this.allow = allow; + return this; + } + + /** + * List of user-agent substrings explicitly denied. + */ + public Builder deny(@Nullable List deny) { + this.deny = deny; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBody build() { + return new UpdateLiveStreamUserAgentRestrictionsRequestBody( + defaultPolicy, allow, deny); + } + + + private static final LazySingletonValue _SINGLETON_VALUE_DefaultPolicy = + new LazySingletonValue<>( + "defaultPolicy", + "\"allow\"", + new TypeReference() {}); + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBuilder.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBuilder.java new file mode 100644 index 0000000..6e3df22 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsRequestBuilder.java @@ -0,0 +1,80 @@ +package io.fastpix.sdk.models.operations; + +import static io.fastpix.sdk.operations.Operations.RequestOperation; + +import jakarta.annotation.Nonnull; +import io.fastpix.sdk.SDKConfiguration; +import io.fastpix.sdk.operations.UpdateLiveStreamUserAgentRestrictions; +import io.fastpix.sdk.utils.Headers; +import io.fastpix.sdk.utils.Options; +import io.fastpix.sdk.utils.RetryConfig; +import io.fastpix.sdk.utils.Utils; + +// Leading-underscore field/method names (_headers, _setterCalled, _buildRequest) are an +// intentional generated convention that avoids clashing with the user-facing builder +// setters (header(), body(), ...); renaming would be inconsistent across all +// *RequestBuilder classes and could reintroduce those clashes. +@SuppressWarnings({"java:S116", "java:S100"}) +public class UpdateLiveStreamUserAgentRestrictionsRequestBuilder { + private final SDKConfiguration sdkConfiguration; + private final Headers _headers = new Headers(); + private final UpdateLiveStreamUserAgentRestrictionsRequest.Builder pojoBuilder; + private UpdateLiveStreamUserAgentRestrictionsRequest request; + private final Options.Builder optionsBuilder; + private boolean _setterCalled; + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder(SDKConfiguration sdkConfiguration) { + this.sdkConfiguration = sdkConfiguration; + this.pojoBuilder = UpdateLiveStreamUserAgentRestrictionsRequest.builder(); + this.optionsBuilder = Options.builder(); + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder streamId(@Nonnull String streamId) { + this.pojoBuilder.streamId(streamId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder playbackId(@Nonnull String playbackId) { + this.pojoBuilder.playbackId(playbackId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder body(@Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body) { + this.pojoBuilder.body(body); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder retryConfig(RetryConfig retryConfig) { + this.optionsBuilder.retryConfig(retryConfig); + return this; + } + + private UpdateLiveStreamUserAgentRestrictionsRequest _buildRequest() { + if (this._setterCalled) { + this.request = this.pojoBuilder.build(); + } + return this.request; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder header(String name, String value) { + Utils.checkNotNull(name, "name"); + Utils.checkNotNull(value, "value"); + this._headers.add(name, value); + return this; + } + + /** + * Executes the request and returns the response. + * + * @return The response from the server. + */ + public UpdateLiveStreamUserAgentRestrictionsResponse call() { + Options options = optionsBuilder.build(); + RequestOperation operation + = new UpdateLiveStreamUserAgentRestrictions.Sync(sdkConfiguration, options, _headers); + return operation.handleResponse(operation.doRequest(this._buildRequest())); + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsResponse.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsResponse.java new file mode 100644 index 0000000..faa064b --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsResponse.java @@ -0,0 +1,254 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import java.io.InputStream; +import java.net.http.HttpResponse; +import java.util.Optional; +import io.fastpix.sdk.models.components.DefaultError; +import io.fastpix.sdk.utils.Response; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamUserAgentRestrictionsResponse implements Response { + + private static final String CONTENT_TYPE = "contentType"; + private static final String RAW_RESPONSE = "rawResponse"; + /** + * HTTP response content type for this operation + */ + private String contentType; + + /** + * HTTP response status code for this operation + */ + private int statusCode; + + /** + * Raw HTTP response; suitable for custom response parsing + */ + private HttpResponse rawResponse; + + /** + * Successfully updated user-agent restrictions + */ + private UpdateLiveStreamUserAgentRestrictionsResponseBody object; + + /** + * See the range of possible error + * responses and their status codes. + */ + private DefaultError defaultError; + + @JsonCreator + public UpdateLiveStreamUserAgentRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse, + @Nullable UpdateLiveStreamUserAgentRestrictionsResponseBody object, + @Nullable DefaultError defaultError) { + this.contentType = Optional.ofNullable(contentType) + .orElseThrow(() -> new IllegalArgumentException("contentType cannot be null")); + this.statusCode = statusCode; + this.rawResponse = Optional.ofNullable(rawResponse) + .orElseThrow(() -> new IllegalArgumentException("rawResponse cannot be null")); + this.object = object; + this.defaultError = defaultError; + } + + public UpdateLiveStreamUserAgentRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse) { + this(contentType, statusCode, rawResponse, + null, null); + } + + /** + * HTTP response content type for this operation + */ + public String contentType() { + return this.contentType; + } + + /** + * HTTP response status code for this operation + */ + public int statusCode() { + return this.statusCode; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public HttpResponse rawResponse() { + return this.rawResponse; + } + + /** + * Successfully updated user-agent restrictions + */ + public Optional object() { + return Optional.ofNullable(this.object); + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Optional defaultError() { + return Optional.ofNullable(this.defaultError); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * HTTP response content type for this operation + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withContentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + + /** + * HTTP response status code for this operation + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withStatusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withRawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + + /** + * Successfully updated user-agent restrictions + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withObject(@Nullable UpdateLiveStreamUserAgentRestrictionsResponseBody object) { + this.object = object; + return this; + } + + + /** + * See the range of possible error + * responses and their status codes. + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withDefaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamUserAgentRestrictionsResponse other = (UpdateLiveStreamUserAgentRestrictionsResponse) o; + return + Utils.enhancedDeepEquals(this.contentType, other.contentType) && + Utils.enhancedDeepEquals(this.statusCode, other.statusCode) && + Utils.enhancedDeepEquals(this.rawResponse, other.rawResponse) && + Utils.enhancedDeepEquals(this.object, other.object) && + Utils.enhancedDeepEquals(this.defaultError, other.defaultError); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + contentType, statusCode, rawResponse, + object, defaultError); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamUserAgentRestrictionsResponse.class, + CONTENT_TYPE, contentType, + "statusCode", statusCode, + RAW_RESPONSE, rawResponse, + "object", object, + "defaultError", defaultError); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String contentType; + + private int statusCode; + + private HttpResponse rawResponse; + + private UpdateLiveStreamUserAgentRestrictionsResponseBody object; + + private DefaultError defaultError; + + private Builder() { + // force use of static builder() method + } + + /** + * HTTP response content type for this operation + */ + public Builder contentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + /** + * HTTP response status code for this operation + */ + public Builder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public Builder rawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + /** + * Successfully updated user-agent restrictions + */ + public Builder object(@Nullable UpdateLiveStreamUserAgentRestrictionsResponseBody object) { + this.object = object; + return this; + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Builder defaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsResponse build() { + return new UpdateLiveStreamUserAgentRestrictionsResponse( + contentType, statusCode, rawResponse, + object, defaultError); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsResponseBody.java b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsResponseBody.java new file mode 100644 index 0000000..160f4b6 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/UpdateLiveStreamUserAgentRestrictionsResponseBody.java @@ -0,0 +1,129 @@ +package io.fastpix.sdk.models.operations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.annotation.Nullable; +import java.util.Optional; +import io.fastpix.sdk.utils.Utils; + +/** + * UpdateLiveStreamUserAgentRestrictionsResponseBody + * + *

Successfully updated user-agent restrictions + */ +public class UpdateLiveStreamUserAgentRestrictionsResponseBody { + /** + * Shows the request status. Returns true for success and false for failure. + */ + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("success") + private Boolean success; + + + @JsonInclude(Include.NON_ABSENT) + @JsonProperty("data") + private UpdateLiveStreamUserAgentRestrictionsData data; + + @JsonCreator + public UpdateLiveStreamUserAgentRestrictionsResponseBody( + @JsonProperty("success") @Nullable Boolean success, + @JsonProperty("data") @Nullable UpdateLiveStreamUserAgentRestrictionsData data) { + this.success = success; + this.data = data; + } + + public UpdateLiveStreamUserAgentRestrictionsResponseBody() { + this(null, null); + } + + /** + * Shows the request status. Returns true for success and false for failure. + */ + public Optional success() { + return Optional.ofNullable(this.success); + } + + public Optional data() { + return Optional.ofNullable(this.data); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * Shows the request status. Returns true for success and false for failure. + */ + public UpdateLiveStreamUserAgentRestrictionsResponseBody withSuccess(@Nullable Boolean success) { + this.success = success; + return this; + } + + + public UpdateLiveStreamUserAgentRestrictionsResponseBody withData(@Nullable UpdateLiveStreamUserAgentRestrictionsData data) { + this.data = data; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamUserAgentRestrictionsResponseBody other = (UpdateLiveStreamUserAgentRestrictionsResponseBody) o; + return + Utils.enhancedDeepEquals(this.success, other.success) && + Utils.enhancedDeepEquals(this.data, other.data); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + success, data); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamUserAgentRestrictionsResponseBody.class, + "success", success, + "data", data); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private Boolean success; + + private UpdateLiveStreamUserAgentRestrictionsData data; + + private Builder() { + // force use of static builder() method + } + + /** + * Shows the request status. Returns true for success and false for failure. + */ + public Builder success(@Nullable Boolean success) { + this.success = success; + return this; + } + + public Builder data(@Nullable UpdateLiveStreamUserAgentRestrictionsData data) { + this.data = data; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsResponseBody build() { + return new UpdateLiveStreamUserAgentRestrictionsResponseBody( + success, data); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamDomainRestrictionsRequestBuilder.java b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamDomainRestrictionsRequestBuilder.java new file mode 100644 index 0000000..844053e --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamDomainRestrictionsRequestBuilder.java @@ -0,0 +1,86 @@ +package io.fastpix.sdk.models.operations.async; + +import static io.fastpix.sdk.operations.Operations.AsyncRequestOperation; + +import jakarta.annotation.Nonnull; +import java.util.concurrent.CompletableFuture; +import io.fastpix.sdk.SDKConfiguration; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; +import io.fastpix.sdk.operations.UpdateLiveStreamDomainRestrictions; +import io.fastpix.sdk.utils.Headers; +import io.fastpix.sdk.utils.Options; +import io.fastpix.sdk.utils.RetryConfig; +import io.fastpix.sdk.utils.Utils; + +// Leading-underscore field/method names (_headers, _setterCalled, _buildRequest) are an +// intentional generated convention that avoids clashing with the user-facing builder +// setters (header(), body(), ...); renaming would be inconsistent across all +// *RequestBuilder classes and could reintroduce those clashes. +@SuppressWarnings({"java:S116", "java:S100"}) +public class UpdateLiveStreamDomainRestrictionsRequestBuilder { + private final SDKConfiguration sdkConfiguration; + private final Headers _headers = new Headers(); + private final UpdateLiveStreamDomainRestrictionsRequest.Builder pojoBuilder; + private UpdateLiveStreamDomainRestrictionsRequest request; + private final Options.Builder optionsBuilder; + private boolean _setterCalled; + + public UpdateLiveStreamDomainRestrictionsRequestBuilder(SDKConfiguration sdkConfiguration) { + this.sdkConfiguration = sdkConfiguration; + this.pojoBuilder = UpdateLiveStreamDomainRestrictionsRequest.builder(); + this.optionsBuilder = Options.builder(); + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder streamId(@Nonnull String streamId) { + this.pojoBuilder.streamId(streamId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder playbackId(@Nonnull String playbackId) { + this.pojoBuilder.playbackId(playbackId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder body(@Nonnull UpdateLiveStreamDomainRestrictionsRequestBody body) { + this.pojoBuilder.body(body); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder retryConfig(RetryConfig retryConfig) { + this.optionsBuilder.retryConfig(retryConfig); + return this; + } + + private UpdateLiveStreamDomainRestrictionsRequest _buildRequest() { + if (this._setterCalled) { + this.request = this.pojoBuilder.build(); + } + return this.request; + } + + public UpdateLiveStreamDomainRestrictionsRequestBuilder header(String name, String value) { + Utils.checkNotNull(name, "name"); + Utils.checkNotNull(value, "value"); + this._headers.add(name, value); + return this; + } + + /** + * Executes the request and returns the response. + * + * @return The response from the server. + */ + public CompletableFuture call() { + Options options = optionsBuilder.build(); + AsyncRequestOperation operation + = new UpdateLiveStreamDomainRestrictions.Async( + sdkConfiguration, options, sdkConfiguration.retryScheduler(), + _headers); + return operation.doRequest(this._buildRequest()) + .thenCompose(operation::handleResponse); + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamDomainRestrictionsResponse.java b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamDomainRestrictionsResponse.java new file mode 100644 index 0000000..0944946 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamDomainRestrictionsResponse.java @@ -0,0 +1,255 @@ +package io.fastpix.sdk.models.operations.async; + +import com.fasterxml.jackson.annotation.JsonCreator; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import java.net.http.HttpResponse; +import java.util.Optional; +import io.fastpix.sdk.models.components.DefaultError; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsResponseBody; +import io.fastpix.sdk.utils.AsyncResponse; +import io.fastpix.sdk.utils.Blob; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamDomainRestrictionsResponse implements AsyncResponse { + + private static final String CONTENT_TYPE = "contentType"; + private static final String RAW_RESPONSE = "rawResponse"; + /** + * HTTP response content type for this operation + */ + private String contentType; + + /** + * HTTP response status code for this operation + */ + private int statusCode; + + /** + * Raw HTTP response; suitable for custom response parsing + */ + private HttpResponse rawResponse; + + /** + * Successfully updated domain restrictions + */ + private UpdateLiveStreamDomainRestrictionsResponseBody object; + + /** + * See the range of possible error + * responses and their status codes. + */ + private DefaultError defaultError; + + @JsonCreator + public UpdateLiveStreamDomainRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse, + @Nullable UpdateLiveStreamDomainRestrictionsResponseBody object, + @Nullable DefaultError defaultError) { + this.contentType = Optional.ofNullable(contentType) + .orElseThrow(() -> new IllegalArgumentException("contentType cannot be null")); + this.statusCode = statusCode; + this.rawResponse = Optional.ofNullable(rawResponse) + .orElseThrow(() -> new IllegalArgumentException("rawResponse cannot be null")); + this.object = object; + this.defaultError = defaultError; + } + + public UpdateLiveStreamDomainRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse) { + this(contentType, statusCode, rawResponse, + null, null); + } + + /** + * HTTP response content type for this operation + */ + public String contentType() { + return this.contentType; + } + + /** + * HTTP response status code for this operation + */ + public int statusCode() { + return this.statusCode; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public HttpResponse rawResponse() { + return this.rawResponse; + } + + /** + * Successfully updated domain restrictions + */ + public Optional object() { + return Optional.ofNullable(this.object); + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Optional defaultError() { + return Optional.ofNullable(this.defaultError); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * HTTP response content type for this operation + */ + public UpdateLiveStreamDomainRestrictionsResponse withContentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + + /** + * HTTP response status code for this operation + */ + public UpdateLiveStreamDomainRestrictionsResponse withStatusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public UpdateLiveStreamDomainRestrictionsResponse withRawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + + /** + * Successfully updated domain restrictions + */ + public UpdateLiveStreamDomainRestrictionsResponse withObject(@Nullable UpdateLiveStreamDomainRestrictionsResponseBody object) { + this.object = object; + return this; + } + + + /** + * See the range of possible error + * responses and their status codes. + */ + public UpdateLiveStreamDomainRestrictionsResponse withDefaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamDomainRestrictionsResponse other = (UpdateLiveStreamDomainRestrictionsResponse) o; + return + Utils.enhancedDeepEquals(this.contentType, other.contentType) && + Utils.enhancedDeepEquals(this.statusCode, other.statusCode) && + Utils.enhancedDeepEquals(this.rawResponse, other.rawResponse) && + Utils.enhancedDeepEquals(this.object, other.object) && + Utils.enhancedDeepEquals(this.defaultError, other.defaultError); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + contentType, statusCode, rawResponse, + object, defaultError); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamDomainRestrictionsResponse.class, + CONTENT_TYPE, contentType, + "statusCode", statusCode, + RAW_RESPONSE, rawResponse, + "object", object, + "defaultError", defaultError); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String contentType; + + private int statusCode; + + private HttpResponse rawResponse; + + private UpdateLiveStreamDomainRestrictionsResponseBody object; + + private DefaultError defaultError; + + private Builder() { + // force use of static builder() method + } + + /** + * HTTP response content type for this operation + */ + public Builder contentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + /** + * HTTP response status code for this operation + */ + public Builder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public Builder rawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + /** + * Successfully updated domain restrictions + */ + public Builder object(@Nullable UpdateLiveStreamDomainRestrictionsResponseBody object) { + this.object = object; + return this; + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Builder defaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + public UpdateLiveStreamDomainRestrictionsResponse build() { + return new UpdateLiveStreamDomainRestrictionsResponse( + contentType, statusCode, rawResponse, + object, defaultError); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamUserAgentRestrictionsRequestBuilder.java b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamUserAgentRestrictionsRequestBuilder.java new file mode 100644 index 0000000..7108e87 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamUserAgentRestrictionsRequestBuilder.java @@ -0,0 +1,86 @@ +package io.fastpix.sdk.models.operations.async; + +import static io.fastpix.sdk.operations.Operations.AsyncRequestOperation; + +import jakarta.annotation.Nonnull; +import java.util.concurrent.CompletableFuture; +import io.fastpix.sdk.SDKConfiguration; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBody; +import io.fastpix.sdk.operations.UpdateLiveStreamUserAgentRestrictions; +import io.fastpix.sdk.utils.Headers; +import io.fastpix.sdk.utils.Options; +import io.fastpix.sdk.utils.RetryConfig; +import io.fastpix.sdk.utils.Utils; + +// Leading-underscore field/method names (_headers, _setterCalled, _buildRequest) are an +// intentional generated convention that avoids clashing with the user-facing builder +// setters (header(), body(), ...); renaming would be inconsistent across all +// *RequestBuilder classes and could reintroduce those clashes. +@SuppressWarnings({"java:S116", "java:S100"}) +public class UpdateLiveStreamUserAgentRestrictionsRequestBuilder { + private final SDKConfiguration sdkConfiguration; + private final Headers _headers = new Headers(); + private final UpdateLiveStreamUserAgentRestrictionsRequest.Builder pojoBuilder; + private UpdateLiveStreamUserAgentRestrictionsRequest request; + private final Options.Builder optionsBuilder; + private boolean _setterCalled; + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder(SDKConfiguration sdkConfiguration) { + this.sdkConfiguration = sdkConfiguration; + this.pojoBuilder = UpdateLiveStreamUserAgentRestrictionsRequest.builder(); + this.optionsBuilder = Options.builder(); + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder streamId(@Nonnull String streamId) { + this.pojoBuilder.streamId(streamId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder playbackId(@Nonnull String playbackId) { + this.pojoBuilder.playbackId(playbackId); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder body(@Nonnull UpdateLiveStreamUserAgentRestrictionsRequestBody body) { + this.pojoBuilder.body(body); + this._setterCalled = true; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder retryConfig(RetryConfig retryConfig) { + this.optionsBuilder.retryConfig(retryConfig); + return this; + } + + private UpdateLiveStreamUserAgentRestrictionsRequest _buildRequest() { + if (this._setterCalled) { + this.request = this.pojoBuilder.build(); + } + return this.request; + } + + public UpdateLiveStreamUserAgentRestrictionsRequestBuilder header(String name, String value) { + Utils.checkNotNull(name, "name"); + Utils.checkNotNull(value, "value"); + this._headers.add(name, value); + return this; + } + + /** + * Executes the request and returns the response. + * + * @return The response from the server. + */ + public CompletableFuture call() { + Options options = optionsBuilder.build(); + AsyncRequestOperation operation + = new UpdateLiveStreamUserAgentRestrictions.Async( + sdkConfiguration, options, sdkConfiguration.retryScheduler(), + _headers); + return operation.doRequest(this._buildRequest()) + .thenCompose(operation::handleResponse); + } +} diff --git a/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamUserAgentRestrictionsResponse.java b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamUserAgentRestrictionsResponse.java new file mode 100644 index 0000000..3b90b3a --- /dev/null +++ b/src/main/java/io/fastpix/sdk/models/operations/async/UpdateLiveStreamUserAgentRestrictionsResponse.java @@ -0,0 +1,255 @@ +package io.fastpix.sdk.models.operations.async; + +import com.fasterxml.jackson.annotation.JsonCreator; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import java.net.http.HttpResponse; +import java.util.Optional; +import io.fastpix.sdk.models.components.DefaultError; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsResponseBody; +import io.fastpix.sdk.utils.AsyncResponse; +import io.fastpix.sdk.utils.Blob; +import io.fastpix.sdk.utils.Utils; + + +public class UpdateLiveStreamUserAgentRestrictionsResponse implements AsyncResponse { + + private static final String CONTENT_TYPE = "contentType"; + private static final String RAW_RESPONSE = "rawResponse"; + /** + * HTTP response content type for this operation + */ + private String contentType; + + /** + * HTTP response status code for this operation + */ + private int statusCode; + + /** + * Raw HTTP response; suitable for custom response parsing + */ + private HttpResponse rawResponse; + + /** + * Successfully updated user-agent restrictions + */ + private UpdateLiveStreamUserAgentRestrictionsResponseBody object; + + /** + * See the range of possible error + * responses and their status codes. + */ + private DefaultError defaultError; + + @JsonCreator + public UpdateLiveStreamUserAgentRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse, + @Nullable UpdateLiveStreamUserAgentRestrictionsResponseBody object, + @Nullable DefaultError defaultError) { + this.contentType = Optional.ofNullable(contentType) + .orElseThrow(() -> new IllegalArgumentException("contentType cannot be null")); + this.statusCode = statusCode; + this.rawResponse = Optional.ofNullable(rawResponse) + .orElseThrow(() -> new IllegalArgumentException("rawResponse cannot be null")); + this.object = object; + this.defaultError = defaultError; + } + + public UpdateLiveStreamUserAgentRestrictionsResponse( + @Nonnull String contentType, + int statusCode, + @Nonnull HttpResponse rawResponse) { + this(contentType, statusCode, rawResponse, + null, null); + } + + /** + * HTTP response content type for this operation + */ + public String contentType() { + return this.contentType; + } + + /** + * HTTP response status code for this operation + */ + public int statusCode() { + return this.statusCode; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public HttpResponse rawResponse() { + return this.rawResponse; + } + + /** + * Successfully updated user-agent restrictions + */ + public Optional object() { + return Optional.ofNullable(this.object); + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Optional defaultError() { + return Optional.ofNullable(this.defaultError); + } + + public static Builder builder() { + return new Builder(); + } + + + /** + * HTTP response content type for this operation + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withContentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + + /** + * HTTP response status code for this operation + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withStatusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withRawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + + /** + * Successfully updated user-agent restrictions + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withObject(@Nullable UpdateLiveStreamUserAgentRestrictionsResponseBody object) { + this.object = object; + return this; + } + + + /** + * See the range of possible error + * responses and their status codes. + */ + public UpdateLiveStreamUserAgentRestrictionsResponse withDefaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateLiveStreamUserAgentRestrictionsResponse other = (UpdateLiveStreamUserAgentRestrictionsResponse) o; + return + Utils.enhancedDeepEquals(this.contentType, other.contentType) && + Utils.enhancedDeepEquals(this.statusCode, other.statusCode) && + Utils.enhancedDeepEquals(this.rawResponse, other.rawResponse) && + Utils.enhancedDeepEquals(this.object, other.object) && + Utils.enhancedDeepEquals(this.defaultError, other.defaultError); + } + + @Override + public int hashCode() { + return Utils.enhancedHash( + contentType, statusCode, rawResponse, + object, defaultError); + } + + @Override + public String toString() { + return Utils.toString(UpdateLiveStreamUserAgentRestrictionsResponse.class, + CONTENT_TYPE, contentType, + "statusCode", statusCode, + RAW_RESPONSE, rawResponse, + "object", object, + "defaultError", defaultError); + } + + @SuppressWarnings("UnusedReturnValue") + public static final class Builder { + + private String contentType; + + private int statusCode; + + private HttpResponse rawResponse; + + private UpdateLiveStreamUserAgentRestrictionsResponseBody object; + + private DefaultError defaultError; + + private Builder() { + // force use of static builder() method + } + + /** + * HTTP response content type for this operation + */ + public Builder contentType(@Nonnull String contentType) { + this.contentType = Utils.checkNotNull(contentType, CONTENT_TYPE); + return this; + } + + /** + * HTTP response status code for this operation + */ + public Builder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + /** + * Raw HTTP response; suitable for custom response parsing + */ + public Builder rawResponse(@Nonnull HttpResponse rawResponse) { + this.rawResponse = Utils.checkNotNull(rawResponse, RAW_RESPONSE); + return this; + } + + /** + * Successfully updated user-agent restrictions + */ + public Builder object(@Nullable UpdateLiveStreamUserAgentRestrictionsResponseBody object) { + this.object = object; + return this; + } + + /** + * See the range of possible error + * responses and their status codes. + */ + public Builder defaultError(@Nullable DefaultError defaultError) { + this.defaultError = defaultError; + return this; + } + + public UpdateLiveStreamUserAgentRestrictionsResponse build() { + return new UpdateLiveStreamUserAgentRestrictionsResponse( + contentType, statusCode, rawResponse, + object, defaultError); + } + + } +} diff --git a/src/main/java/io/fastpix/sdk/operations/UpdateLiveStreamDomainRestrictions.java b/src/main/java/io/fastpix/sdk/operations/UpdateLiveStreamDomainRestrictions.java new file mode 100644 index 0000000..ccfdf8b --- /dev/null +++ b/src/main/java/io/fastpix/sdk/operations/UpdateLiveStreamDomainRestrictions.java @@ -0,0 +1,336 @@ +package io.fastpix.sdk.operations; + +import static io.fastpix.sdk.operations.Operations.RequestOperation; +import static io.fastpix.sdk.utils.Exceptions.unchecked; +import static io.fastpix.sdk.operations.Operations.AsyncRequestOperation; + +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import java.io.InputStream; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import io.fastpix.sdk.SDKConfiguration; +import io.fastpix.sdk.SecuritySource; +import io.fastpix.sdk.models.components.DefaultError; +import io.fastpix.sdk.models.errors.APIException; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsResponse; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsResponseBody; +import io.fastpix.sdk.utils.AsyncRetries; +import io.fastpix.sdk.utils.BackoffStrategy; +import io.fastpix.sdk.utils.Blob; +import io.fastpix.sdk.utils.HTTPClient; +import io.fastpix.sdk.utils.HTTPRequest; +import io.fastpix.sdk.utils.Headers; +import io.fastpix.sdk.utils.Hook.AfterErrorContextImpl; +import io.fastpix.sdk.utils.Hook.AfterSuccessContextImpl; +import io.fastpix.sdk.utils.Hook.BeforeRequestContextImpl; +import io.fastpix.sdk.utils.NonRetryableException; +import io.fastpix.sdk.utils.Options; +import io.fastpix.sdk.utils.Retries; +import io.fastpix.sdk.utils.RetryConfig; +import io.fastpix.sdk.utils.SerializedBody; +import io.fastpix.sdk.utils.Utils.JsonShape; +import io.fastpix.sdk.utils.Utils; + + +// Holder for the generated Sync/Async operation classes. The leading-underscore _headers +// field/parameter and the securitySource field/accessor sharing a name are intentional +// generated conventions; renaming would be inconsistent across all operation classes. +@SuppressWarnings({"java:S116", "java:S117", "java:S1845", "java:S2142"}) +public final class UpdateLiveStreamDomainRestrictions { + + private static final String OPERATION_ID = "update-live-stream-domain-restrictions"; + private static final String APPLICATION_JSON = "application/json"; + private static final String API_ERROR_OCCURRED = "API error occurred"; + private static final String UNEXPECTED_CONTENT_TYPE = "Unexpected content-type received: "; + private static final String STATUS_4XX = "4XX"; + private static final String STATUS_5XX = "5XX"; + + private UpdateLiveStreamDomainRestrictions() { + // utility holder for the generated operation classes; not instantiable + } + + abstract static class Base { + final SDKConfiguration sdkConfiguration; + final String baseUrl; + final SecuritySource securitySource; + final List retryStatusCodes; + final RetryConfig retryConfig; + final HTTPClient client; + final Headers _headers; + + protected Base( + @Nonnull SDKConfiguration sdkConfiguration, @Nullable Options options, + Headers _headers) { + this.sdkConfiguration = sdkConfiguration; + this._headers =_headers; + this.baseUrl = this.sdkConfiguration.serverUrl(); + this.securitySource = this.sdkConfiguration.securitySource(); + Optional.ofNullable(options) + .ifPresent(o -> o.validate(List.of(Options.Option.RETRY_CONFIG))); + this.retryStatusCodes = List.of("408", "429", "500", "502", "503", "504"); + this.retryConfig = Optional.ofNullable(options) + .flatMap(Options::retryConfig) + .or(sdkConfiguration::retryConfig) + .orElse(RetryConfig.builder().backoff(BackoffStrategy.builder() + .initialInterval(1000, TimeUnit.MILLISECONDS) + .maxInterval(10000, TimeUnit.MILLISECONDS) + .baseFactor(1.5) + .maxElapsedTime(3600000, TimeUnit.MILLISECONDS) + .retryConnectError(true) + .build()) + .build()); + this.client = this.sdkConfiguration.client(); + } + + Optional securitySource() { + return Optional.ofNullable(this.securitySource); + } + + BeforeRequestContextImpl createBeforeRequestContext() { + return new BeforeRequestContextImpl( + this.sdkConfiguration, + this.baseUrl, + OPERATION_ID, + java.util.Optional.empty(), + securitySource()); + } + + AfterSuccessContextImpl createAfterSuccessContext() { + return new AfterSuccessContextImpl( + this.sdkConfiguration, + this.baseUrl, + OPERATION_ID, + java.util.Optional.empty(), + securitySource()); + } + + AfterErrorContextImpl createAfterErrorContext() { + return new AfterErrorContextImpl( + this.sdkConfiguration, + this.baseUrl, + OPERATION_ID, + java.util.Optional.empty(), + securitySource()); + } + HttpRequest buildRequest(T request, Class klass, TypeReference typeReference) throws Exception { + String url = Utils.generateURL( + klass, + this.baseUrl, + "/live/streams/{streamId}/playback-ids/{playbackId}/domains", + request, null); + HTTPRequest req = new HTTPRequest(url, "PATCH"); + Object convertedRequest = Utils.convertToShape( + request, + JsonShape.DEFAULT, + typeReference); + SerializedBody serializedRequestBody = Utils.serializeRequestBody( + convertedRequest, + "body", + "json", + false); + if (serializedRequestBody == null) { + throw new IllegalArgumentException("Request body is required"); + } + req.setBody(Optional.ofNullable(serializedRequestBody)); + req.addHeader("Accept", APPLICATION_JSON) + .addHeader("user-agent", SDKConfiguration.USER_AGENT); + _headers.forEach((k, list) -> list.forEach(v -> req.addHeader(k, v))); + Utils.configureSecurity(req, this.sdkConfiguration.securitySource().getSecurity()); + + return req.build(); + } + } + + public static class Sync extends Base + implements RequestOperation { + public Sync( + @Nonnull SDKConfiguration sdkConfiguration, @Nullable Options options, + Headers _headers) { + super( + sdkConfiguration, options, + _headers); + } + + private HttpRequest onBuildRequest(UpdateLiveStreamDomainRestrictionsRequest request) throws Exception { + HttpRequest req = buildRequest(request, UpdateLiveStreamDomainRestrictionsRequest.class, new TypeReference() {}); + return sdkConfiguration.hooks().beforeRequest(createBeforeRequestContext(), req); + } + + private HttpResponse onError(HttpResponse response, Exception error) throws Exception { + return sdkConfiguration.hooks().afterError( + createAfterErrorContext(), + Optional.ofNullable(response), + Optional.ofNullable(error)); + } + + private HttpResponse onSuccess(HttpResponse response) throws Exception { + return sdkConfiguration.hooks().afterSuccess(createAfterSuccessContext(), response); + } + + @Override + public HttpResponse doRequest(UpdateLiveStreamDomainRestrictionsRequest request) { + Retries retries = Retries.builder() + .action(() -> { + HttpRequest r; + try { + r = onBuildRequest(request); + } catch (Exception e) { + throw new NonRetryableException(e); + } + try { + HttpResponse httpRes = client.send(r); + if (Utils.statusCodeMatches(httpRes.statusCode(), STATUS_4XX, STATUS_5XX)) { + return onError(httpRes, null); + } + return httpRes; + } catch (Exception e) { + return onError(null, e); + } + }) + .retryConfig(retryConfig) + .statusCodes(retryStatusCodes) + .build(); + return unchecked(() -> onSuccess(retries.run())).get(); + } + + + @Override + public UpdateLiveStreamDomainRestrictionsResponse handleResponse(HttpResponse response) { + String contentType = response + .headers() + .firstValue("Content-Type") + .orElse("application/octet-stream"); + UpdateLiveStreamDomainRestrictionsResponse.Builder resBuilder = + UpdateLiveStreamDomainRestrictionsResponse + .builder() + .contentType(contentType) + .statusCode(response.statusCode()) + .rawResponse(response); + + UpdateLiveStreamDomainRestrictionsResponse res = resBuilder.build(); + + if (Utils.statusCodeMatches(response.statusCode(), "200")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return res.withObject(Utils.unmarshal(response, new TypeReference() {})); + } else { + throw APIException.from(UNEXPECTED_CONTENT_TYPE + contentType, response); + } + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_4XX)) { + // no content + throw APIException.from(API_ERROR_OCCURRED, response); + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_5XX)) { + // no content + throw APIException.from(API_ERROR_OCCURRED, response); + } + if (Utils.statusCodeMatches(response.statusCode(), "default")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return res.withDefaultError(Utils.unmarshal(response, new TypeReference() {})); + } else { + throw APIException.from(UNEXPECTED_CONTENT_TYPE + contentType, response); + } + } + throw APIException.from("Unexpected status code received: " + response.statusCode(), response); + } + } + public static class Async extends Base + implements AsyncRequestOperation { + private final ScheduledExecutorService retryScheduler; + + public Async( + @Nonnull SDKConfiguration sdkConfiguration, @Nullable Options options, + @Nullable ScheduledExecutorService retryScheduler, Headers _headers) { + super( + sdkConfiguration, options, + _headers); + this.retryScheduler = retryScheduler; + } + + private CompletableFuture onBuildRequest(UpdateLiveStreamDomainRestrictionsRequest request) throws Exception { + HttpRequest req = buildRequest(request, UpdateLiveStreamDomainRestrictionsRequest.class, new TypeReference() {}); + return this.sdkConfiguration.asyncHooks().beforeRequest(createBeforeRequestContext(), req); + } + + private CompletableFuture> onError(HttpResponse response, Throwable error) { + return this.sdkConfiguration.asyncHooks().afterError(createAfterErrorContext(), response, error); + } + + private CompletableFuture> onSuccess(HttpResponse response) { + return this.sdkConfiguration.asyncHooks().afterSuccess(createAfterSuccessContext(), response); + } + + @Override + public CompletableFuture> doRequest(UpdateLiveStreamDomainRestrictionsRequest request) { + AsyncRetries retries = AsyncRetries.builder() + .retryConfig(retryConfig) + .statusCodes(retryStatusCodes) + .scheduler(retryScheduler) + .build(); + return retries.retry(() -> unchecked(() -> onBuildRequest(request)).get().thenCompose(client::sendAsync) + .handle((resp, err) -> { + if (err != null) { + return onError(null, err); + } + if (Utils.statusCodeMatches(resp.statusCode(), STATUS_4XX, STATUS_5XX)) { + return onError(resp, null); + } + return CompletableFuture.completedFuture(resp); + }) + .thenCompose(Function.identity())) + .thenCompose(this::onSuccess); + } + + @Override + public CompletableFuture handleResponse( + HttpResponse response) { + String contentType = response + .headers() + .firstValue("Content-Type") + .orElse("application/octet-stream"); + io.fastpix.sdk.models.operations.async.UpdateLiveStreamDomainRestrictionsResponse.Builder resBuilder = + io.fastpix.sdk.models.operations.async.UpdateLiveStreamDomainRestrictionsResponse + .builder() + .contentType(contentType) + .statusCode(response.statusCode()) + .rawResponse(response); + + io.fastpix.sdk.models.operations.async.UpdateLiveStreamDomainRestrictionsResponse res = resBuilder.build(); + + if (Utils.statusCodeMatches(response.statusCode(), "200")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return Utils.unmarshalAsync(response, new TypeReference() {}) + .thenApply(res::withObject); + } else { + return Utils.createAsyncApiError(response, UNEXPECTED_CONTENT_TYPE + contentType); + } + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_4XX)) { + // no content + return Utils.createAsyncApiError(response, API_ERROR_OCCURRED); + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_5XX)) { + // no content + return Utils.createAsyncApiError(response, API_ERROR_OCCURRED); + } + if (Utils.statusCodeMatches(response.statusCode(), "default")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return Utils.unmarshalAsync(response, new TypeReference() {}) + .thenApply(res::withDefaultError); + } else { + return Utils.createAsyncApiError(response, UNEXPECTED_CONTENT_TYPE + contentType); + } + } + return Utils.createAsyncApiError(response, "Unexpected status code received: " + response.statusCode()); + } + } +} diff --git a/src/main/java/io/fastpix/sdk/operations/UpdateLiveStreamUserAgentRestrictions.java b/src/main/java/io/fastpix/sdk/operations/UpdateLiveStreamUserAgentRestrictions.java new file mode 100644 index 0000000..e789d34 --- /dev/null +++ b/src/main/java/io/fastpix/sdk/operations/UpdateLiveStreamUserAgentRestrictions.java @@ -0,0 +1,336 @@ +package io.fastpix.sdk.operations; + +import static io.fastpix.sdk.operations.Operations.RequestOperation; +import static io.fastpix.sdk.utils.Exceptions.unchecked; +import static io.fastpix.sdk.operations.Operations.AsyncRequestOperation; + +import com.fasterxml.jackson.core.type.TypeReference; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import java.io.InputStream; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import io.fastpix.sdk.SDKConfiguration; +import io.fastpix.sdk.SecuritySource; +import io.fastpix.sdk.models.components.DefaultError; +import io.fastpix.sdk.models.errors.APIException; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsResponse; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsResponseBody; +import io.fastpix.sdk.utils.AsyncRetries; +import io.fastpix.sdk.utils.BackoffStrategy; +import io.fastpix.sdk.utils.Blob; +import io.fastpix.sdk.utils.HTTPClient; +import io.fastpix.sdk.utils.HTTPRequest; +import io.fastpix.sdk.utils.Headers; +import io.fastpix.sdk.utils.Hook.AfterErrorContextImpl; +import io.fastpix.sdk.utils.Hook.AfterSuccessContextImpl; +import io.fastpix.sdk.utils.Hook.BeforeRequestContextImpl; +import io.fastpix.sdk.utils.NonRetryableException; +import io.fastpix.sdk.utils.Options; +import io.fastpix.sdk.utils.Retries; +import io.fastpix.sdk.utils.RetryConfig; +import io.fastpix.sdk.utils.SerializedBody; +import io.fastpix.sdk.utils.Utils.JsonShape; +import io.fastpix.sdk.utils.Utils; + + +// Holder for the generated Sync/Async operation classes. The leading-underscore _headers +// field/parameter and the securitySource field/accessor sharing a name are intentional +// generated conventions; renaming would be inconsistent across all operation classes. +@SuppressWarnings({"java:S116", "java:S117", "java:S1845", "java:S2142"}) +public final class UpdateLiveStreamUserAgentRestrictions { + + private static final String OPERATION_ID = "update-live-stream-user-agent-restrictions"; + private static final String APPLICATION_JSON = "application/json"; + private static final String API_ERROR_OCCURRED = "API error occurred"; + private static final String UNEXPECTED_CONTENT_TYPE = "Unexpected content-type received: "; + private static final String STATUS_4XX = "4XX"; + private static final String STATUS_5XX = "5XX"; + + private UpdateLiveStreamUserAgentRestrictions() { + // utility holder for the generated operation classes; not instantiable + } + + abstract static class Base { + final SDKConfiguration sdkConfiguration; + final String baseUrl; + final SecuritySource securitySource; + final List retryStatusCodes; + final RetryConfig retryConfig; + final HTTPClient client; + final Headers _headers; + + protected Base( + @Nonnull SDKConfiguration sdkConfiguration, @Nullable Options options, + Headers _headers) { + this.sdkConfiguration = sdkConfiguration; + this._headers =_headers; + this.baseUrl = this.sdkConfiguration.serverUrl(); + this.securitySource = this.sdkConfiguration.securitySource(); + Optional.ofNullable(options) + .ifPresent(o -> o.validate(List.of(Options.Option.RETRY_CONFIG))); + this.retryStatusCodes = List.of("408", "429", "500", "502", "503", "504"); + this.retryConfig = Optional.ofNullable(options) + .flatMap(Options::retryConfig) + .or(sdkConfiguration::retryConfig) + .orElse(RetryConfig.builder().backoff(BackoffStrategy.builder() + .initialInterval(1000, TimeUnit.MILLISECONDS) + .maxInterval(10000, TimeUnit.MILLISECONDS) + .baseFactor(1.5) + .maxElapsedTime(3600000, TimeUnit.MILLISECONDS) + .retryConnectError(true) + .build()) + .build()); + this.client = this.sdkConfiguration.client(); + } + + Optional securitySource() { + return Optional.ofNullable(this.securitySource); + } + + BeforeRequestContextImpl createBeforeRequestContext() { + return new BeforeRequestContextImpl( + this.sdkConfiguration, + this.baseUrl, + OPERATION_ID, + java.util.Optional.empty(), + securitySource()); + } + + AfterSuccessContextImpl createAfterSuccessContext() { + return new AfterSuccessContextImpl( + this.sdkConfiguration, + this.baseUrl, + OPERATION_ID, + java.util.Optional.empty(), + securitySource()); + } + + AfterErrorContextImpl createAfterErrorContext() { + return new AfterErrorContextImpl( + this.sdkConfiguration, + this.baseUrl, + OPERATION_ID, + java.util.Optional.empty(), + securitySource()); + } + HttpRequest buildRequest(T request, Class klass, TypeReference typeReference) throws Exception { + String url = Utils.generateURL( + klass, + this.baseUrl, + "/live/streams/{streamId}/playback-ids/{playbackId}/user-agents", + request, null); + HTTPRequest req = new HTTPRequest(url, "PATCH"); + Object convertedRequest = Utils.convertToShape( + request, + JsonShape.DEFAULT, + typeReference); + SerializedBody serializedRequestBody = Utils.serializeRequestBody( + convertedRequest, + "body", + "json", + false); + if (serializedRequestBody == null) { + throw new IllegalArgumentException("Request body is required"); + } + req.setBody(Optional.ofNullable(serializedRequestBody)); + req.addHeader("Accept", APPLICATION_JSON) + .addHeader("user-agent", SDKConfiguration.USER_AGENT); + _headers.forEach((k, list) -> list.forEach(v -> req.addHeader(k, v))); + Utils.configureSecurity(req, this.sdkConfiguration.securitySource().getSecurity()); + + return req.build(); + } + } + + public static class Sync extends Base + implements RequestOperation { + public Sync( + @Nonnull SDKConfiguration sdkConfiguration, @Nullable Options options, + Headers _headers) { + super( + sdkConfiguration, options, + _headers); + } + + private HttpRequest onBuildRequest(UpdateLiveStreamUserAgentRestrictionsRequest request) throws Exception { + HttpRequest req = buildRequest(request, UpdateLiveStreamUserAgentRestrictionsRequest.class, new TypeReference() {}); + return sdkConfiguration.hooks().beforeRequest(createBeforeRequestContext(), req); + } + + private HttpResponse onError(HttpResponse response, Exception error) throws Exception { + return sdkConfiguration.hooks().afterError( + createAfterErrorContext(), + Optional.ofNullable(response), + Optional.ofNullable(error)); + } + + private HttpResponse onSuccess(HttpResponse response) throws Exception { + return sdkConfiguration.hooks().afterSuccess(createAfterSuccessContext(), response); + } + + @Override + public HttpResponse doRequest(UpdateLiveStreamUserAgentRestrictionsRequest request) { + Retries retries = Retries.builder() + .action(() -> { + HttpRequest r; + try { + r = onBuildRequest(request); + } catch (Exception e) { + throw new NonRetryableException(e); + } + try { + HttpResponse httpRes = client.send(r); + if (Utils.statusCodeMatches(httpRes.statusCode(), STATUS_4XX, STATUS_5XX)) { + return onError(httpRes, null); + } + return httpRes; + } catch (Exception e) { + return onError(null, e); + } + }) + .retryConfig(retryConfig) + .statusCodes(retryStatusCodes) + .build(); + return unchecked(() -> onSuccess(retries.run())).get(); + } + + + @Override + public UpdateLiveStreamUserAgentRestrictionsResponse handleResponse(HttpResponse response) { + String contentType = response + .headers() + .firstValue("Content-Type") + .orElse("application/octet-stream"); + UpdateLiveStreamUserAgentRestrictionsResponse.Builder resBuilder = + UpdateLiveStreamUserAgentRestrictionsResponse + .builder() + .contentType(contentType) + .statusCode(response.statusCode()) + .rawResponse(response); + + UpdateLiveStreamUserAgentRestrictionsResponse res = resBuilder.build(); + + if (Utils.statusCodeMatches(response.statusCode(), "200")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return res.withObject(Utils.unmarshal(response, new TypeReference() {})); + } else { + throw APIException.from(UNEXPECTED_CONTENT_TYPE + contentType, response); + } + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_4XX)) { + // no content + throw APIException.from(API_ERROR_OCCURRED, response); + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_5XX)) { + // no content + throw APIException.from(API_ERROR_OCCURRED, response); + } + if (Utils.statusCodeMatches(response.statusCode(), "default")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return res.withDefaultError(Utils.unmarshal(response, new TypeReference() {})); + } else { + throw APIException.from(UNEXPECTED_CONTENT_TYPE + contentType, response); + } + } + throw APIException.from("Unexpected status code received: " + response.statusCode(), response); + } + } + public static class Async extends Base + implements AsyncRequestOperation { + private final ScheduledExecutorService retryScheduler; + + public Async( + @Nonnull SDKConfiguration sdkConfiguration, @Nullable Options options, + @Nullable ScheduledExecutorService retryScheduler, Headers _headers) { + super( + sdkConfiguration, options, + _headers); + this.retryScheduler = retryScheduler; + } + + private CompletableFuture onBuildRequest(UpdateLiveStreamUserAgentRestrictionsRequest request) throws Exception { + HttpRequest req = buildRequest(request, UpdateLiveStreamUserAgentRestrictionsRequest.class, new TypeReference() {}); + return this.sdkConfiguration.asyncHooks().beforeRequest(createBeforeRequestContext(), req); + } + + private CompletableFuture> onError(HttpResponse response, Throwable error) { + return this.sdkConfiguration.asyncHooks().afterError(createAfterErrorContext(), response, error); + } + + private CompletableFuture> onSuccess(HttpResponse response) { + return this.sdkConfiguration.asyncHooks().afterSuccess(createAfterSuccessContext(), response); + } + + @Override + public CompletableFuture> doRequest(UpdateLiveStreamUserAgentRestrictionsRequest request) { + AsyncRetries retries = AsyncRetries.builder() + .retryConfig(retryConfig) + .statusCodes(retryStatusCodes) + .scheduler(retryScheduler) + .build(); + return retries.retry(() -> unchecked(() -> onBuildRequest(request)).get().thenCompose(client::sendAsync) + .handle((resp, err) -> { + if (err != null) { + return onError(null, err); + } + if (Utils.statusCodeMatches(resp.statusCode(), STATUS_4XX, STATUS_5XX)) { + return onError(resp, null); + } + return CompletableFuture.completedFuture(resp); + }) + .thenCompose(Function.identity())) + .thenCompose(this::onSuccess); + } + + @Override + public CompletableFuture handleResponse( + HttpResponse response) { + String contentType = response + .headers() + .firstValue("Content-Type") + .orElse("application/octet-stream"); + io.fastpix.sdk.models.operations.async.UpdateLiveStreamUserAgentRestrictionsResponse.Builder resBuilder = + io.fastpix.sdk.models.operations.async.UpdateLiveStreamUserAgentRestrictionsResponse + .builder() + .contentType(contentType) + .statusCode(response.statusCode()) + .rawResponse(response); + + io.fastpix.sdk.models.operations.async.UpdateLiveStreamUserAgentRestrictionsResponse res = resBuilder.build(); + + if (Utils.statusCodeMatches(response.statusCode(), "200")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return Utils.unmarshalAsync(response, new TypeReference() {}) + .thenApply(res::withObject); + } else { + return Utils.createAsyncApiError(response, UNEXPECTED_CONTENT_TYPE + contentType); + } + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_4XX)) { + // no content + return Utils.createAsyncApiError(response, API_ERROR_OCCURRED); + } + if (Utils.statusCodeMatches(response.statusCode(), STATUS_5XX)) { + // no content + return Utils.createAsyncApiError(response, API_ERROR_OCCURRED); + } + if (Utils.statusCodeMatches(response.statusCode(), "default")) { + if (Utils.contentTypeMatches(contentType, APPLICATION_JSON)) { + return Utils.unmarshalAsync(response, new TypeReference() {}) + .thenApply(res::withDefaultError); + } else { + return Utils.createAsyncApiError(response, UNEXPECTED_CONTENT_TYPE + contentType); + } + } + return Utils.createAsyncApiError(response, "Unexpected status code received: " + response.statusCode()); + } + } +} diff --git a/src/main/java/io/fastpix/sdk/utils/OneOfDeserializer.java b/src/main/java/io/fastpix/sdk/utils/OneOfDeserializer.java index eef0c63..0e1840b 100644 --- a/src/main/java/io/fastpix/sdk/utils/OneOfDeserializer.java +++ b/src/main/java/io/fastpix/sdk/utils/OneOfDeserializer.java @@ -472,7 +472,7 @@ public static List> applyMatchPreferences(List> matches, S matches = integerMatches; } } else if (allDateTime(matches)) { - matches = json.contains("T") ? filter(matches, OffsetDateTime.class) : filter(matches, LocalDate.class); + matches = filter(matches, json.contains("T") ? OffsetDateTime.class : LocalDate.class); } // Apply smart scoring using natural ordering if still multiple candidates diff --git a/src/main/java/io/fastpix/sdk/utils/Utils.java b/src/main/java/io/fastpix/sdk/utils/Utils.java index f8e5dce..42c495a 100644 --- a/src/main/java/io/fastpix/sdk/utils/Utils.java +++ b/src/main/java/io/fastpix/sdk/utils/Utils.java @@ -846,53 +846,46 @@ public interface Function { T apply(S value) throws Exception; } - // The anonymous Iterable wraps a stateful anonymous Iterator whose pending-value field is null - // before the first load, so the lambda-conversion and Optional-null findings are suppressed to - // keep this lazy iteration behavior unchanged. - @SuppressWarnings({"java:S1604", "java:S2789"}) + // The stateful Iterator's pending-value field is null before the first load, so the + // Optional-null finding is suppressed to keep this lazy iteration behavior unchanged. + @SuppressWarnings("java:S2789") private static Iterable iterable(Callable> first, Function> next) { - return new Iterable() { - - @Override - public Iterator iterator() { - return new Iterator() { + return () -> new Iterator() { - private boolean pending = true; + private boolean pending = true; - private Optional nxt; + private Optional nxt; - @Override - public boolean hasNext() { - load(); - return nxt.isPresent(); - } + @Override + public boolean hasNext() { + load(); + return nxt.isPresent(); + } - @Override - public T next() { - load(); - if (!nxt.isPresent()) { - throw new NoSuchElementException(); - } else { - pending = true; - return nxt.get(); - } - } + @Override + public T next() { + load(); + if (!nxt.isPresent()) { + throw new NoSuchElementException(); + } else { + pending = true; + return nxt.get(); + } + } - private void load() { - try { - if (pending) { - if (nxt == null) { - nxt = first.call(); - } else if (nxt.isPresent()) { - nxt = next.apply(nxt.get()); - } - pending = false; - } - } catch (Exception e) { - Exceptions.rethrow(e); - } + private void load() { + try { + if (pending) { + if (nxt == null) { + nxt = first.call(); + } else if (nxt.isPresent()) { + nxt = next.apply(nxt.get()); + } + pending = false; } - }; + } catch (Exception e) { + Exceptions.rethrow(e); + } } }; } @@ -1274,17 +1267,17 @@ public static Object sortSerializedMaps(Object input, String regex, String delim // ordering behavior cohesive; the cognitive-complexity finding is suppressed. @SuppressWarnings("java:S3776") private static String sortMapString(String input, String regex, String delim) { + Pattern delimPattern = Pattern.compile(Pattern.quote(delim)); return Pattern.compile(regex).matcher(input).replaceAll(m -> { - String escapedDelim = Pattern.quote(delim); String result = m.group(); for (int i = 1; i <= m.groupCount(); i++) { final String match = m.group(i); String[] pairs; if (match.contains("=")) { - pairs = match.split(escapedDelim); + pairs = delimPattern.split(match); sortByDelimitedKey(pairs, "="); } else { - String[] values = match.split(escapedDelim); + String[] values = delimPattern.split(match); if (values.length == 1) { pairs = values; } else { diff --git a/src/test/java/io/fastpix/sdk/LivePlaybackRestrictionsTest.java b/src/test/java/io/fastpix/sdk/LivePlaybackRestrictionsTest.java new file mode 100644 index 0000000..6b9ecbf --- /dev/null +++ b/src/test/java/io/fastpix/sdk/LivePlaybackRestrictionsTest.java @@ -0,0 +1,118 @@ +package io.fastpix.sdk; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.sun.net.httpserver.HttpServer; + +import io.fastpix.sdk.models.components.Security; +import io.fastpix.sdk.models.errors.APIException; +import io.fastpix.sdk.models.errors.AsyncAPIException; +import io.fastpix.sdk.models.errors.FastpixException; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsResponse; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBody; +import io.fastpix.sdk.utils.JSON; +import io.fastpix.sdk.utils.RetryConfig; + +/** Drives the live playback restriction operations against a local HTTP server and checks the wire request. */ +class LivePlaybackRestrictionsTest { + + private static final String OK = "{\"success\":true,\"data\":{\"defaultPolicy\":\"allow\",\"allow\":[\"yourdomain.com\"],\"deny\":[]}}"; + + private HttpServer server; + private FastPixSDK sdk; + private volatile String method; + private volatile String path; + private volatile String contentType; + private volatile String body; + private volatile int status = 200; + + @BeforeEach + void start() throws Exception { + server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + server.createContext("/", exchange -> { + method = exchange.getRequestMethod(); + path = exchange.getRequestURI().getPath(); + contentType = exchange.getRequestHeaders().getFirst("Content-Type"); + body = new String(exchange.getRequestBody().readAllBytes(), StandardCharsets.UTF_8); + byte[] out = OK.getBytes(StandardCharsets.UTF_8); + exchange.getResponseHeaders().add("Content-Type", "application/json"); + exchange.sendResponseHeaders(status, out.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(out); + } + }); + server.start(); + sdk = FastPixSDK.builder() + .serverURL("http://localhost:" + server.getAddress().getPort() + "/v1/") + .security(Security.builder().username("user").password("pass").build()) + .retryConfig(RetryConfig.noRetries()) + .build(); + } + + @AfterEach + void stop() { + server.stop(0); + } + + @Test + void updateDomainRestrictionsSendsFlatPatch() throws Exception { + UpdateLiveStreamDomainRestrictionsResponse res = sdk.livePlayback().updateDomainRestrictions("s1", "p1", + UpdateLiveStreamDomainRestrictionsRequestBody.builder() + .allow(List.of("yourdomain.com")).deny(List.of("malicioussite.io")).build()); + + assertEquals("PATCH", method); + assertEquals("/v1/live/streams/s1/playback-ids/p1/domains", path); + assertTrue(contentType.startsWith("application/json")); + JsonNode sent = JSON.getMapper().readTree(body); + assertEquals(JSON.getMapper().readTree("{\"defaultPolicy\":\"allow\",\"allow\":[\"yourdomain.com\"],\"deny\":[\"malicioussite.io\"]}"), sent); + assertEquals(Optional.of(List.of("yourdomain.com")), res.object().get().data().get().allow()); + } + + @Test + void updateUserAgentRestrictionsSendsFlatPatchAsync() throws Exception { + var res = sdk.livePlayback().async().updateUserAgentRestrictions("s1", "p1", + UpdateLiveStreamUserAgentRestrictionsRequestBody.builder() + .defaultPolicy(io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsDefaultPolicy.DENY) + .allow(List.of("PostmanRuntime/7.29.0")).build()).get(); + + assertEquals("PATCH", method); + assertEquals("/v1/live/streams/s1/playback-ids/p1/user-agents", path); + assertEquals(JSON.getMapper().readTree("{\"defaultPolicy\":\"deny\",\"allow\":[\"PostmanRuntime/7.29.0\"]}"), + JSON.getMapper().readTree(body)); + assertEquals(Optional.of(true), res.object().get().success()); + } + + @Test + void apiErrorSurfacesAsApiException() { + status = 403; + assertThrows(APIException.class, () -> sdk.livePlayback().updateDomainRestrictions("s1", "p1", + UpdateLiveStreamDomainRestrictionsRequestBody.builder().build())); + ExecutionException async = assertThrows(ExecutionException.class, () -> sdk.livePlayback().async() + .updateUserAgentRestrictions("s1", "p1", UpdateLiveStreamUserAgentRestrictionsRequestBody.builder().build()).get()); + assertTrue(async.getCause() instanceof FastpixException); + } + + @Test + void asyncServerErrorFailsTheFuture() { + status = 500; + ExecutionException async = assertThrows(ExecutionException.class, () -> sdk.livePlayback().async() + .updateDomainRestrictions("s1", "p1", UpdateLiveStreamDomainRestrictionsRequestBody.builder().build()).get()); + assertTrue(async.getCause() instanceof AsyncAPIException); + assertEquals(500, ((AsyncAPIException) async.getCause()).code()); + } +} diff --git a/src/test/java/io/fastpix/sdk/ResourceReturnTypeTest.java b/src/test/java/io/fastpix/sdk/ResourceReturnTypeTest.java new file mode 100644 index 0000000..38d07ec --- /dev/null +++ b/src/test/java/io/fastpix/sdk/ResourceReturnTypeTest.java @@ -0,0 +1,56 @@ +package io.fastpix.sdk; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +/** + * Every resource method must declare the {@code Response} envelope that the + * operation it constructs deserializes on the success path. Fails per method by name. + */ +class ResourceReturnTypeTest { + + private static final Path RESOURCES = Path.of("src/main/java/io/fastpix/sdk"); + private static final int EXPECTED_METHOD_COUNT = 140; + + private static final Pattern METHOD = Pattern.compile( + "public (?:CompletableFuture<)?(\\w+Response)>? (\\w+)\\([^)]*\\)\\s*\\{[^}]*?new (\\w+)\\.(Sync|Async)\\(", Pattern.DOTALL); + + @Test + void declaredReturnTypeMatchesDeserializedEnvelope() throws IOException { + List mismatches = new ArrayList<>(); + int scanned = 0; + try (Stream files = Files.list(RESOURCES)) { + for (Path file : (Iterable) files.filter(p -> p.toString().endsWith(".java"))::iterator) { + String source = Files.readString(file); + Matcher m = METHOD.matcher(source); + while (m.find()) { + scanned++; + String declared = m.group(1); + String expected = m.group(3) + "Response"; + if (!declared.equals(expected)) { + mismatches.add(file.getFileName() + "#" + m.group(2) + " declares " + declared + " but deserializes " + expected); + } + String pkg = m.group(4).equals("Async") ? "io.fastpix.sdk.models.operations.async." : "io.fastpix.sdk.models.operations."; + try { + Class.forName(pkg + declared); + } catch (ClassNotFoundException e) { + mismatches.add(file.getFileName() + "#" + m.group(2) + " return type " + pkg + declared + " does not exist"); + } + } + } + } + assertTrue(mismatches.isEmpty(), () -> String.join("\n", mismatches)); + assertEquals(EXPECTED_METHOD_COUNT, scanned, "resource method scan count drifted; update the constant with the new operation"); + } +} diff --git a/src/test/java/io/fastpix/sdk/models/ModelContractTest.java b/src/test/java/io/fastpix/sdk/models/ModelContractTest.java new file mode 100644 index 0000000..2b25d35 --- /dev/null +++ b/src/test/java/io/fastpix/sdk/models/ModelContractTest.java @@ -0,0 +1,161 @@ +package io.fastpix.sdk.models; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; + +import io.fastpix.sdk.AsyncLivePlayback; +import io.fastpix.sdk.LivePlayback; +import io.fastpix.sdk.Playback; +import io.fastpix.sdk.models.components.CreateLiveStreamRequest; +import io.fastpix.sdk.models.components.GetAllMediaResponse; +import io.fastpix.sdk.models.components.GetMediaDetailResponse; +import io.fastpix.sdk.models.components.InputMediaSettings; +import io.fastpix.sdk.models.components.LiveMediaClips; +import io.fastpix.sdk.models.components.Media; +import io.fastpix.sdk.models.components.MediaClipResponseData; +import io.fastpix.sdk.models.components.PlaybackIdAccessRestrictions; +import io.fastpix.sdk.models.components.PlaybackIdDomains; +import io.fastpix.sdk.models.components.PlaybackIdRequest; +import io.fastpix.sdk.models.components.PlaybackIdResponse; +import io.fastpix.sdk.models.components.PlaybackIdSuccessResponse; +import io.fastpix.sdk.models.components.PlaybackIdUserAgents; +import io.fastpix.sdk.models.components.PlaybackSettings; +import io.fastpix.sdk.models.components.PlaylistByIdResponseMediaListItem; +import io.fastpix.sdk.models.components.PolicyAction; +import io.fastpix.sdk.models.components.SourceAccessMedia; +import io.fastpix.sdk.models.components.UpdateMedia; +import io.fastpix.sdk.models.operations.UpdateDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsResponseBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequest; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsResponseBody; +import io.fastpix.sdk.models.operations.UpdateUserAgentRestrictionsRequestBody; +import io.fastpix.sdk.utils.JSON; + +/** Wire-contract checks for models touched by the live-restrictions spec sync. */ +class ModelContractTest { + + private static final ObjectMapper MAPPER = JSON.getMapper(); + + private static final String RESTRICTIONS = "{\"domains\":{\"defaultPolicy\":\"deny\",\"allow\":[\"example.com\"],\"deny\":[]}," + + "\"userAgents\":{\"defaultPolicy\":\"allow\",\"allow\":[],\"deny\":[]}}"; + + static Stream> durationModels() { + return Stream.of(GetAllMediaResponse.class, GetMediaDetailResponse.class, LiveMediaClips.class, + MediaClipResponseData.class, Media.class, UpdateMedia.class, SourceAccessMedia.class, + PlaylistByIdResponseMediaListItem.class); + } + + @SuppressWarnings("unchecked") + private static Optional duration(Object model) throws Exception { + return (Optional) model.getClass().getMethod("duration").invoke(model); + } + + @ParameterizedTest + @MethodSource("durationModels") + void durationIsOptionalDouble(Class type) throws Exception { + assertEquals(Optional.of(145.821315), duration(MAPPER.readValue("{\"duration\":145.821315}", type))); + assertEquals(Optional.of(10.0), duration(MAPPER.readValue("{\"duration\":10}", type))); + assertEquals(Optional.empty(), duration(MAPPER.readValue("{}", type))); + JsonNode out = MAPPER.readTree(MAPPER.writeValueAsString(MAPPER.readValue("{\"duration\":145.82}", type))); + assertTrue(out.get("duration").isNumber()); + assertEquals(145.82, out.get("duration").doubleValue()); + assertThrows(MismatchedInputException.class, () -> MAPPER.readValue("{\"duration\":\"00:02:25\"}", type)); + } + + @Test + void enableRecordingIsOptionalAndRoundTrips() throws Exception { + assertFalse(MAPPER.readTree(MAPPER.writeValueAsString(InputMediaSettings.builder().build())).has("enableRecording")); + InputMediaSettings parsed = MAPPER.readValue("{\"enableRecording\":false}", InputMediaSettings.class); + assertEquals(Optional.of(false), parsed.enableRecording()); + assertFalse(MAPPER.readTree(MAPPER.writeValueAsString(parsed)).get("enableRecording").booleanValue()); + CreateLiveStreamRequest req = CreateLiveStreamRequest.builder() + .playbackSettings(PlaybackSettings.builder().build()) + .inputMediaSettings(InputMediaSettings.builder().enableRecording(false).build()).build(); + assertFalse(MAPPER.readTree(MAPPER.writeValueAsString(req)).at("/inputMediaSettings/enableRecording").booleanValue()); + } + + private static PlaybackIdAccessRestrictions exampleRestrictions() { + return PlaybackIdAccessRestrictions.builder() + .domains(PlaybackIdDomains.builder().defaultPolicy(PolicyAction.DENY) + .allow(List.of("example.com")).deny(List.of()).build()) + .userAgents(PlaybackIdUserAgents.builder().defaultPolicy(PolicyAction.ALLOW) + .allow(List.of()).deny(List.of()).build()) + .build(); + } + + @Test + void accessRestrictionsOnLivePlaybackModels() throws Exception { + JsonNode expected = MAPPER.readTree(RESTRICTIONS); + + PlaybackIdRequest request = PlaybackIdRequest.builder().accessRestrictions(exampleRestrictions()).build(); + assertEquals(MAPPER.readTree("{\"accessPolicy\":\"public\",\"accessRestrictions\":" + RESTRICTIONS + "}"), + MAPPER.readTree(MAPPER.writeValueAsString(request))); + assertFalse(MAPPER.readTree(MAPPER.writeValueAsString(PlaybackIdRequest.builder().build())).has("accessRestrictions")); + + PlaybackSettings settings = PlaybackSettings.builder().accessRestrictions(exampleRestrictions()).build(); + assertEquals(expected, MAPPER.readTree(MAPPER.writeValueAsString(settings)).get("accessRestrictions")); + + PlaybackIdResponse item = MAPPER.readValue("{\"id\":\"p1\",\"accessRestrictions\":" + RESTRICTIONS + "}", PlaybackIdResponse.class); + assertEquals(Optional.of(PolicyAction.DENY), item.accessRestrictions().get().domains().get().defaultPolicy()); + assertEquals(Optional.empty(), MAPPER.readValue("{\"id\":\"p1\"}", PlaybackIdResponse.class).accessRestrictions()); + + PlaybackIdSuccessResponse with = MAPPER.readValue( + "{\"success\":true,\"data\":{\"id\":\"p1\",\"accessPolicy\":\"public\",\"accessRestrictions\":" + RESTRICTIONS + "}}", + PlaybackIdSuccessResponse.class); + assertEquals(Optional.of(List.of("example.com")), with.data().get().accessRestrictions().get().domains().get().allow()); + PlaybackIdSuccessResponse without = MAPPER.readValue( + "{\"success\":true,\"data\":{\"id\":\"p1\",\"accessPolicy\":\"public\"}}", PlaybackIdSuccessResponse.class); + assertEquals(Optional.empty(), without.data().get().accessRestrictions()); + } + + @Test + void liveRestrictionRequestBodiesAreFlat() throws Exception { + assertEquals(MAPPER.readTree("{\"defaultPolicy\":\"allow\",\"allow\":[\"yourdomain.com\"],\"deny\":[\"malicioussite.io\"]}"), + MAPPER.readTree(MAPPER.writeValueAsString(UpdateLiveStreamDomainRestrictionsRequestBody.builder() + .allow(List.of("yourdomain.com")).deny(List.of("malicioussite.io")).build()))); + assertEquals(MAPPER.readTree("{\"defaultPolicy\":\"allow\"}"), + MAPPER.readTree(MAPPER.writeValueAsString(UpdateLiveStreamUserAgentRestrictionsRequestBody.builder().build()))); + + UpdateLiveStreamDomainRestrictionsRequest request = new UpdateLiveStreamDomainRestrictionsRequest( + "s1", "p1", UpdateLiveStreamDomainRestrictionsRequestBody.builder().build()); + assertEquals("s1", request.streamId()); + assertEquals("p1", request.playbackId()); + assertThrows(NoSuchMethodException.class, () -> UpdateLiveStreamDomainRestrictionsRequest.class.getMethod("mediaId")); + assertThrows(NoSuchMethodException.class, () -> UpdateLiveStreamUserAgentRestrictionsRequest.class.getMethod("mediaId")); + + String response = "{\"success\":true,\"data\":{\"defaultPolicy\":\"allow\",\"allow\":[\"yourdomain.com\"],\"deny\":[\"malicioussite.io\"]}}"; + UpdateLiveStreamDomainRestrictionsResponseBody domains = MAPPER.readValue(response, UpdateLiveStreamDomainRestrictionsResponseBody.class); + assertEquals(Optional.of(true), domains.success()); + assertEquals(Optional.of("allow"), domains.data().get().defaultPolicy()); + assertEquals(Optional.of(List.of("malicioussite.io")), domains.data().get().deny()); + UpdateLiveStreamUserAgentRestrictionsResponseBody agents = MAPPER.readValue(response, UpdateLiveStreamUserAgentRestrictionsResponseBody.class); + assertEquals(Optional.of(List.of("yourdomain.com")), agents.data().get().allow()); + } + + @Test + void livePlaybackExposesRestrictionOperations() throws Exception { + LivePlayback.class.getMethod("updateDomainRestrictions", String.class, String.class, UpdateLiveStreamDomainRestrictionsRequestBody.class); + LivePlayback.class.getMethod("updateUserAgentRestrictions", String.class, String.class, UpdateLiveStreamUserAgentRestrictionsRequestBody.class); + AsyncLivePlayback.class.getMethod("updateDomainRestrictions", String.class, String.class, UpdateLiveStreamDomainRestrictionsRequestBody.class); + AsyncLivePlayback.class.getMethod("updateUserAgentRestrictions", String.class, String.class, UpdateLiveStreamUserAgentRestrictionsRequestBody.class); + Playback.class.getMethod("updateDomainRestrictions", String.class, String.class, UpdateDomainRestrictionsRequestBody.class); + Playback.class.getMethod("updateUserAgentRestrictions", String.class, String.class, UpdateUserAgentRestrictionsRequestBody.class); + } +} diff --git a/tests/.env.example b/tests/.env.example new file mode 100644 index 0000000..91091cf --- /dev/null +++ b/tests/.env.example @@ -0,0 +1,7 @@ +# FastPix API credentials (from the FastPix dashboard). +# Copy this file to `.env` and fill in your values. +FASTPIX_USERNAME=your-access-token +FASTPIX_PASSWORD=your-secret-key + +# Optional: override the API base URL +# FASTPIX_BASE_URL=https://api.fastpix.com/v1 diff --git a/tests/README.md b/tests/README.md index d9071ed..0b39eff 100644 --- a/tests/README.md +++ b/tests/README.md @@ -69,7 +69,6 @@ against the OpenAPI schema. each via fetch + the SDK, diffs the two, and writes: - `GET_ENDPOINTS_OPENAPI_RESPONSE_VALIDATION_REPORT.md` - `GET_ENDPOINTS_OPENAPI_RESPONSE_FIX_SUGGESTIONS.md` - - the consolidated summary block in this `README.md` - `validate-non-get-endpoints.ts` — runs the mutating lifecycle and writes `NON_GET_ENDPOINTS_VALIDATION_REPORT.md`. - `java-harness.ts` — resolves the SDK classpath, compiles the harness once, and @@ -97,204 +96,13 @@ once per process (lazily, cached), mirroring the Go harness's compile-once model ## Fixtures -`get-endpoints-fixtures.json` contains real IDs for GET endpoints that require -path parameters. Update it with working IDs from your FastPix account for -accurate testing. If a fixture is missing, the GET driver falls back to a -placeholder UUID, which typically yields a 404. +`get-endpoints-fixtures.json` ships with placeholder IDs. Fill it for a run with - -Last generated: 2026-08-03T09:43:48.587Z - -- **Total GET endpoints**: 30 -- **PASS**: 27 -- **FAIL**: 3 -- **SKIP**: 0 - -| Endpoint | OperationId | OpenAPI valid | SDK parse | Missing in SDK (present in API) | Missing in API (present in SDK) | Empty arrays omitted by SDK | Status | -|---|---|---:|---:|---|---|---|---| -| `/on-demand` | `list-media` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/{livestreamId}/live-clips` | `list-live-clips` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/{mediaId}` | `get-media` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/{mediaId}/summary` | `get-media-summary` | ✅ | ❌ | None | None | None | ❌ FAIL | -| `/on-demand/{mediaId}/input-info` | `retrieveMediaInputInfo` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/{mediaId}/playback-ids` | `list-playback-ids` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/uploads` | `list-uploads` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/{mediaId}/media-clips` | `get-media-clips` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/playlists` | `get-all-playlists` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/playlists/{playlistId}` | `get-playlist-by-id` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/{mediaId}/playback-ids/{playbackId}` | `get-playback-id` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/on-demand/drm-configurations` | `getDrmConfiguration` | ✅ | ❌ | None | None | None | ❌ FAIL | -| `/on-demand/drm-configurations/{drmConfigurationId}` | `getDrmConfigurationById` | ✅ | ❌ | None | None | None | ❌ FAIL | -| `/live/streams` | `get-all-streams` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/live/streams/{streamId}/viewer-count` | `get-live-stream-viewer-count-by-id` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/live/streams/{streamId}` | `get-live-stream-by-id` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/live/streams/{streamId}/playback-ids/{playbackId}` | `get-live-stream-playback-id` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/live/streams/{streamId}/simulcast/{simulcastId}` | `get-specific-simulcast-of-stream` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/iam/signing-keys` | `list_signing_keys` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/iam/signing-keys/{signingKeyId}` | `get-signing_key_by_id` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/viewlist` | `list_video_views` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/viewlist/{viewId}` | `get_video_view_details` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/viewlist/top-content` | `list_by_top_content` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/dimensions` | `list_dimensions` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/dimensions/{dimensionsId}` | `list_filter_values_for_dimension` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/metrics/{metricId}/breakdown` | `list_breakdown_values` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/metrics/{metricId}/overall` | `list_overall_values` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/metrics/{metricId}/timeseries` | `get_timeseries_data` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/metrics/comparison` | `list_comparison_values` | ✅ | ✅ | None | None | None | ✅ PASS | -| `/data/errors` | `list_errors` | ✅ | ✅ | None | None | None | ✅ PASS | - -#### Missing fields (full lists) - -- **list-media** (`/on-demand`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list-live-clips** (`/on-demand/{livestreamId}/live-clips`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-media** (`/on-demand/{mediaId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-media-summary** (`/on-demand/{mediaId}/summary`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **retrieveMediaInputInfo** (`/on-demand/{mediaId}/input-info`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list-playback-ids** (`/on-demand/{mediaId}/playback-ids`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list-uploads** (`/on-demand/uploads`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-media-clips** (`/on-demand/{mediaId}/media-clips`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-all-playlists** (`/on-demand/playlists`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-playlist-by-id** (`/on-demand/playlists/{playlistId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-playback-id** (`/on-demand/{mediaId}/playback-ids/{playbackId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **getDrmConfiguration** (`/on-demand/drm-configurations`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **getDrmConfigurationById** (`/on-demand/drm-configurations/{drmConfigurationId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-all-streams** (`/live/streams`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-live-stream-viewer-count-by-id** (`/live/streams/{streamId}/viewer-count`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-live-stream-by-id** (`/live/streams/{streamId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-live-stream-playback-id** (`/live/streams/{streamId}/playback-ids/{playbackId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-specific-simulcast-of-stream** (`/live/streams/{streamId}/simulcast/{simulcastId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_signing_keys** (`/iam/signing-keys`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get-signing_key_by_id** (`/iam/signing-keys/{signingKeyId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_video_views** (`/data/viewlist`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get_video_view_details** (`/data/viewlist/{viewId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_by_top_content** (`/data/viewlist/top-content`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_dimensions** (`/data/dimensions`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_filter_values_for_dimension** (`/data/dimensions/{dimensionsId}`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_breakdown_values** (`/data/metrics/{metricId}/breakdown`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_overall_values** (`/data/metrics/{metricId}/overall`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **get_timeseries_data** (`/data/metrics/{metricId}/timeseries`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_comparison_values** (`/data/metrics/comparison`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None -- **list_errors** (`/data/errors`) - - **Missing in SDK (present in API)**: None - - **Missing in API (present in SDK)**: None - - **Empty arrays omitted by SDK**: None - - **Empty arrays omitted by API**: None +```bash +npm run fixtures:setup # creates temp resources on the account, writes their IDs +npm run validate:get-endpoints +npm run fixtures:teardown # deletes them and restores the fixture file +``` -Full details: `tests/GET_ENDPOINTS_OPENAPI_RESPONSE_VALIDATION_REPORT.md` - +Never commit the filled file. Endpoints without a fixture fall back to a +placeholder UUID, which typically yields a 404 or 422. diff --git a/tests/js-yaml.d.ts b/tests/js-yaml.d.ts deleted file mode 100644 index d3c60b8..0000000 --- a/tests/js-yaml.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare module 'js-yaml' { - export function load(str: string, options?: any): any; - export function dump(obj: any, options?: any): string; - export function safeLoad(str: string, options?: any): any; - export function safeDump(obj: any, options?: any): string; - export default { - load, - dump, - safeLoad, - safeDump, - }; -} diff --git a/tests/package-lock.json b/tests/package-lock.json index 59b2ab2..2f56979 100644 --- a/tests/package-lock.json +++ b/tests/package-lock.json @@ -6,18 +6,17 @@ "": { "name": "fastpix-java-sdk-devtools", "devDependencies": { - "@types/js-yaml": "^4.0.9", "@types/node": "^25.0.2", - "js-yaml": "^4.1.1", + "js-yaml": "^5.4.1", "openapi-response-validator": "^12.1.3", - "tsx": "^4.21.0", + "tsx": "^4.22.3", "typescript": "~5.8.3" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", - "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", "cpu": [ "ppc64" ], @@ -32,9 +31,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", - "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", "cpu": [ "arm" ], @@ -49,9 +48,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", - "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", "cpu": [ "arm64" ], @@ -66,9 +65,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", - "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", "cpu": [ "x64" ], @@ -83,9 +82,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", - "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", "cpu": [ "arm64" ], @@ -100,9 +99,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", - "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", "cpu": [ "x64" ], @@ -117,9 +116,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", - "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", "cpu": [ "arm64" ], @@ -134,9 +133,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", - "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", "cpu": [ "x64" ], @@ -151,9 +150,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", - "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", "cpu": [ "arm" ], @@ -168,9 +167,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", - "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", "cpu": [ "arm64" ], @@ -185,9 +184,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", - "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", "cpu": [ "ia32" ], @@ -202,9 +201,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", - "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", "cpu": [ "loong64" ], @@ -219,9 +218,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", - "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", "cpu": [ "mips64el" ], @@ -236,9 +235,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", - "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", "cpu": [ "ppc64" ], @@ -253,9 +252,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", - "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", "cpu": [ "riscv64" ], @@ -270,9 +269,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", - "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", "cpu": [ "s390x" ], @@ -287,9 +286,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", - "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", "cpu": [ "x64" ], @@ -304,9 +303,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", - "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", "cpu": [ "arm64" ], @@ -321,9 +320,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", - "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", "cpu": [ "x64" ], @@ -338,9 +337,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", - "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", "cpu": [ "arm64" ], @@ -355,9 +354,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", - "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", "cpu": [ "x64" ], @@ -372,9 +371,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", - "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", "cpu": [ "arm64" ], @@ -389,9 +388,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", - "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", "cpu": [ "x64" ], @@ -406,9 +405,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", - "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", "cpu": [ "arm64" ], @@ -423,9 +422,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", - "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", "cpu": [ "ia32" ], @@ -440,9 +439,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", - "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", "cpu": [ "x64" ], @@ -456,13 +455,6 @@ "node": ">=18" } }, - "node_modules/@types/js-yaml": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", - "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { "version": "25.9.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", @@ -498,9 +490,9 @@ "license": "Python-2.0" }, "node_modules/esbuild": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", - "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -511,32 +503,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.0", - "@esbuild/android-arm": "0.28.0", - "@esbuild/android-arm64": "0.28.0", - "@esbuild/android-x64": "0.28.0", - "@esbuild/darwin-arm64": "0.28.0", - "@esbuild/darwin-x64": "0.28.0", - "@esbuild/freebsd-arm64": "0.28.0", - "@esbuild/freebsd-x64": "0.28.0", - "@esbuild/linux-arm": "0.28.0", - "@esbuild/linux-arm64": "0.28.0", - "@esbuild/linux-ia32": "0.28.0", - "@esbuild/linux-loong64": "0.28.0", - "@esbuild/linux-mips64el": "0.28.0", - "@esbuild/linux-ppc64": "0.28.0", - "@esbuild/linux-riscv64": "0.28.0", - "@esbuild/linux-s390x": "0.28.0", - "@esbuild/linux-x64": "0.28.0", - "@esbuild/netbsd-arm64": "0.28.0", - "@esbuild/netbsd-x64": "0.28.0", - "@esbuild/openbsd-arm64": "0.28.0", - "@esbuild/openbsd-x64": "0.28.0", - "@esbuild/openharmony-arm64": "0.28.0", - "@esbuild/sunos-x64": "0.28.0", - "@esbuild/win32-arm64": "0.28.0", - "@esbuild/win32-ia32": "0.28.0", - "@esbuild/win32-x64": "0.28.0" + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" } }, "node_modules/fast-deep-equal": { @@ -547,9 +539,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.3.tgz", + "integrity": "sha512-7+72G6vLt7jjNas8SmSATx2qeyRIjxeqO3i4IkmDTxlqYZRKANhOe1bnovcp4WZmvsYrp60WyqPyHqgRiX0yXw==", "dev": true, "funding": [ { @@ -579,16 +571,26 @@ } }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.1.tgz", + "integrity": "sha512-28R/k+NAjeuf7+CKlTxWZVExJGwVVLwY06DgEnOMz2gEpfNkDcD7QvyiVPT0xy0XXhU8vHsd4Ot42OOPdJG7dQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "js-yaml": "bin/js-yaml.mjs" } }, "node_modules/json-schema-traverse": { diff --git a/tests/package.json b/tests/package.json index 1333d56..3260089 100644 --- a/tests/package.json +++ b/tests/package.json @@ -4,14 +4,18 @@ "type": "module", "scripts": { "validate:get-endpoints": "tsx validate-get-endpoints.ts", - "validate:non-get-endpoints": "tsx validate-non-get-endpoints.ts" + "validate:non-get-endpoints": "tsx validate-non-get-endpoints.ts", + "fixtures:setup": "tsx setup-get-fixtures.ts", + "fixtures:teardown": "tsx setup-get-fixtures.ts --teardown" }, "devDependencies": { - "@types/js-yaml": "^4.0.9", "@types/node": "^25.0.2", - "js-yaml": "^4.1.1", + "js-yaml": "^5.4.1", "openapi-response-validator": "^12.1.3", - "tsx": "^4.21.0", + "tsx": "^4.22.3", "typescript": "~5.8.3" + }, + "overrides": { + "fast-uri": "^4.1.3" } } diff --git a/tests/sdkharness/Dispatch.java b/tests/sdkharness/Dispatch.java index dd45c26..006a8fa 100644 --- a/tests/sdkharness/Dispatch.java +++ b/tests/sdkharness/Dispatch.java @@ -23,7 +23,10 @@ import io.fastpix.sdk.models.components.PlaybackSettings; import io.fastpix.sdk.models.components.InputMediaSettings; import io.fastpix.sdk.models.components.PatchLiveStreamRequest; +import io.fastpix.sdk.models.components.PlaybackIdAccessRestrictions; +import io.fastpix.sdk.models.components.PlaybackIdDomains; import io.fastpix.sdk.models.components.PlaybackIdRequest; +import io.fastpix.sdk.models.components.PolicyAction; import io.fastpix.sdk.models.components.SimulcastRequest; import io.fastpix.sdk.models.components.SimulcastUpdateRequest; import io.fastpix.sdk.models.components.UpdateTrackRequest; @@ -48,6 +51,8 @@ import io.fastpix.sdk.models.operations.UpdateMediaModerationRequestBody; import io.fastpix.sdk.models.operations.UpdateMediaNamedEntitiesRequestBody; import io.fastpix.sdk.models.operations.UpdateDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamDomainRestrictionsRequestBody; +import io.fastpix.sdk.models.operations.UpdateLiveStreamUserAgentRestrictionsRequestBody; import io.fastpix.sdk.models.operations.UpdateUserAgentRestrictionsRequestBody; import io.fastpix.sdk.models.operations.ListVideoViewsRequest; @@ -209,7 +214,8 @@ static Object invoke(FastPixSDK sdk, String op, Map req) throws return sdk.streams().create(CreateLiveStreamRequest.builder() .playbackSettings(PlaybackSettings.builder().build()) .inputMediaSettings(InputMediaSettings.builder() - .metadata(Map.of("name", "sdk-validate")).build()) + .metadata(Map.of("name", "sdk-validate")) + .enableRecording(true).build()) .build()); case "create-media-playback-id": return sdk.playback().createId(str(req, "mediaId"), @@ -225,7 +231,13 @@ static Object invoke(FastPixSDK sdk, String op, Map req) throws return sdk.manageVideos().generateSubtitles(str(req, "mediaId"), str(req, "trackId"), TrackSubtitlesGenerateRequest.builder().build()); case "create-playbackId-of-stream": - return sdk.livePlayback().createPlaybackId(str(req, "streamId"), PlaybackIdRequest.builder().build()); + return sdk.livePlayback().createPlaybackId(str(req, "streamId"), PlaybackIdRequest.builder() + .accessRestrictions(PlaybackIdAccessRestrictions.builder() + .domains(PlaybackIdDomains.builder() + .defaultPolicy(PolicyAction.DENY) + .allow(List.of("example.com")).build()) + .build()) + .build()); case "create-simulcast-of-stream": return sdk.simulcastStream().create(str(req, "streamId"), SimulcastRequest.builder() .url("rtmp://example.com/live") @@ -269,6 +281,12 @@ static Object invoke(FastPixSDK sdk, String op, Map req) throws case "update-user-agent-restrictions": return sdk.playback().updateUserAgentRestrictions(str(req, "mediaId"), str(req, "playbackId"), UpdateUserAgentRestrictionsRequestBody.builder().allow(List.of("Mozilla")).build()); + case "update-live-stream-domain-restrictions": + return sdk.livePlayback().updateDomainRestrictions(str(req, "streamId"), str(req, "playbackId"), + UpdateLiveStreamDomainRestrictionsRequestBody.builder().allow(List.of("example.com")).build()); + case "update-live-stream-user-agent-restrictions": + return sdk.livePlayback().updateUserAgentRestrictions(str(req, "streamId"), str(req, "playbackId"), + UpdateLiveStreamUserAgentRestrictionsRequestBody.builder().allow(List.of("Mozilla")).build()); case "update-a-playlist": return sdk.playlists().update(str(req, "playlistId"), UpdatePlaylistRequest.builder() .name("SDK Validate Updated").description("updated by validator").build()); diff --git a/tests/setup-get-fixtures.ts b/tests/setup-get-fixtures.ts new file mode 100644 index 0000000..96ca227 --- /dev/null +++ b/tests/setup-get-fixtures.ts @@ -0,0 +1,97 @@ +#!/usr/bin/env tsx +/* + * Fills `get-endpoints-fixtures.json` with real IDs for a GET validator run. + * + * npm run fixtures:setup creates a stream + playback ID, a playlist and a + * signing key, picks a Ready media, writes the IDs + * into the fixture file and records them in + * .fixture-resources.json + * npm run fixtures:teardown deletes those resources and restores the fixture + * file from git + * + * Requires FASTPIX_USERNAME / FASTPIX_PASSWORD and optionally FASTPIX_BASE_URL. + * Never commit the filled fixture file; teardown restores it. + */ + +import { readFileSync, writeFileSync, existsSync, unlinkSync } from "node:fs"; +import { execSync } from "node:child_process"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const here = dirname(fileURLToPath(import.meta.url)); +const fixturePath = join(here, "get-endpoints-fixtures.json"); +const statePath = join(here, ".fixture-resources.json"); +const base = (process.env.FASTPIX_BASE_URL ?? "https://api.fastpix.com/v1").replace(/\/$/, ""); +const auth = "Basic " + Buffer.from(`${process.env.FASTPIX_USERNAME}:${process.env.FASTPIX_PASSWORD}`).toString("base64"); + +if (!process.env.FASTPIX_USERNAME || !process.env.FASTPIX_PASSWORD) { + console.error("Set FASTPIX_USERNAME and FASTPIX_PASSWORD (see .env.example)."); + process.exit(1); +} + +async function call(method: string, path: string, body?: unknown): Promise { + const res = await fetch(base + path, { + method, + headers: { Authorization: auth, "Content-Type": "application/json" }, + body: body === undefined ? undefined : JSON.stringify(body), + }); + const text = await res.text(); + if (!res.ok) throw new Error(`${method} ${path} -> ${res.status} ${text.slice(0, 200)}`); + return text ? JSON.parse(text) : {}; +} + +async function setup() { + const stream = (await call("POST", "/live/streams", { + playbackSettings: { accessPolicy: "public" }, + inputMediaSettings: { metadata: { name: "sdk-get-validate" }, enableRecording: true }, + })).data; + const streamId: string = stream.streamId ?? stream.id; + const pb = (await call("POST", `/live/streams/${streamId}/playback-ids`, { + accessPolicy: "public", + accessRestrictions: { + domains: { defaultPolicy: "deny", allow: ["example.com"], deny: [] }, + userAgents: { defaultPolicy: "allow", allow: [], deny: [] }, + }, + })).data; + const playbackId: string = pb.id ?? pb.playbackIds?.[0]?.id; + const playlistId: string = (await call("POST", "/on-demand/playlists", { + name: "sdk-get-validate", referenceId: "sdkgetvalidate" + Date.now(), type: "manual", + })).data.id; + const signingKeyId: string = (await call("POST", "/iam/signing-keys", {})).data.id; + const media = ((await call("GET", "/on-demand?limit=50&offset=1")).data as any[]).find((m) => m.status === "Ready"); + if (!media) throw new Error("no Ready media in this workspace; upload one first"); + + const ids: Record = { + "your-stream-id": streamId, "your-livestream-id": streamId, "your-playback-id": playbackId, + "your-playlist-id": playlistId, "your-signing-key-id": signingKeyId, "your-media-id": media.id, + }; + const fixtures = JSON.parse(readFileSync(fixturePath, "utf-8")); + const walk = (v: any): any => + typeof v === "string" ? (ids[v] ?? v) : Array.isArray(v) ? v.map(walk) : + v && typeof v === "object" ? Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x)])) : v; + const filled = walk(fixtures); + // the on-demand playback lookup needs the media's own playback ID, not the stream's + filled.operations["get-playback-id"].pathParams.playbackId = media.playbackIds?.[0]?.id ?? playbackId; + writeFileSync(fixturePath, JSON.stringify(filled, null, 2) + "\n"); + writeFileSync(statePath, JSON.stringify({ streamId, playbackId, playlistId, signingKeyId }, null, 2) + "\n"); + console.log(`fixtures filled: stream=${streamId} playback=${playbackId} playlist=${playlistId} signingKey=${signingKeyId} media=${media.id}`); + console.log("run `npm run validate:get-endpoints`, then `npm run fixtures:teardown`"); +} + +async function teardown() { + if (!existsSync(statePath)) { console.log("nothing to tear down"); return; } + const s = JSON.parse(readFileSync(statePath, "utf-8")); + for (const [m, p] of [ + ["DELETE", `/live/streams/${s.streamId}/playback-ids/${s.playbackId}`], + ["DELETE", `/live/streams/${s.streamId}`], + ["DELETE", `/on-demand/playlists/${s.playlistId}`], + ["DELETE", `/iam/signing-keys/${s.signingKeyId}`], + ]) { + try { await call(m, p); console.log(`deleted ${p}`); } catch (e) { console.warn(String(e)); } + } + unlinkSync(statePath); + execSync("git checkout -- get-endpoints-fixtures.json", { cwd: here, stdio: "inherit" }); + console.log("fixture file restored"); +} + +(process.argv.includes("--teardown") ? teardown() : setup()).catch((e) => { console.error(String(e)); process.exit(1); }); diff --git a/tests/validate-get-endpoints.ts b/tests/validate-get-endpoints.ts index 3da7233..336538a 100644 --- a/tests/validate-get-endpoints.ts +++ b/tests/validate-get-endpoints.ts @@ -12,9 +12,6 @@ * - Generates two markdown reports in `tests/`: * - `GET_ENDPOINTS_OPENAPI_RESPONSE_VALIDATION_REPORT.md` * - `GET_ENDPOINTS_OPENAPI_RESPONSE_FIX_SUGGESTIONS.md` - * - Updates `tests/README.md` by replacing the block between markers: - * - `` - * - `` * * Requirements: * - FASTPIX_USERNAME / FASTPIX_PASSWORD env vars (Basic Auth) @@ -28,7 +25,7 @@ import { spawnSync } from "node:child_process"; import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { createRequire } from "node:module"; -import yaml from "js-yaml"; +import { load as loadYaml } from "js-yaml"; import { invokeJavaSDK, type JavaSDKResult } from "./java-harness.js"; const require = createRequire(import.meta.url); @@ -247,7 +244,7 @@ function resolveSpecPath(): string { // then the known spec filenames at the repo root (parent of tests/). const candidates = [ process.env.FASTPIX_OPENAPI_SPEC, - join(__dirname, "../fixed 7.yaml"), + join(__dirname, "../openapi.yaml"), join(__dirname, "../fastpix.yaml"), join(__dirname, "../../fastpix.yaml"), join(__dirname, "../fixed.yaml"), @@ -265,7 +262,7 @@ function resolveSpecPath(): string { function loadOpenAPISpec(): any { const specPath = resolveSpecPath(); - return yaml.load(readFileSync(specPath, "utf-8")); + return loadYaml(readFileSync(specPath, "utf-8")); } function extractGetEndpoints(spec: any): EndpointInfo[] { @@ -755,7 +752,6 @@ function writeReport(results: EndpointResult[]) { const skipped = 0; const reportPath = join(__dirname, "GET_ENDPOINTS_OPENAPI_RESPONSE_VALIDATION_REPORT.md"); - const readmePath = join(__dirname, "README.md"); const generatedAt = new Date().toISOString(); const lines: string[] = []; @@ -855,55 +851,6 @@ function writeReport(results: EndpointResult[]) { writeFileSync(reportPath, lines.join("\n")); writeFixSuggestions(results); - // Also update tests/README.md with the consolidated report section so it always stays in sync. - try { - if (existsSync(readmePath)) { - const begin = ""; - const end = ""; - - const consolidated: string[] = []; - consolidated.push(`Last generated: ${generatedAt}`); - consolidated.push(""); - consolidated.push(`- **Total GET endpoints**: ${total}`); - consolidated.push(`- **PASS**: ${passed}`); - consolidated.push(`- **FAIL**: ${failed}`); - consolidated.push(`- **SKIP**: ${skipped}`); - consolidated.push(""); - consolidated.push("| Endpoint | OperationId | OpenAPI valid | SDK parse | Missing in SDK (present in API) | Missing in API (present in SDK) | Empty arrays omitted by SDK | Status |"); - consolidated.push("|---|---|---:|---:|---|---|---|---|"); - for (const r of results) { - const openapiCol = r.openapiValid ? "✅" : "❌"; - const sdkCol = r.sdkParseOk ? "✅" : "❌"; - const missSdk = r.missingInSDK.length ? r.missingInSDK.map((p) => `\`${p}\``).join(", ") : "None"; - const missApi = r.missingInAPI.length ? r.missingInAPI.map((p) => `\`${p}\``).join(", ") : "None"; - const emptyOmitted = r.emptyArraysOmittedInSDK.length ? r.emptyArraysOmittedInSDK.map((p) => `\`${p}\``).join(", ") : "None"; - const status = r.status === "PASS" ? "✅ PASS" : "❌ FAIL"; - consolidated.push(`| \`${r.endpoint}\` | \`${r.operationId}\` | ${openapiCol} | ${sdkCol} | ${missSdk} | ${missApi} | ${emptyOmitted} | ${status} |`); - } - consolidated.push(""); - consolidated.push("#### Missing fields (full lists)"); - consolidated.push(""); - for (const r of results) { - consolidated.push(`- **${r.operationId}** (\`${r.endpoint}\`)`); - consolidated.push(` - **Missing in SDK (present in API)**: ${r.missingInSDK.length ? r.missingInSDK.map((p) => `\`${p}\``).join(", ") : "None"}`); - consolidated.push(` - **Missing in API (present in SDK)**: ${r.missingInAPI.length ? r.missingInAPI.map((p) => `\`${p}\``).join(", ") : "None"}`); - consolidated.push(` - **Empty arrays omitted by SDK**: ${r.emptyArraysOmittedInSDK.length ? r.emptyArraysOmittedInSDK.map((p) => `\`${p}\``).join(", ") : "None"}`); - consolidated.push(` - **Empty arrays omitted by API**: ${r.emptyArraysOmittedInAPI.length ? r.emptyArraysOmittedInAPI.map((p) => `\`${p}\``).join(", ") : "None"}`); - } - consolidated.push(""); - consolidated.push(`Full details: \`tests/GET_ENDPOINTS_OPENAPI_RESPONSE_VALIDATION_REPORT.md\``); - - const readme = readFileSync(readmePath, "utf-8"); - if (readme.includes(begin) && readme.includes(end)) { - const block = `${begin}\n${consolidated.join("\n")}\n${end}`; - const updated = readme.replace(new RegExp(`${begin}[\\s\\S]*?${end}`), block); - writeFileSync(readmePath, updated); - } - } - } catch { - // ignore README update failures - } - // eslint-disable-next-line no-console console.log(`Report generated: ${reportPath}`); // eslint-disable-next-line no-console diff --git a/tests/validate-non-get-endpoints.ts b/tests/validate-non-get-endpoints.ts index a1d2eae..1f3165f 100644 --- a/tests/validate-non-get-endpoints.ts +++ b/tests/validate-non-get-endpoints.ts @@ -34,7 +34,7 @@ import { spawnSync } from "node:child_process"; import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { createRequire } from "node:module"; -import yaml from "js-yaml"; +import { load as loadYaml } from "js-yaml"; const require = createRequire(import.meta.url); const openapiResponseValidatorMod = require("openapi-response-validator"); @@ -197,7 +197,7 @@ async function waitForTrackReady( function resolveSpecPath(): string { const candidates = [ process.env.FASTPIX_OPENAPI_SPEC, - join(__dirname, "../fixed 7.yaml"), + join(__dirname, "../openapi.yaml"), join(__dirname, "../fastpix.yaml"), join(__dirname, "../fixed.yaml"), join(__dirname, "../fastpix-openapi.yaml"), @@ -208,7 +208,7 @@ function resolveSpecPath(): string { } function loadOpenAPISpec(): any { - return yaml.load(readFileSync(resolveSpecPath(), "utf-8")); + return loadYaml(readFileSync(resolveSpecPath(), "utf-8")); } function extractNonGetEndpoints(spec: any): Map { @@ -338,6 +338,8 @@ const STEPS: Step[] = [ { operationId: "add-media-to-playlist", phase: "UPDATE", needs: ["playlistId", "mediaId"], request: (c) => ({ playlistId: c.playlistId, mediaId: c.mediaId }) }, { operationId: "change-media-order-in-playlist", phase: "UPDATE", needs: ["playlistId", "mediaId"], request: (c) => ({ playlistId: c.playlistId, mediaId: c.mediaId }) }, { operationId: "update-live-stream", phase: "UPDATE", needs: ["streamId"], request: (c) => ({ streamId: c.streamId }) }, + { operationId: "update-live-stream-domain-restrictions", phase: "UPDATE", needs: ["streamId", "streamPlaybackId"], request: (c) => ({ streamId: c.streamId, playbackId: c.streamPlaybackId }) }, + { operationId: "update-live-stream-user-agent-restrictions", phase: "UPDATE", needs: ["streamId", "streamPlaybackId"], request: (c) => ({ streamId: c.streamId, playbackId: c.streamPlaybackId }) }, { operationId: "update-specific-simulcast-of-stream", phase: "UPDATE", needs: ["streamId", "simulcastId"], request: (c) => ({ streamId: c.streamId, simulcastId: c.simulcastId }) }, // a freshly-created stream is already enabled, so disable first, then enable. { operationId: "disable-live-stream", phase: "UPDATE", needs: ["streamId"], request: (c) => ({ streamId: c.streamId }) },