diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..10a0653 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: ci + +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 15 + container: maven:3.9-eclipse-temurin-17 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Tools for the generator step + run: | + apt-get update -qq + apt-get install -y -qq --no-install-recommends git python3 python3-yaml + git config --global --add safe.directory "$GITHUB_WORKSPACE" + - name: Generated code is up to date + run: | + python3 scripts/gen_operations.py + mvn -B -q -Pgenerate generate-sources + rm -rf api gradle + git diff --exit-code -- src/main/java + - run: mvn -B test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f1f74ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +target/ +build/ +.openapi-generator/ +.idea/ +*.iml +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..985f07f --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# sdk-java + +Java client for the sitewarm API. Models in [`com.sitewarm.sdk.model`](src/main/java/com/sitewarm/sdk/model) are generated from the OpenAPI 3.1 spec in [`openapi/openapi.yaml`](openapi/openapi.yaml) with [OpenAPI Generator](https://openapi-generator.tech); the client (`SiteWarm`) is hand-written on `java.net.http`. Java 17+. Runtime dependency: Jackson. + +**Status: pre-release (`0.1.0-SNAPSHOT`, nothing published).** The API and this client can still change. The spec describes the whole planned surface; the service may not offer every operation yet. + +```java +SiteWarm c = SiteWarm.builder(System.getenv("SITEWARM_API_KEY"), "https:///v1").build(); + +Site site = c.sites.create(new SiteCreate().hostname("example.com")); +WarmRun run = c.warmRuns.create(site.getId(), new WarmRunCreate()); +WarmRun done = c.warmRuns.waitFor(run.getId(), Duration.ofMinutes(10), Duration.ofSeconds(2)); +for (Result r : c.warmRuns.results(done.getId(), "miss")) { + System.out.println(r.getUrl()); +} +``` + +A site must be verified before a run is accepted; verification happens outside this API. + +## Surface + +- `c.sites` (`get`, `create`, `all`) and `c.warmRuns` (`create`, `get`, `cancel`, `results`, `waitFor`). +- Every operation of the spec is reachable with `c.call("", Request.of().withPath(...).withBody(...))`; `c.items(...)` iterates list operations (cursors are opaque). The operation table (`Operations`) is generated and a test checks it against the spec. +- Webhook callbacks are server-to-customer and not covered. + +## Behavior + +- **Auth**: `Authorization: Bearer `. The key is not in `toString()`, exception messages or logs (the SDK never logs), and the client is not `Serializable`. The base URL must be https (http only for localhost) with no credentials or query. The SDK builds its own `HttpClient` with redirects disabled (there is no way to pass one in), so the key never goes to another origin; a 3xx is thrown as `SiteWarmException.Api`. +- **No default base URL**: pass the API host you were given. +- **Retries**: up to 3 (`maxRetries`; a negative value keeps the default) on `429`, `5xx` (not `501`) and network errors, exponential backoff with equal jitter, capped at 30 s. `Retry-After` is honored with a floor of the retry base delay and up to +25% jitter; if it exceeds the cap the error is thrown instead of sleeping. `429` is always retried; `5xx`, network errors and a response body that breaks off only when repeating is safe (`GET`, `HEAD`, `PUT`, `OPTIONS`, or a POST with an `Idempotency-Key`; never `DELETE`/`PATCH`). `timeout(null / zero / negative)` keeps the default (30 s). +- **Idempotency**: every POST that accepts `Idempotency-Key` sends one (random UUID unless you pass one), generated once per call and reused by its retries, so a retried `warmRuns.create` never starts two runs. +- **Limits**: response bodies over 32 MiB throw `SiteWarmException.ResponseTooLarge` (not retried); item iteration throws on a repeated cursor or after 10,000 pages instead of stopping silently; a `limit` query value outside 1..100 throws before the request (empty or 0 = server default). +- **More retry rules**: a `409` `conflict` on a keyed POST is retried (the first attempt may still be running); `idempotency-key-reused` never. Certificate verification failures, unknown hosts and malformed requests (invalid header or URL) are not retried; other network errors are. +- **User-Agent**: `sitewarm-java/ (+https://github.com/sitewarm/sdk-java)`; `userAgent(null or "")` keeps it. +- **Errors**: `SiteWarmException.Api` (`status()`, `kind()`, RFC 9457 `code()`, `retryAfter()`, `rateLimitRemaining()`), `SiteWarmException.Connection`, `SiteWarmException.Decode` (`status()`) for a 2xx body that is not JSON (the body is never included), and `SiteWarmException.WaitTimeout` from `waitFor`, which does not cancel the run. + +## Development + +Build and test with Maven, or in Docker with no local JDK: + +``` +docker run --rm -v "$PWD":/work -w /work maven:3.9-eclipse-temurin-17 mvn -B test +``` + +To regenerate after changing `openapi/openapi.yaml` (needs Python 3 with PyYAML): + +``` +python3 scripts/gen_operations.py && mvn -B -Pgenerate generate-sources +``` + +CI fails if the generated sources are out of date. + +## License + +Apache-2.0, see [LICENSE](LICENSE). diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml new file mode 100644 index 0000000..95445e3 --- /dev/null +++ b/openapi/openapi.yaml @@ -0,0 +1,2713 @@ +openapi: 3.1.0 +info: + title: sitewarm public API + version: 0.1.0 + summary: Manage sites, warm runs, schedules, webhooks and API keys of the hosted sitewarm service. + description: | + This document is the source of truth for the public REST API; the server, the SDKs and the contract + tests are built from it. + + ## Vocabulary + + A **site** is one hostname. A **vantage + point** is the place a run's requests are sent from (`region` is an attribute of it). The + **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry + the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a + cache state. + + ## Conventions + + - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. + - **Authentication.** Every operation takes a scoped API key as a bearer token + (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the + scope it needs. A request for a resource of another organization returns `404`, not `403`. + - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the + same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a + different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires + the header; the other `POST` operations accept it. + - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous + page. Clients must not parse cursors. + - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI + reference naming one of the problem types listed in `ProblemType`. + - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and + `RateLimit-Reset`. A `429` also carries `Retry-After`. + - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at + the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. + - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. + - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings + such as `10s` or `5m`, as in the CLI. + - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a + customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` + are returned as observed. + - **Safety.** A site must be verified before any run. Triggering a run for an unverified + or paused site is rejected with a problem. + contact: + name: sitewarm + url: https://github.com/sitewarm + license: + name: Apache-2.0 + identifier: Apache-2.0 +servers: + - url: /api/v1 + description: | + Relative to the host that serves the API. + +tags: + - name: Sites + description: Hostnames the organization owns, and their sitemaps and URL sets. + - name: Warm runs + description: Warm and verify runs, their status and their results. + - name: Cache status reports + description: Cache status per route group and vantage point, derived from warm runs. + - name: Schedules + description: Recurring warm runs. + - name: Webhooks + description: Outbound event subscriptions signed with HMAC. + - name: API keys + description: Scoped credentials for this API. +security: + - ApiKey: [] +paths: + /sites: + get: + operationId: listSites + summary: List sites + tags: [Sites] + security: + - ApiKey: [sites:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + responses: + '200': + description: A page of sites. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/SiteList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + post: + operationId: createSite + summary: Create a site + description: | + Creates an unverified site. Verification is done outside this API; until it passes, runs for + the site are rejected (`site-not-verified`). A site is one hostname: the apex and its `www` are + the same site. + tags: [Sites] + security: + - ApiKey: [sites:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SiteCreate' + responses: + '201': + description: The site was created. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/Site' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}: + parameters: + - $ref: '#/components/parameters/SiteId' + get: + operationId: getSite + summary: Get a site + tags: [Sites] + security: + - ApiKey: [sites:read] + responses: + '200': + description: The site. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/Site' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + patch: + operationId: updateSite + summary: Update site settings + tags: [Sites] + security: + - ApiKey: [sites:write] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SiteUpdate' + responses: + '200': + description: The updated site. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/Site' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + delete: + operationId: deleteSite + summary: Delete a site and its history + description: Deletes the site, its sitemaps, URL sets, schedules and stored results. + tags: [Sites] + security: + - ApiKey: [sites:write] + responses: + '204': + description: The site was deleted. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}/sitemaps: + parameters: + - $ref: '#/components/parameters/SiteId' + get: + operationId: listSitemaps + summary: List the sitemaps of a site + tags: [Sites] + security: + - ApiKey: [sites:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + responses: + '200': + description: A page of sitemaps. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/SitemapList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + post: + operationId: createSitemap + summary: Register a sitemap + description: The sitemap URL must be on the site's hostname. Sitemap indexes and `.gz` files are accepted. + tags: [Sites] + security: + - ApiKey: [sites:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SitemapCreate' + responses: + '201': + description: The sitemap was registered. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/Sitemap' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}/sitemaps/{sitemapId}: + parameters: + - $ref: '#/components/parameters/SiteId' + - $ref: '#/components/parameters/SitemapId' + get: + operationId: getSitemap + summary: Get a sitemap + tags: [Sites] + security: + - ApiKey: [sites:read] + responses: + '200': + description: The sitemap. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/Sitemap' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + delete: + operationId: deleteSitemap + summary: Remove a sitemap + tags: [Sites] + security: + - ApiKey: [sites:write] + responses: + '204': + description: The sitemap was removed. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}/url-sets: + parameters: + - $ref: '#/components/parameters/SiteId' + get: + operationId: listUrlSets + summary: List the URL sets of a site + description: | + A URL set is an explicit, ordered list of URLs, the hosted equivalent of the CLI's `--top-from` + file. The order is the warming priority. + tags: [Sites] + security: + - ApiKey: [sites:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + responses: + '200': + description: A page of URL sets (without their URLs). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/UrlSetList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + post: + operationId: createUrlSet + summary: Create a URL set + tags: [Sites] + security: + - ApiKey: [sites:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UrlSetWrite' + responses: + '201': + description: The URL set was created. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/UrlSet' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}/url-sets/{urlSetId}: + parameters: + - $ref: '#/components/parameters/SiteId' + - $ref: '#/components/parameters/UrlSetId' + get: + operationId: getUrlSet + summary: Get a URL set with its URLs + tags: [Sites] + security: + - ApiKey: [sites:read] + responses: + '200': + description: The URL set. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/UrlSet' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + put: + operationId: replaceUrlSet + summary: Replace a URL set + tags: [Sites] + security: + - ApiKey: [sites:write] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UrlSetWrite' + responses: + '200': + description: The replaced URL set. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/UrlSet' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + delete: + operationId: deleteUrlSet + summary: Delete a URL set + tags: [Sites] + security: + - ApiKey: [sites:write] + responses: + '204': + description: The URL set was deleted. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}/warm-runs: + parameters: + - $ref: '#/components/parameters/SiteId' + get: + operationId: listWarmRuns + summary: List warm runs of a site + tags: [Warm runs] + security: + - ApiKey: [warm-runs:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + - name: status + in: query + description: Only runs in this lifecycle status. + schema: + $ref: '#/components/schemas/RunStatus' + - name: trigger_type + in: query + description: Only runs started this way. + schema: + $ref: '#/components/schemas/TriggerType' + responses: + '200': + description: A page of warm runs, newest first. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/WarmRunList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + post: + operationId: createWarmRun + summary: Start a warm run (for example after a deploy) + description: | + Queues a run that warms and verifies the URLs of one source, from the vantage points the + organization is entitled to, and answers `202`. Poll `GET /warm-runs/{runId}` (the `Location` + header) until `status` is `completed` or `canceled`, then read `outcome` and the results. + + The run is rejected if the site is not verified (`site-not-verified`), is paused (`site-paused`), + or the organization is over a limit (`quota-exceeded`). + + `source` may be omitted: the run then warms the URLs of the site's discovered sitemaps + (`robots.txt` and `/sitemap.xml`). In the current implementation `source` of type `sitemap` or + `url_set`, `vantage_point_ids` and every option other than `top` and `fail_on` answer `422` + (`validation-failed`) with a JSON Pointer; they are never ignored silently. Only one run per + site may be queued or running (`conflict`). + + `Idempotency-Key` is required: a retried trigger from CI must not start a second run. + + tags: [Warm runs] + security: + - ApiKey: [warm-runs:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKeyRequired' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WarmRunCreate' + examples: + afterDeploy: + summary: Warm the sitemap after a production deploy + value: + source: + type: sitemap + sitemap_id: sm_example + deployment: + id: deploy-1234 + environment: production + ref: 0123abcd + options: + fail_on: [miss, error, noindex] + responses: + '202': + description: The run was accepted and queued. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Retry-After: + $ref: '#/components/headers/RetryAfter' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/WarmRun' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /warm-runs/{runId}: + parameters: + - $ref: '#/components/parameters/RunId' + get: + operationId: getWarmRun + summary: Get a warm run (status resource) + description: | + While the run is `queued` or `running` the response carries `Retry-After` with the suggested + polling delay. `outcome` is null until the run is `completed`. + tags: [Warm runs] + security: + - ApiKey: [warm-runs:read] + responses: + '200': + description: The warm run, with a per-vantage-point summary. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Retry-After: + $ref: '#/components/headers/RetryAfter' + content: + application/json: + schema: + $ref: '#/components/schemas/WarmRun' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /warm-runs/{runId}/cancel: + parameters: + - $ref: '#/components/parameters/RunId' + post: + operationId: cancelWarmRun + summary: Cancel a warm run + description: | + Asks the vantage points to stop. URLs not requested yet are recorded as `incomplete`. Answers + `202`; the run becomes `canceled` once every vantage point has stopped. Cancelling a run that is + already `completed` or `canceled` is a no-op that returns `202` with the current state. + tags: [Warm runs] + security: + - ApiKey: [warm-runs:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + responses: + '202': + description: Cancellation was requested. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Retry-After: + $ref: '#/components/headers/RetryAfter' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/WarmRun' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /warm-runs/{runId}/results: + parameters: + - $ref: '#/components/parameters/RunId' + get: + operationId: listWarmRunResults + summary: List per-URL results of a warm run + description: | + One result per URL, profile and vantage point. Results of a run that is still in progress are + partial and may change until the run is `completed`. + tags: [Warm runs] + security: + - ApiKey: [warm-runs:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + - name: final_state + in: query + description: Only results whose final cache status is this state. + schema: + $ref: '#/components/schemas/CacheState' + - name: vantage_point_id + in: query + description: Only results observed from this vantage point. + schema: + type: string + - name: profile + in: query + description: Only results for this request profile (for example `desktop` or `mobile`). + schema: + type: string + - name: url + in: query + description: Only the results of this exact URL. + schema: + type: string + format: uri + - name: route_group + in: query + description: Only results in this route group. + schema: + type: string + responses: + '200': + description: A page of results. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/ResultList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}/cache-status-reports: + parameters: + - $ref: '#/components/parameters/SiteId' + get: + operationId: listCacheStatusReports + summary: List cache status reports of a site + description: One report per completed warm run, newest first. + tags: [Cache status reports] + security: + - ApiKey: [cache-reports:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + - name: warm_run_id + in: query + description: Only the report of this warm run. + schema: + type: string + responses: + '200': + description: A page of report summaries (without cells). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/CacheStatusReportList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /cache-status-reports/{reportId}: + parameters: + - $ref: '#/components/parameters/ReportId' + get: + operationId: getCacheStatusReport + summary: Get a cache status report + tags: [Cache status reports] + security: + - ApiKey: [cache-reports:read] + responses: + '200': + description: The report, with one cell per route group and vantage point. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/CacheStatusReport' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /sites/{siteId}/schedules: + parameters: + - $ref: '#/components/parameters/SiteId' + get: + operationId: listSchedules + summary: List schedules of a site + tags: [Schedules] + security: + - ApiKey: [schedules:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + responses: + '200': + description: A page of schedules. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/ScheduleList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + post: + operationId: createSchedule + summary: Create a schedule + description: The cadence is validated against the organization's limits (`quota-exceeded`). + tags: [Schedules] + security: + - ApiKey: [schedules:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ScheduleCreate' + responses: + '201': + description: The schedule was created. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/Schedule' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /schedules/{scheduleId}: + parameters: + - $ref: '#/components/parameters/ScheduleId' + get: + operationId: getSchedule + summary: Get a schedule + tags: [Schedules] + security: + - ApiKey: [schedules:read] + responses: + '200': + description: The schedule. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/Schedule' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + patch: + operationId: updateSchedule + summary: Update a schedule + tags: [Schedules] + security: + - ApiKey: [schedules:write] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ScheduleUpdate' + responses: + '200': + description: The updated schedule. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/Schedule' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + delete: + operationId: deleteSchedule + summary: Delete a schedule + tags: [Schedules] + security: + - ApiKey: [schedules:write] + responses: + '204': + description: The schedule was deleted. Runs already started are not affected. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /webhooks: + get: + operationId: listWebhooks + summary: List webhook endpoints + tags: [Webhooks] + security: + - ApiKey: [webhooks:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + responses: + '200': + description: A page of webhook endpoints (secrets are never listed). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + post: + operationId: createWebhook + summary: Create a webhook endpoint + description: | + The signing secret is returned once, in this response. Keep it: it cannot be read again, only + replaced with `rotateWebhookSecret`. + tags: [Webhooks] + security: + - ApiKey: [webhooks:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookCreate' + responses: + '201': + description: The endpoint was created. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookWithSecret' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /webhooks/{webhookId}: + parameters: + - $ref: '#/components/parameters/WebhookId' + get: + operationId: getWebhook + summary: Get a webhook endpoint + tags: [Webhooks] + security: + - ApiKey: [webhooks:read] + responses: + '200': + description: The endpoint. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/Webhook' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + patch: + operationId: updateWebhook + summary: Update a webhook endpoint + tags: [Webhooks] + security: + - ApiKey: [webhooks:write] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookUpdate' + responses: + '200': + description: The updated endpoint. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/Webhook' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + delete: + operationId: deleteWebhook + summary: Delete a webhook endpoint + tags: [Webhooks] + security: + - ApiKey: [webhooks:write] + responses: + '204': + description: The endpoint was deleted. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /webhooks/{webhookId}/rotate-secret: + parameters: + - $ref: '#/components/parameters/WebhookId' + post: + operationId: rotateWebhookSecret + summary: Replace the signing secret of a webhook endpoint + description: | + Returns the new secret once. + tags: [Webhooks] + security: + - ApiKey: [webhooks:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + responses: + '200': + description: The endpoint with its new secret. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookWithSecret' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /api-keys: + get: + operationId: listApiKeys + summary: List API keys + tags: [API keys] + security: + - ApiKey: [api-keys:read] + parameters: + - $ref: '#/components/parameters/Cursor' + - $ref: '#/components/parameters/Limit' + responses: + '200': + description: A page of API keys (secrets are never listed). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/ApiKeyList' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + post: + operationId: createApiKey + summary: Create an API key + description: | + The key secret is returned once, in this response. The scopes of the new key must be a subset of + the scopes of the calling key (`scope-not-allowed` otherwise). If the calling key has an + `expires_at`, the new key must set `expires_at` no later than it (`scope-not-allowed` otherwise): + a key cannot mint a credential that outlives itself. The first key of an organization is created + in the panel, not through this API. + tags: [API keys] + security: + - ApiKey: [api-keys:write] + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ApiKeyCreate' + responses: + '201': + description: The key was created. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Location: + $ref: '#/components/headers/Location' + Idempotent-Replayed: + $ref: '#/components/headers/IdempotentReplayed' + content: + application/json: + schema: + $ref: '#/components/schemas/ApiKeyWithSecret' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/Unprocessable' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + /api-keys/{apiKeyId}: + parameters: + - $ref: '#/components/parameters/ApiKeyId' + get: + operationId: getApiKey + summary: Get an API key + tags: [API keys] + security: + - ApiKey: [api-keys:read] + responses: + '200': + description: The key metadata. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/json: + schema: + $ref: '#/components/schemas/ApiKey' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' + delete: + operationId: revokeApiKey + summary: Revoke an API key + description: Revocation is immediate and permanent. A key can revoke itself. + tags: [API keys] + security: + - ApiKey: [api-keys:write] + responses: + '204': + description: The key was revoked. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalError' +webhooks: + warmRunCompleted: + post: + operationId: onWarmRunCompleted + summary: A warm run finished + description: | + Sent when a run becomes `completed`, with its `outcome`. Use it to gate a pipeline without + polling. + + **Signature.** Each delivery carries `Sitewarm-Signature: t=,v1=`, where + `` is HMAC-SHA256, keyed with the endpoint secret, over the string + `.`. Verify it against the raw bytes, compare in constant time, and reject + a timestamp that is too old. A 2xx response acknowledges the delivery; other responses and + timeouts are retried. + tags: [Webhooks] + security: [] + parameters: + - $ref: '#/components/parameters/SignatureHeader' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WarmRunCompletedEvent' + responses: + '200': + description: Delivery acknowledged. + warmRunCanceled: + post: + operationId: onWarmRunCanceled + summary: A warm run was canceled + description: Sent when a run becomes `canceled`. Signed like every webhook delivery. + tags: [Webhooks] + security: [] + parameters: + - $ref: '#/components/parameters/SignatureHeader' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WarmRunCanceledEvent' + responses: + '200': + description: Delivery acknowledged. + siteVerificationChanged: + post: + operationId: onSiteVerificationChanged + summary: A site became verified or lost its verification + description: | + Sent when the verification status of a site changes. When a site stops being verified its jobs + are stopped. Signed like every webhook delivery. + tags: [Webhooks] + security: [] + parameters: + - $ref: '#/components/parameters/SignatureHeader' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SiteVerificationChangedEvent' + responses: + '200': + description: Delivery acknowledged. +components: + securitySchemes: + ApiKey: + type: http + scheme: bearer + bearerFormat: sitewarm API key + description: | + A scoped API key sent as `Authorization: Bearer `. Operations name the scope they need in + their `security` requirement. Session cookies are not accepted. Scopes: + `sites:read`, `sites:write`, `warm-runs:read`, `warm-runs:write`, `cache-reports:read`, + `schedules:read`, `schedules:write`, `webhooks:read`, `webhooks:write`, `api-keys:read`, + `api-keys:write`. + parameters: + Cursor: + name: cursor + in: query + description: Opaque cursor from `page.next_cursor` of the previous page. Omit for the first page. + schema: + type: string + Limit: + name: limit + in: query + description: | + Maximum number of items in the page. The server may return fewer. Default 20, maximum 100. + + schema: + type: integer + minimum: 1 + maximum: 100 + default: 20 + IdempotencyKey: + name: Idempotency-Key + in: header + required: false + description: | + Client-chosen unique value for this request (a random UUID is a good choice). A retry with the + same key and body returns the first response. + schema: + type: string + minLength: 1 + maxLength: 255 + IdempotencyKeyRequired: + name: Idempotency-Key + in: header + required: true + description: | + Client-chosen unique value for this request (a random UUID is a good choice). A retry with the + same key and body returns the first response and does not start a second run. + schema: + type: string + minLength: 1 + maxLength: 255 + SignatureHeader: + name: Sitewarm-Signature + in: header + required: true + description: '`t=,v1=.">`.' + schema: + type: string + SiteId: + name: siteId + in: path + required: true + schema: + type: string + SitemapId: + name: sitemapId + in: path + required: true + schema: + type: string + UrlSetId: + name: urlSetId + in: path + required: true + schema: + type: string + RunId: + name: runId + in: path + required: true + schema: + type: string + ReportId: + name: reportId + in: path + required: true + schema: + type: string + ScheduleId: + name: scheduleId + in: path + required: true + schema: + type: string + WebhookId: + name: webhookId + in: path + required: true + schema: + type: string + ApiKeyId: + name: apiKeyId + in: path + required: true + schema: + type: string + headers: + RateLimit-Limit: + description: Requests allowed in the current window. + schema: + type: integer + RateLimit-Remaining: + description: Requests left in the current window. + schema: + type: integer + RateLimit-Reset: + description: Seconds until the current window resets. + schema: + type: integer + RetryAfter: + description: Seconds to wait before polling or retrying. + schema: + type: integer + minimum: 0 + Location: + description: URL of the created resource or of the status resource to poll. + schema: + type: string + format: uri-reference + IdempotentReplayed: + description: '`true` when this response replays the first response for the same Idempotency-Key.' + schema: + type: boolean + responses: + BadRequest: + description: The request is malformed (`invalid-request`, `idempotency-key-missing`). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + Unauthorized: + description: Missing, invalid, expired or revoked API key (`unauthorized`). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + Forbidden: + description: | + The key lacks the scope or is not allowed to use the site (`insufficient-scope`, + `scope-not-allowed`), or the organization is not entitled to the feature (`not-entitled`). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + NotFound: + description: The resource does not exist or belongs to another organization (`not-found`). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + Conflict: + description: | + The request conflicts with the current state (`conflict`, `idempotency-key-reused`, + `site-not-verified`, `site-paused`). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + Unprocessable: + description: | + The body is well formed but not acceptable (`validation-failed`, `quota-exceeded`). + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + InternalError: + description: | + Unexpected server error (`internal-error`). The body is a problem document with no detail: nothing about the + request, the data or the cause is echoed. Retrying is safe for reads; for `createWarmRun` retry with the + same `Idempotency-Key`. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + TooManyRequests: + description: Rate limit reached (`rate-limited`). Wait for `Retry-After` seconds. + headers: + RateLimit-Limit: + $ref: '#/components/headers/RateLimit-Limit' + RateLimit-Remaining: + $ref: '#/components/headers/RateLimit-Remaining' + RateLimit-Reset: + $ref: '#/components/headers/RateLimit-Reset' + Retry-After: + $ref: '#/components/headers/RetryAfter' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + schemas: + Problem: + type: object + description: RFC 9457 problem details. + required: [type, title, status] + properties: + type: + type: string + format: uri-reference + description: | + Identifies the problem type; one of `ProblemType`, as a URI reference such as + `/problems/site-not-verified`. + examples: + - /problems/site-not-verified + code: + $ref: '#/components/schemas/ProblemType' + title: + type: string + status: + type: integer + detail: + type: string + instance: + type: string + format: uri-reference + errors: + type: array + description: Field errors, present for `validation-failed` and `invalid-request`. + items: + type: object + required: [pointer, detail] + properties: + pointer: + type: string + description: JSON Pointer to the offending member. + detail: + type: string + limit: + type: string + description: For `quota-exceeded`, the name of the limit that was reached (for example `sites`). + plan: + type: string + description: For `quota-exceeded`, the organization's plan as an opaque label. + additionalProperties: true + ProblemType: + type: string + description: Documented problem type slugs. Clients must tolerate new values. + enum: + - invalid-request + - validation-failed + - idempotency-key-missing + - idempotency-key-reused + - unauthorized + - insufficient-scope + - scope-not-allowed + - not-entitled + - not-found + - conflict + - site-not-verified + - site-paused + - quota-exceeded + - rate-limited + - internal-error + PageInfo: + type: object + required: [has_more, next_cursor] + properties: + has_more: + type: boolean + next_cursor: + type: [string, 'null'] + description: Cursor for the next page; null on the last page. + Scope: + type: string + enum: + - sites:read + - sites:write + - warm-runs:read + - warm-runs:write + - cache-reports:read + - schedules:read + - schedules:write + - webhooks:read + - webhooks:write + - api-keys:read + - api-keys:write + CacheState: + type: string + description: | + Normalized cache status of one URL and profile at one vantage point, exactly the engine states. + `unknown` means the CDN does not expose a status (see `unknown_reason`). Clients must tolerate + new values. + enum: + - hit + - stale + - miss + - bypass + - variant-unverifiable + - challenged + - client-error + - redirect-error + - error + - incomplete + - unknown + - skipped-robots + - stale-revision + - expected + - unexpected + FailOnToken: + description: | + A value accepted by the engine's `--fail-on`: any cache state, or an indexability token. + `noindex` also fails on `indexability-error`. + anyOf: + - $ref: '#/components/schemas/CacheState' + - type: string + enum: + - noindex + - indexability-inconclusive + UnknownReason: + type: string + description: | + Why a state is `unknown`. + + enum: + - cdn-hidden + - region-unavailable + Indexability: + type: object + description: Indexability is separate from the cache state. + properties: + finding: + type: [string, 'null'] + enum: [noindex, indexability-error, indexability-inconclusive, null] + description: The engine's finding; null when none was reported. + meta_robots: + type: [string, 'null'] + x_robots_tag: + type: [string, 'null'] + canonical: + type: [string, 'null'] + RunStatus: + type: string + description: | + Lifecycle of a run. Whether the run passed is `outcome`, not the status. `failed` means the + run itself broke (see `error_code`); it is never a verdict about the site. + + enum: [queued, running, completed, canceled, failed] + TriggerType: + type: string + enum: [api, schedule, panel] + Trigger: + type: object + required: [type] + properties: + type: + $ref: '#/components/schemas/TriggerType' + schedule_id: + type: [string, 'null'] + api_key_id: + type: [string, 'null'] + Deployment: + type: object + description: Context of the deploy that caused the run, echoed to the results and webhooks. + properties: + id: + type: string + environment: + type: string + ref: + type: string + description: Commit SHA, tag or other revision label. + Site: + type: object + required: [id, hostname, verification, created_at] + properties: + id: + type: string + hostname: + type: string + description: The site's hostname; apex and `www` are the same site. + verification: + type: object + description: Read-only. Verification is done outside this API. + required: [status] + properties: + status: + type: string + description: | + `verified` only while the proof is valid. A pending, expired or lapsed proof is + `unverified`. + enum: [unverified, verified] + verified_at: + type: [string, 'null'] + format: date-time + paused: + type: boolean + description: | + Read-only here. A paused site gets no new jobs. Omitted until sites can be paused. + + settings: + $ref: '#/components/schemas/SiteSettings' + description: Omitted until site settings are stored. + created_at: + type: string + format: date-time + SiteSettings: + type: object + properties: + device_variants: + type: boolean + description: | + The operator declares that the CDN segments the cache by device, so affected URLs are + reported `variant-unverifiable`. + SiteCreate: + type: object + required: [hostname] + properties: + hostname: + type: string + settings: + $ref: '#/components/schemas/SiteSettings' + SiteUpdate: + type: object + properties: + settings: + $ref: '#/components/schemas/SiteSettings' + SiteList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/Site' + page: + $ref: '#/components/schemas/PageInfo' + Sitemap: + type: object + required: [id, site_id, url, created_at] + properties: + id: + type: string + site_id: + type: string + url: + type: string + format: uri + created_at: + type: string + format: date-time + SitemapCreate: + type: object + required: [url] + properties: + url: + type: string + format: uri + SitemapList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/Sitemap' + page: + $ref: '#/components/schemas/PageInfo' + UrlSet: + type: object + required: [id, site_id, name, url_count, created_at] + properties: + id: + type: string + site_id: + type: string + name: + type: string + url_count: + type: integer + minimum: 0 + urls: + type: array + description: The URLs in warming priority order. Returned by `getUrlSet`, omitted in lists. + items: + type: string + format: uri + created_at: + type: string + format: date-time + UrlSetWrite: + type: object + required: [name, urls] + properties: + name: + type: string + urls: + type: array + description: Absolute URLs on the site's hostname, in priority order. + items: + type: string + format: uri + UrlSetList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/UrlSet' + page: + $ref: '#/components/schemas/PageInfo' + RunSourceSitemap: + type: object + required: [type, sitemap_id] + properties: + type: + const: sitemap + sitemap_id: + type: string + RunSourceUrlSet: + type: object + required: [type, url_set_id] + properties: + type: + const: url_set + url_set_id: + type: string + RunSource: + description: Exactly one source of URLs per run, as in the engine. + oneOf: + - $ref: '#/components/schemas/RunSourceSitemap' + - $ref: '#/components/schemas/RunSourceUrlSet' + discriminator: + propertyName: type + mapping: + sitemap: '#/components/schemas/RunSourceSitemap' + url_set: '#/components/schemas/RunSourceUrlSet' + RunOptions: + type: object + description: | + Engine options for a run. Every field is optional; an omitted field takes the engine or + organization default, which this document does not define. + properties: + top: + type: integer + minimum: 1 + description: Use only the first N URLs of the source, in its order. + fail_on: + type: array + uniqueItems: true + description: | + Cache states and indexability tokens that make the run fail. Omitted means the engine + default. An empty array means nothing fails the run (the "no verification" rule still + applies). + items: + $ref: '#/components/schemas/FailOnToken' + expect_revision_header: + type: string + description: '`NAME=VALUE`. Each verified response must carry this revision, otherwise `stale-revision`.' + examples: + - X-Build-Id=0123abcd + wait_for_header: + type: string + description: '`NAME=VALUE`. Wait until the site serves this header before warming.' + wait_for_url: + type: string + format: uri + description: Wait until this URL is live (use with `expect_text`) before warming. + expect_text: + type: string + settle: + type: string + description: Fixed delay before warming, such as `30s`. + max_wait: + type: string + description: How long to retry a URL until it is a `hit`, such as `5m`. + run_timeout: + type: string + description: Cap for the whole run, such as `15m`. URLs left over become `incomplete`. + vantage_point_ids: + type: array + items: + type: string + description: | + Restrict the run to these vantage points. Omitted means all the organization may use. + + EffectiveRunOptions: + type: object + description: | + The options of a run as accepted. `fail_on` is the list the run was created with, or the list + the engine reports it applied once known; it is null until then (no default is invented). + required: [fail_on] + properties: + top: + type: [integer, 'null'] + minimum: 1 + fail_on: + type: [array, 'null'] + description: The list in effect, or null while the engine default is not yet reported. + items: + $ref: '#/components/schemas/FailOnToken' + additionalProperties: true + WarmRunCreate: + type: object + properties: + source: + $ref: '#/components/schemas/RunSource' + deployment: + $ref: '#/components/schemas/Deployment' + options: + $ref: '#/components/schemas/RunOptions' + Outcome: + type: object + description: Whether the run passes, by the `--fail-on` contract. + required: [failed, failing_states, reason] + properties: + failed: + type: boolean + failing_states: + type: array + description: Tokens from the effective `fail_on` that matched at least one result. + items: + $ref: '#/components/schemas/FailOnToken' + reason: + type: [string, 'null'] + enum: [fail_on_matched, no_verifications, null] + description: | + `no_verifications`: no URL could be verified (for example all `skipped-robots`), which + fails the run even if `skipped-robots` is not in `fail_on`. Null when the run passed. + StateCounts: + type: object + description: Number of results per cache state. States with no results may be omitted. + propertyNames: + $ref: '#/components/schemas/CacheState' + additionalProperties: + type: integer + minimum: 0 + VantagePointSummary: + type: object + required: [vantage_point_id, region, status, n, counts] + properties: + vantage_point_id: + type: string + region: + type: string + status: + $ref: '#/components/schemas/RunStatus' + n: + type: integer + minimum: 0 + description: Number of results (URL by profile) for this vantage point. + counts: + $ref: '#/components/schemas/StateCounts' + unknown_reason: + oneOf: + - $ref: '#/components/schemas/UnknownReason' + - type: 'null' + WarmRun: + type: object + required: [id, site_id, status, trigger, options, outcome, vantage_points, created_at] + properties: + id: + type: string + site_id: + type: string + status: + $ref: '#/components/schemas/RunStatus' + trigger: + $ref: '#/components/schemas/Trigger' + deployment: + oneOf: + - $ref: '#/components/schemas/Deployment' + - type: 'null' + source: + $ref: '#/components/schemas/RunSource' + options: + $ref: '#/components/schemas/EffectiveRunOptions' + outcome: + oneOf: + - $ref: '#/components/schemas/Outcome' + - type: 'null' + description: Null until the run is `completed`. + vantage_points: + type: array + items: + $ref: '#/components/schemas/VantagePointSummary' + created_at: + type: string + format: date-time + started_at: + type: [string, 'null'] + format: date-time + finished_at: + type: [string, 'null'] + format: date-time + error_code: + type: [string, 'null'] + description: A short code when `status` is `failed`; null otherwise. + WarmRunList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/WarmRun' + page: + $ref: '#/components/schemas/PageInfo' + VantagePointRef: + type: object + required: [id, region] + properties: + id: + type: string + region: + type: string + Result: + type: object + description: | + What the engine observed for one URL and one profile at one vantage point. Fields marked + nullable depend on engine releases that may not be out yet. + required: [url, final_state] + properties: + url: + type: string + format: uri + profile: + type: [string, 'null'] + description: Request profile name, for example `desktop` or `mobile`. + vantage_point: + oneOf: + - $ref: '#/components/schemas/VantagePointRef' + - type: 'null' + initial_state: + description: Omitted when the engine has not reported the first observation separately. + $ref: '#/components/schemas/CacheState' + final_state: + $ref: '#/components/schemas/CacheState' + unknown_reason: + oneOf: + - $ref: '#/components/schemas/UnknownReason' + - type: 'null' + http_status: + type: [integer, 'null'] + cdn: + type: [string, 'null'] + description: Detected CDN, for example `cloudflare`. + cdn_cache_header: + type: [string, 'null'] + description: Raw cache status header value as observed (for example `EXPIRED`), never normalized. + pop: + type: [string, 'null'] + description: Point of presence when the CDN exposes it. + time_to_hit_ms: + type: [integer, 'null'] + minimum: 0 + ttfb_ms: + type: [integer, 'null'] + minimum: 0 + cache_control: + type: [string, 'null'] + age_seconds: + type: [integer, 'null'] + minimum: 0 + vary: + type: [string, 'null'] + indexability: + oneOf: + - $ref: '#/components/schemas/Indexability' + - type: 'null' + route_group: + type: [string, 'null'] + description: Route template the URL belongs to (for example `/blog/*`). + cause: + type: array + description: Engine-provided causes for a non-`hit` state, citing observed headers. `Set-Cookie` values are redacted. + items: + type: string + fix: + type: array + description: Engine-provided suggested fixes. + items: + type: string + error: + type: [string, 'null'] + ResultList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/Result' + page: + $ref: '#/components/schemas/PageInfo' + ReportCell: + type: object + description: Results of one route group at one vantage point. No percentage is given on purpose. + required: [route_group, vantage_point, n, counts] + properties: + route_group: + type: string + vantage_point: + $ref: '#/components/schemas/VantagePointRef' + n: + type: integer + minimum: 0 + description: Number of results (URL by profile) in the cell. + counts: + $ref: '#/components/schemas/StateCounts' + unknown_reason: + oneOf: + - $ref: '#/components/schemas/UnknownReason' + - type: 'null' + CacheStatusReportSummary: + type: object + required: [id, site_id, warm_run_id, created_at] + properties: + id: + type: string + site_id: + type: string + warm_run_id: + type: string + created_at: + type: string + format: date-time + CacheStatusReport: + allOf: + - $ref: '#/components/schemas/CacheStatusReportSummary' + - type: object + required: [cells] + properties: + cells: + type: array + items: + $ref: '#/components/schemas/ReportCell' + CacheStatusReportList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/CacheStatusReportSummary' + page: + $ref: '#/components/schemas/PageInfo' + Cadence: + type: object + description: Run every N hours or days. Allowed values depend on the organization's limits. + required: [unit, every] + properties: + unit: + type: string + enum: [hour, day] + every: + type: integer + minimum: 1 + Schedule: + type: object + required: [id, site_id, enabled, cadence, source, options, created_at] + properties: + id: + type: string + site_id: + type: string + enabled: + type: boolean + cadence: + $ref: '#/components/schemas/Cadence' + source: + $ref: '#/components/schemas/RunSource' + options: + $ref: '#/components/schemas/RunOptions' + next_run_at: + type: [string, 'null'] + format: date-time + last_run_id: + type: [string, 'null'] + created_at: + type: string + format: date-time + ScheduleCreate: + type: object + required: [cadence, source] + properties: + enabled: + type: boolean + cadence: + $ref: '#/components/schemas/Cadence' + source: + $ref: '#/components/schemas/RunSource' + options: + $ref: '#/components/schemas/RunOptions' + ScheduleUpdate: + type: object + properties: + enabled: + type: boolean + cadence: + $ref: '#/components/schemas/Cadence' + source: + $ref: '#/components/schemas/RunSource' + options: + $ref: '#/components/schemas/RunOptions' + ScheduleList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/Schedule' + page: + $ref: '#/components/schemas/PageInfo' + EventType: + type: string + description: Events a webhook endpoint can subscribe to. + enum: + - warm_run.completed + - warm_run.canceled + - site.verification_changed + Webhook: + type: object + required: [id, url, events, enabled, created_at] + properties: + id: + type: string + url: + type: string + format: uri + description: HTTPS endpoint that receives deliveries. + description: + type: [string, 'null'] + events: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/EventType' + enabled: + type: boolean + created_at: + type: string + format: date-time + WebhookWithSecret: + allOf: + - $ref: '#/components/schemas/Webhook' + - type: object + required: [secret] + properties: + secret: + type: string + description: HMAC signing secret. Shown only in this response. + WebhookCreate: + type: object + required: [url, events] + properties: + url: + type: string + format: uri + description: + type: string + events: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/EventType' + enabled: + type: boolean + WebhookUpdate: + type: object + properties: + url: + type: string + format: uri + description: + type: string + events: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/EventType' + enabled: + type: boolean + WebhookList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/Webhook' + page: + $ref: '#/components/schemas/PageInfo' + EventEnvelope: + type: object + required: [id, type, created_at] + properties: + id: + type: string + description: Unique per event. A redelivery of the same event keeps the id; use it to deduplicate. + type: + $ref: '#/components/schemas/EventType' + created_at: + type: string + format: date-time + WarmRunCompletedEvent: + allOf: + - $ref: '#/components/schemas/EventEnvelope' + - type: object + required: [data] + properties: + type: + const: warm_run.completed + data: + $ref: '#/components/schemas/WarmRun' + WarmRunCanceledEvent: + allOf: + - $ref: '#/components/schemas/EventEnvelope' + - type: object + required: [data] + properties: + type: + const: warm_run.canceled + data: + $ref: '#/components/schemas/WarmRun' + SiteVerificationChangedEvent: + allOf: + - $ref: '#/components/schemas/EventEnvelope' + - type: object + required: [data] + properties: + type: + const: site.verification_changed + data: + $ref: '#/components/schemas/Site' + ApiKey: + type: object + required: [id, name, prefix, scopes, created_at] + properties: + id: + type: string + name: + type: string + prefix: + type: string + description: First characters of the key, to recognize it. Not a secret. + scopes: + type: array + items: + $ref: '#/components/schemas/Scope' + site_ids: + type: [array, 'null'] + description: | + If set, the key can only act on these sites. A site-restricted key cannot hold + `webhooks:*` or `api-keys:*`. Null means all sites of the organization. + + items: + type: string + expires_at: + type: [string, 'null'] + format: date-time + last_used_at: + type: [string, 'null'] + format: date-time + created_at: + type: string + format: date-time + ApiKeyWithSecret: + allOf: + - $ref: '#/components/schemas/ApiKey' + - type: object + required: [secret] + properties: + secret: + type: string + description: The API key. Shown only in this response. + ApiKeyCreate: + type: object + required: [name, scopes] + properties: + name: + type: string + scopes: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/Scope' + site_ids: + type: [array, 'null'] + items: + type: string + expires_at: + type: [string, 'null'] + format: date-time + ApiKeyList: + type: object + required: [data, page] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ApiKey' + page: + $ref: '#/components/schemas/PageInfo' diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4465642 --- /dev/null +++ b/pom.xml @@ -0,0 +1,107 @@ + + + 4.0.0 + + com.sitewarm + sitewarm-sdk + 0.1.0-SNAPSHOT + jar + sitewarm SDK for Java + Java client for the sitewarm API (pre-release) + https://github.com/sitewarm/sdk-java + + + + Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + 17 + UTF-8 + 2.22.4 + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + + jakarta.annotation + jakarta.annotation-api + 3.0.0 + provided + + + org.junit.jupiter + junit-jupiter + 5.12.2 + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.3 + + + + + + + + generate + + + + org.openapitools + openapi-generator-maven-plugin + 7.26.0 + + + generate + + ${project.basedir}/build/openapi.prep.yaml + java + native + ${project.basedir} + com.sitewarm.sdk.model + false + false + false + false + false + true + JSON.java,AbstractOpenApiSchema.java,RFC3339DateFormat.java + false + + src/main/java + false + true + true + jackson + none + java8 + + + + + + + + + + diff --git a/scripts/gen_operations.py b/scripts/gen_operations.py new file mode 100644 index 0000000..b2e8427 --- /dev/null +++ b/scripts/gen_operations.py @@ -0,0 +1,65 @@ +"""Prepares generation. Needs PyYAML. + +- build/openapi.prep.yaml : the spec without webhook callbacks (server-to-customer, not part of the SDK), so the + type generator does not emit event types that have no schema in components. +- src/main/java/com/sitewarm/sdk/Operations.java : operationId -> method/path/idempotency table. + +Then run: mvn -B -q -Pgenerate generate-sources +""" +from pathlib import Path + +import yaml + +ROOT = Path(__file__).resolve().parent.parent +spec = yaml.safe_load((ROOT / "openapi" / "openapi.yaml").read_text()) + +prep = yaml.safe_load(yaml.safe_dump(spec)) +prep.pop("webhooks", None) +prep.get("components", {}).pop("callbacks", None) +for item in prep["paths"].values(): + for op in item.values(): + if isinstance(op, dict): + op.pop("callbacks", None) +(ROOT / "build").mkdir(exist_ok=True) +(ROOT / "build" / "openapi.prep.yaml").write_text(yaml.safe_dump(prep, sort_keys=False)) + +rows = [] +for path, item in spec["paths"].items(): + for method in ("get", "put", "post", "patch", "delete"): + op = item.get(method) + if not op: + continue + refs = [p.get("$ref", "") for p in [*item.get("parameters", []), *op.get("parameters", [])]] + idem = next((r for r in refs if r.endswith("/IdempotencyKey") or r.endswith("/IdempotencyKeyRequired")), None) + kind = "NONE" if not idem else ("REQUIRED" if idem.endswith("Required") else "OPTIONAL") + rows.append((op["operationId"], method.upper(), path, kind)) +rows.sort() + +lines = "\n".join(f' m.put("{i}", new Operation("{m}", "{p}", Operation.Idempotency.{k}));' for i, m, p, k in rows) +out = ROOT / "src" / "main" / "java" / "com" / "sitewarm" / "sdk" / "Operations.java" +out.parent.mkdir(parents=True, exist_ok=True) +out.write_text( + "// GENERATED by scripts/gen_operations.py from openapi/openapi.yaml. Do not edit.\n" + "package com.sitewarm.sdk;\n\n" + "import java.util.Collections;\n" + "import java.util.LinkedHashMap;\n" + "import java.util.Map;\n\n" + "/** operationId to method, path and idempotency support. */\n" + "final class Operations {\n" + " private Operations() {}\n\n" + " static final Map TABLE = build();\n\n" + " private static Map build() {\n" + " Map m = new LinkedHashMap<>();\n" + f"{lines}\n" + " return Collections.unmodifiableMap(m);\n" + " }\n" + "}\n" +) +(out.parent / "Operation.java").write_text( + "// GENERATED by scripts/gen_operations.py from openapi/openapi.yaml. Do not edit.\n" + "package com.sitewarm.sdk;\n\n" + "record Operation(String method, String path, Idempotency idempotency) {\n" + " enum Idempotency { NONE, OPTIONAL, REQUIRED }\n" + "}\n" +) +print(f"generated {len(rows)} operations") diff --git a/src/main/java/com/sitewarm/sdk/ApiClient.java b/src/main/java/com/sitewarm/sdk/ApiClient.java new file mode 100644 index 0000000..83694d4 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/ApiClient.java @@ -0,0 +1,30 @@ +package com.sitewarm.sdk; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.StringJoiner; + +/** + * Static helpers that the generated model classes call ({@code toUrlQueryString}). Not an HTTP client: the + * client is {@link SiteWarm}. + */ +public final class ApiClient { + private ApiClient() {} + + public static String urlEncode(String s) { + return URLEncoder.encode(s, StandardCharsets.UTF_8).replace("+", "%20"); + } + + public static String valueToString(Object value) { + if (value == null) return ""; + if (value instanceof java.time.OffsetDateTime t) return t.toString(); + return String.valueOf(value); + } + + public static String collectionToString(Collection values) { + StringJoiner j = new StringJoiner(","); + for (Object v : values) j.add(valueToString(v)); + return j.toString(); + } +} diff --git a/src/main/java/com/sitewarm/sdk/JSON.java b/src/main/java/com/sitewarm/sdk/JSON.java new file mode 100644 index 0000000..089ad7c --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/JSON.java @@ -0,0 +1,261 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.sitewarm.sdk.model.*; + +import java.text.DateFormat; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class JSON { + private ObjectMapper mapper; + + public JSON() { + mapper = JsonMapper.builder() + .serializationInclusion(JsonInclude.Include.NON_NULL) + .disable(MapperFeature.ALLOW_COERCION_OF_SCALARS) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE) + .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) + .enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING) + .enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) + .defaultDateFormat(new RFC3339DateFormat()) + .addModule(new JavaTimeModule()) + .build(); + } + + /** + * Set the date format for JSON (de)serialization with Date properties. + * + * @param dateFormat Date format + */ + public void setDateFormat(DateFormat dateFormat) { + mapper.setDateFormat(dateFormat); + } + + /** + * Get the object mapper + * + * @return object mapper + */ + public ObjectMapper getMapper() { return mapper; } + + /** + * Returns the target model class that should be used to deserialize the input data. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param modelClass The class that contains the discriminator mappings. + * + * @return the target model class. + */ + public static Class getClassForElement(JsonNode node, Class modelClass) { + ClassDiscriminatorMapping cdm = modelDiscriminators.get(modelClass); + if (cdm != null) { + return cdm.getClassForElement(node, new HashSet>()); + } + return null; + } + + /** + * Helper class to register the discriminator mappings. + */ + @jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") + private static class ClassDiscriminatorMapping { + // The model class name. + Class modelClass; + // The name of the discriminator property. + String discriminatorName; + // The discriminator mappings for a model class. + Map> discriminatorMappings; + + // Constructs a new class discriminator. + ClassDiscriminatorMapping(Class cls, String propertyName, Map> mappings) { + modelClass = cls; + discriminatorName = propertyName; + discriminatorMappings = new HashMap>(); + if (mappings != null) { + discriminatorMappings.putAll(mappings); + } + } + + // Return the name of the discriminator property for this model class. + String getDiscriminatorPropertyName() { + return discriminatorName; + } + + // Return the discriminator value or null if the discriminator is not + // present in the payload. + String getDiscriminatorValue(JsonNode node) { + // Determine the value of the discriminator property in the input data. + if (discriminatorName != null) { + // Get the value of the discriminator property, if present in the input payload. + node = node.get(discriminatorName); + if (node != null && node.isValueNode()) { + String discrValue = node.asText(); + if (discrValue != null) { + return discrValue; + } + } + } + return null; + } + + /** + * Returns the target model class that should be used to deserialize the input data. + * This function can be invoked for anyOf/oneOf composed models with discriminator mappings. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param visitedClasses The set of classes that have already been visited. + * + * @return the target model class. + */ + Class getClassForElement(JsonNode node, Set> visitedClasses) { + if (visitedClasses.contains(modelClass)) { + // Class has already been visited. + return null; + } + // Determine the value of the discriminator property in the input data. + String discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + return null; + } + Class cls = discriminatorMappings.get(discrValue); + // It may not be sufficient to return this cls directly because that target class + // may itself be a composed schema, possibly with its own discriminator. + visitedClasses.add(modelClass); + for (Class childClass : discriminatorMappings.values()) { + ClassDiscriminatorMapping childCdm = modelDiscriminators.get(childClass); + if (childCdm == null) { + continue; + } + if (!discriminatorName.equals(childCdm.discriminatorName)) { + discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + continue; + } + } + if (childCdm != null) { + // Recursively traverse the discriminator mappings. + Class childDiscr = childCdm.getClassForElement(node, visitedClasses); + if (childDiscr != null) { + return childDiscr; + } + } + } + return cls; + } + } + + /** + * Returns true if inst is an instance of modelClass in the OpenAPI model hierarchy. + * + * The Java class hierarchy is not implemented the same way as the OpenAPI model hierarchy, + * so it's not possible to use the instanceof keyword. + * + * @param modelClass A OpenAPI model class. + * @param inst The instance object. + * @param visitedClasses The set of classes that have already been visited. + * + * @return true if inst is an instance of modelClass in the OpenAPI model hierarchy. + */ + public static boolean isInstanceOf(Class modelClass, Object inst, Set> visitedClasses) { + if (modelClass.isInstance(inst)) { + // This handles the 'allOf' use case with single parent inheritance. + return true; + } + if (visitedClasses.contains(modelClass)) { + // This is to prevent infinite recursion when the composed schemas have + // a circular dependency. + return false; + } + visitedClasses.add(modelClass); + + // Traverse the oneOf/anyOf composed schemas. + Map> descendants = modelDescendants.get(modelClass); + if (descendants != null) { + for (Class childType : descendants.values()) { + if (isInstanceOf(childType, inst, visitedClasses)) { + return true; + } + } + } + return false; + } + + /** + * A map of discriminators for all model classes. + */ + private static Map, ClassDiscriminatorMapping> modelDiscriminators = new HashMap<>(); + + /** + * A map of oneOf/anyOf descendants for each model class. + */ + private static Map, Map>> modelDescendants = new HashMap<>(); + + /** + * Register a model class discriminator. + * + * @param modelClass the model class + * @param discriminatorPropertyName the name of the discriminator property + * @param mappings a map with the discriminator mappings. + */ + public static void registerDiscriminator(Class modelClass, String discriminatorPropertyName, Map> mappings) { + ClassDiscriminatorMapping m = new ClassDiscriminatorMapping(modelClass, discriminatorPropertyName, mappings); + modelDiscriminators.put(modelClass, m); + } + + /** + * Register the oneOf/anyOf descendants of the modelClass. + * + * @param modelClass the model class + * @param descendants a map of oneOf/anyOf descendants. + */ + public static void registerDescendants(Class modelClass, Map> descendants) { + modelDescendants.put(modelClass, descendants); + } + + private static JSON json; + + static { + json = new JSON(); + } + + /** + * Get the default JSON instance. + * + * @return the default JSON instance + */ + public static JSON getDefault() { + return json; + } + + /** + * Set the default JSON instance. + * + * @param json JSON instance to be used + */ + public static void setDefault(JSON json) { + JSON.json = json; + } +} diff --git a/src/main/java/com/sitewarm/sdk/Operation.java b/src/main/java/com/sitewarm/sdk/Operation.java new file mode 100644 index 0000000..76d58cd --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/Operation.java @@ -0,0 +1,6 @@ +// GENERATED by scripts/gen_operations.py from openapi/openapi.yaml. Do not edit. +package com.sitewarm.sdk; + +record Operation(String method, String path, Idempotency idempotency) { + enum Idempotency { NONE, OPTIONAL, REQUIRED } +} diff --git a/src/main/java/com/sitewarm/sdk/Operations.java b/src/main/java/com/sitewarm/sdk/Operations.java new file mode 100644 index 0000000..ce90792 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/Operations.java @@ -0,0 +1,54 @@ +// GENERATED by scripts/gen_operations.py from openapi/openapi.yaml. Do not edit. +package com.sitewarm.sdk; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +/** operationId to method, path and idempotency support. */ +final class Operations { + private Operations() {} + + static final Map TABLE = build(); + + private static Map build() { + Map m = new LinkedHashMap<>(); + m.put("cancelWarmRun", new Operation("POST", "/warm-runs/{runId}/cancel", Operation.Idempotency.OPTIONAL)); + m.put("createApiKey", new Operation("POST", "/api-keys", Operation.Idempotency.OPTIONAL)); + m.put("createSchedule", new Operation("POST", "/sites/{siteId}/schedules", Operation.Idempotency.OPTIONAL)); + m.put("createSite", new Operation("POST", "/sites", Operation.Idempotency.OPTIONAL)); + m.put("createSitemap", new Operation("POST", "/sites/{siteId}/sitemaps", Operation.Idempotency.OPTIONAL)); + m.put("createUrlSet", new Operation("POST", "/sites/{siteId}/url-sets", Operation.Idempotency.OPTIONAL)); + m.put("createWarmRun", new Operation("POST", "/sites/{siteId}/warm-runs", Operation.Idempotency.REQUIRED)); + m.put("createWebhook", new Operation("POST", "/webhooks", Operation.Idempotency.OPTIONAL)); + m.put("deleteSchedule", new Operation("DELETE", "/schedules/{scheduleId}", Operation.Idempotency.NONE)); + m.put("deleteSite", new Operation("DELETE", "/sites/{siteId}", Operation.Idempotency.NONE)); + m.put("deleteSitemap", new Operation("DELETE", "/sites/{siteId}/sitemaps/{sitemapId}", Operation.Idempotency.NONE)); + m.put("deleteUrlSet", new Operation("DELETE", "/sites/{siteId}/url-sets/{urlSetId}", Operation.Idempotency.NONE)); + m.put("deleteWebhook", new Operation("DELETE", "/webhooks/{webhookId}", Operation.Idempotency.NONE)); + m.put("getApiKey", new Operation("GET", "/api-keys/{apiKeyId}", Operation.Idempotency.NONE)); + m.put("getCacheStatusReport", new Operation("GET", "/cache-status-reports/{reportId}", Operation.Idempotency.NONE)); + m.put("getSchedule", new Operation("GET", "/schedules/{scheduleId}", Operation.Idempotency.NONE)); + m.put("getSite", new Operation("GET", "/sites/{siteId}", Operation.Idempotency.NONE)); + m.put("getSitemap", new Operation("GET", "/sites/{siteId}/sitemaps/{sitemapId}", Operation.Idempotency.NONE)); + m.put("getUrlSet", new Operation("GET", "/sites/{siteId}/url-sets/{urlSetId}", Operation.Idempotency.NONE)); + m.put("getWarmRun", new Operation("GET", "/warm-runs/{runId}", Operation.Idempotency.NONE)); + m.put("getWebhook", new Operation("GET", "/webhooks/{webhookId}", Operation.Idempotency.NONE)); + m.put("listApiKeys", new Operation("GET", "/api-keys", Operation.Idempotency.NONE)); + m.put("listCacheStatusReports", new Operation("GET", "/sites/{siteId}/cache-status-reports", Operation.Idempotency.NONE)); + m.put("listSchedules", new Operation("GET", "/sites/{siteId}/schedules", Operation.Idempotency.NONE)); + m.put("listSitemaps", new Operation("GET", "/sites/{siteId}/sitemaps", Operation.Idempotency.NONE)); + m.put("listSites", new Operation("GET", "/sites", Operation.Idempotency.NONE)); + m.put("listUrlSets", new Operation("GET", "/sites/{siteId}/url-sets", Operation.Idempotency.NONE)); + m.put("listWarmRunResults", new Operation("GET", "/warm-runs/{runId}/results", Operation.Idempotency.NONE)); + m.put("listWarmRuns", new Operation("GET", "/sites/{siteId}/warm-runs", Operation.Idempotency.NONE)); + m.put("listWebhooks", new Operation("GET", "/webhooks", Operation.Idempotency.NONE)); + m.put("replaceUrlSet", new Operation("PUT", "/sites/{siteId}/url-sets/{urlSetId}", Operation.Idempotency.NONE)); + m.put("revokeApiKey", new Operation("DELETE", "/api-keys/{apiKeyId}", Operation.Idempotency.NONE)); + m.put("rotateWebhookSecret", new Operation("POST", "/webhooks/{webhookId}/rotate-secret", Operation.Idempotency.OPTIONAL)); + m.put("updateSchedule", new Operation("PATCH", "/schedules/{scheduleId}", Operation.Idempotency.NONE)); + m.put("updateSite", new Operation("PATCH", "/sites/{siteId}", Operation.Idempotency.NONE)); + m.put("updateWebhook", new Operation("PATCH", "/webhooks/{webhookId}", Operation.Idempotency.NONE)); + return Collections.unmodifiableMap(m); + } +} diff --git a/src/main/java/com/sitewarm/sdk/RFC3339DateFormat.java b/src/main/java/com/sitewarm/sdk/RFC3339DateFormat.java new file mode 100644 index 0000000..aa6ca94 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/RFC3339DateFormat.java @@ -0,0 +1,57 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sitewarm.sdk; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.text.DecimalFormat; +import java.util.GregorianCalendar; +import java.util.TimeZone; +import com.fasterxml.jackson.databind.util.StdDateFormat; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class RFC3339DateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); + + private final StdDateFormat fmt = new StdDateFormat() + .withTimeZone(TIMEZONE_Z) + .withColonInTimeZone(true); + + public RFC3339DateFormat() { + this.calendar = new GregorianCalendar(); + this.numberFormat = new DecimalFormat(); + } + + @Override + public Date parse(String source) { + return parse(source, new ParsePosition(0)); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return fmt.parse(source, pos); + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return fmt.format(date, toAppendTo, fieldPosition); + } + + @Override + public Object clone() { + return super.clone(); + } +} diff --git a/src/main/java/com/sitewarm/sdk/Request.java b/src/main/java/com/sitewarm/sdk/Request.java new file mode 100644 index 0000000..0326a77 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/Request.java @@ -0,0 +1,35 @@ +package com.sitewarm.sdk; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** Arguments of one operation. Build with {@link #of()} and the {@code with*} methods. */ +public record Request(Map path, Map query, Object body, String idempotencyKey) { + public static Request of() { + return new Request(Map.of(), Map.of(), null, null); + } + + public Request withPath(String name, String value) { + return new Request(plus(path, name, value), query, body, idempotencyKey); + } + + /** A query parameter; null values are skipped. */ + public Request withQuery(String name, String value) { + return value == null ? this : new Request(path, plus(query, name, value), body, idempotencyKey); + } + + public Request withBody(Object body) { + return new Request(path, query, body, idempotencyKey); + } + + /** Overrides the random Idempotency-Key sent for operations that accept one. */ + public Request withIdempotencyKey(String key) { + return new Request(path, query, body, key); + } + + private static Map plus(Map m, String k, String v) { + Map out = new LinkedHashMap<>(m); + out.put(k, v); + return Map.copyOf(out); + } +} diff --git a/src/main/java/com/sitewarm/sdk/SiteWarm.java b/src/main/java/com/sitewarm/sdk/SiteWarm.java new file mode 100644 index 0000000..3097e47 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/SiteWarm.java @@ -0,0 +1,539 @@ +package com.sitewarm.sdk; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.sitewarm.sdk.model.Result; +import com.sitewarm.sdk.model.Site; +import com.sitewarm.sdk.model.SiteCreate; +import com.sitewarm.sdk.model.WarmRun; +import com.sitewarm.sdk.model.WarmRunCreate; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.Instant; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.OptionalInt; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Client for the sitewarm API (pre-release). Thread-safe. Every operation of the spec is reachable by its + * operationId through {@link #call}; {@link #sites} and {@link #warmRuns} are typed conveniences. + */ +public final class SiteWarm { + private static final Pattern KEY = Pattern.compile("^[\\x21-\\x7e]+$"); + private static final Pattern PATH_PARAM = Pattern.compile("\\{(\\w+)}"); + private static final Pattern SLUG = Pattern.compile("^[a-z0-9-]+$"); + + /** Largest response body that is read (32 MiB). */ + static final int MAX_BODY = 32 << 20; + static final int MAX_PAGES = 10_000; + + static final ObjectMapper MAPPER = new ObjectMapper() + .registerModule(new JavaTimeModule()) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL); + + /** Pauses between attempts; replaceable in tests. */ + interface Sleeper { + void sleep(Duration d) throws InterruptedException; + } + + /** SDK version, sent in the User-Agent. A test keeps it equal to the pom version. */ + public static final String VERSION = "0.1.0-SNAPSHOT"; + + static final String DEFAULT_USER_AGENT = "sitewarm-java/" + VERSION + " (+https://github.com/sitewarm/sdk-java)"; + + private static final Set REPEATABLE = Set.of("GET", "HEAD", "PUT", "OPTIONS"); + + private final String apiKey; + private final String baseUrl; + private final HttpClient http; + private final int maxRetries; + private final Duration retryBase; + private final Duration retryMax; + private final Duration timeout; + private final String userAgent; + private final Sleeper sleeper; + + public final Sites sites = new Sites(); + public final WarmRuns warmRuns = new WarmRuns(); + + private SiteWarm(Builder b) { + this.apiKey = b.apiKey; + this.baseUrl = b.baseUrl; + this.http = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NEVER).connectTimeout(b.timeout).build(); + this.maxRetries = b.maxRetries; + this.retryBase = b.retryBase; + this.retryMax = b.retryMax; + this.timeout = b.timeout; + this.userAgent = b.userAgent; + this.sleeper = b.sleeper; + } + + public static Builder builder(String apiKey, String baseUrl) { + return new Builder(apiKey, baseUrl); + } + + /** Never contains the key. */ + @Override + public String toString() { + return "SiteWarm{baseUrl=" + baseUrl + "}"; + } + + public static final class Builder { + private final String apiKey; + private final String baseUrl; + private int maxRetries = 3; + private Duration retryBase = Duration.ofMillis(500); + private Duration retryMax = Duration.ofSeconds(30); + private Duration timeout = Duration.ofSeconds(30); + private String userAgent = DEFAULT_USER_AGENT; + private Sleeper sleeper = d -> Thread.sleep(d.toMillis()); + + private Builder(String apiKey, String baseUrl) { + // Messages below never echo the key. + if (apiKey == null || !KEY.matcher(apiKey).matches()) { + throw new SiteWarmException("apiKey must be non-empty printable ASCII without whitespace"); + } + this.apiKey = apiKey; + this.baseUrl = normalize(baseUrl); + } + + /** Retries after the first attempt (default 3). A negative value keeps the default. */ + public Builder maxRetries(int n) { if (n >= 0) this.maxRetries = n; return this; } + public Builder retryDelays(Duration base, Duration max) { this.retryBase = base; this.retryMax = max; return this; } + /** Per-attempt timeout (default 30 s). Null, zero or a negative value keeps the default. */ + public Builder timeout(Duration d) { if (d != null && !d.isZero() && !d.isNegative()) this.timeout = d; return this; } + /** Overrides the User-Agent. Null or empty keeps the default. */ + public Builder userAgent(String s) { if (s != null && !s.isEmpty()) this.userAgent = s; return this; } + Builder sleeper(Sleeper s) { this.sleeper = s; return this; } + + public SiteWarm build() { return new SiteWarm(this); } + } + + private static String normalize(String raw) { + URI u; + try { + u = URI.create(raw == null ? "" : raw); + } catch (IllegalArgumentException e) { + throw new SiteWarmException("baseUrl must be an absolute URL such as https:///v1"); + } + if (u.getScheme() == null || u.getHost() == null) { + throw new SiteWarmException("baseUrl must be an absolute URL such as https:///v1"); + } + String host = u.getHost(); + boolean loopback = host.equals("localhost") || host.equals("127.0.0.1") || host.equals("[::1]"); + if (!u.getScheme().equals("https") && !(u.getScheme().equals("http") && loopback)) { + throw new SiteWarmException("baseUrl must use https (http is only allowed for localhost)"); + } + if (u.getUserInfo() != null) throw new SiteWarmException("baseUrl must not contain credentials"); + if (u.getQuery() != null || u.getFragment() != null) { + throw new SiteWarmException("baseUrl must not contain a query or fragment"); + } + String path = u.getRawPath() == null ? "" : u.getRawPath().replaceAll("/+$", ""); + return u.getScheme() + "://" + u.getRawAuthority() + path; + } + + /** Calls one operation by operationId and returns the decoded JSON body (null for an empty body). */ + public JsonNode call(String operationId, Request req) { + return exchange(operationId, req).body(); + } + + /** Like {@link #call(String, Request)} but maps the body to {@code type} (a generated model). */ + public T call(String operationId, Request req, Class type) { + JsonNode n = call(operationId, req); + if (n == null) return null; + try { + return MAPPER.treeToValue(n, type); + } catch (IOException e) { + throw new SiteWarmException("response does not match " + type.getSimpleName(), e); + } + } + + /** A decoded response with its transport data. */ + public record Response(int status, Map> headers, JsonNode body) { + public String header(String name) { + return headers.entrySet().stream().filter(e -> e.getKey().equalsIgnoreCase(name)) + .findFirst().map(e -> e.getValue().get(0)).orElse(null); + } + } + + public Response exchange(String operationId, Request req) { + Operation op = Operations.TABLE.get(operationId); + if (op == null) throw new SiteWarmException("unknown operation \"" + operationId + "\""); + StringBuilder url = new StringBuilder(baseUrl).append(expand(op.path(), req.path())); + Map query = checkedQuery(req.query()); + if (!query.isEmpty()) { + url.append('?'); + query.forEach((k, v) -> url.append(enc(k)).append('=').append(enc(v)).append('&')); + url.setLength(url.length() - 1); + } + String body = null; + if (req.body() != null) { + try { + body = MAPPER.writeValueAsString(req.body()); + } catch (IOException e) { + throw new SiteWarmException("could not encode the request body", e); + } + } + boolean sendsKey = op.idempotency() != Operation.Idempotency.NONE && op.method().equals("POST"); + // One key per call, reused by every retry, so a retried POST never starts a second run. + String key = sendsKey ? (req.idempotencyKey() != null ? req.idempotencyKey() : UUID.randomUUID().toString()) : null; + // 429 = not processed. 5xx, network errors and broken bodies may have been, so retry them only when + // repeating is safe: GET, HEAD, PUT, OPTIONS, or a POST with an Idempotency-Key. DELETE and PATCH: 429 only. + boolean retryAmbiguous = REPEATABLE.contains(op.method()) || sendsKey; + + for (int attempt = 0; ; attempt++) { + boolean last = attempt >= maxRetries; + HttpRequest request; + try { + HttpRequest.Builder rb = HttpRequest.newBuilder(URI.create(url.toString())).timeout(timeout) + .header("Authorization", "Bearer " + apiKey) + .header("Accept", "application/json, application/problem+json") + .header("User-Agent", userAgent); + if (body != null) rb.header("Content-Type", "application/json"); + if (key != null) rb.header("Idempotency-Key", key); + rb.method(op.method(), body == null ? HttpRequest.BodyPublishers.noBody() + : HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8)); + request = rb.build(); + } catch (IllegalArgumentException e) { + // An invalid header value or URL: repeating cannot fix it. The message may echo a value, so it is dropped. + throw new SiteWarmException("malformed request (invalid header or URL)"); + } + + HttpResponse resp; + try { + resp = http.send(request, HttpResponse.BodyHandlers.ofInputStream()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new SiteWarmException("interrupted", e); + } catch (IOException e) { + if (!last && retryAmbiguous && isTransient(e)) { + pause(backoff(attempt)); + continue; + } + boolean timedOut = e instanceof java.net.http.HttpTimeoutException; + // The cause is dropped on purpose: transport errors can carry the request URL. + throw new SiteWarmException.Connection(timedOut ? "request timed out" : "request failed", timedOut, null); + } + + int status = resp.statusCode(); + String text; + try (InputStream in = resp.body()) { + text = new String(readLimited(in, MAX_BODY), StandardCharsets.UTF_8); + } catch (IOException e) { + // A body that breaks off is as ambiguous as a network error, except after a 429. + if (!last && (retryAmbiguous || status == 429)) { + pause(backoff(attempt)); + continue; + } + boolean timedOut = e instanceof java.net.http.HttpTimeoutException || e instanceof java.net.SocketTimeoutException; + throw new SiteWarmException.Connection(timedOut ? "request timed out" : "response body failed", timedOut, null); + } + if (status >= 200 && status < 300) { + return new Response(status, resp.headers().map(), parse(text, status)); + } + Duration retryAfter = parseRetryAfter(resp.headers().firstValue("Retry-After").orElse(null)); + SiteWarmException.Api error = apiError(status, text, resp.headers(), retryAfter); + boolean retryable = status == 429 || (status >= 500 && status != 501 && retryAmbiguous); + // A 409 "conflict" on a keyed POST is the original request still running (a timeout retry racing it). + // "idempotency-key-reused" is a caller bug and is never retried. + if (status == 409 && sendsKey && "conflict".equals(error.code())) retryable = true; + if (retryable && !last) { + // Never a hot retry on "Retry-After: 0" or a date in the past; jitter spreads clients out. + // A server-provided wait longer than the cap is surfaced, not slept. + Duration floored = retryAfter == null ? null : retryAfter.compareTo(retryBase) < 0 ? retryBase : retryAfter; + if (floored == null || floored.compareTo(retryMax) <= 0) { + pause(floored == null ? backoff(attempt) + : floored.plusMillis((long) (ThreadLocalRandom.current().nextDouble() * floored.toMillis() / 4))); + continue; + } + } + throw error; + } + } + + /** + * False for failures that repeating cannot fix: certificate verification, unknown host and malformed requests. + * Other network errors are retried. + */ + static boolean isTransient(Throwable t) { + for (int i = 0; t != null && i < 8; i++, t = t.getCause()) { + // HttpClient reports an unresolvable host as a ConnectException caused by UnresolvedAddressException. + if (t instanceof java.net.UnknownHostException + || t instanceof java.nio.channels.UnresolvedAddressException + || t instanceof javax.net.ssl.SSLPeerUnverifiedException + || t instanceof java.security.cert.CertificateException + || t instanceof java.security.cert.CertPathValidatorException) { + return false; + } + String m = t.getMessage(); + if (m != null && m.toLowerCase(java.util.Locale.ROOT).contains("invalid header")) return false; + } + return true; + } + + private void pause(Duration d) { + try { + sleeper.sleep(d); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new SiteWarmException("interrupted", e); + } + } + + private Duration backoff(int attempt) { + double ceil = Math.min(retryMax.toMillis(), retryBase.toMillis() * Math.pow(2, attempt)); + return Duration.ofMillis((long) (ceil / 2 + ThreadLocalRandom.current().nextDouble() * ceil / 2)); + } + + private static JsonNode parse(String text, int status) { + if (status == 204 || text == null || text.isBlank()) return null; + try { + return MAPPER.readTree(text); + } catch (IOException e) { + throw new SiteWarmException.Decode(status); // no cause: a parser message can quote the body + } + } + + /** Reads at most {@code limit + 1} bytes; a larger body throws {@link SiteWarmException.ResponseTooLarge}. */ + static byte[] readLimited(InputStream in, int limit) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buf = new byte[8192]; + long total = 0; + int n; + while ((n = in.read(buf)) >= 0) { + total += n; + if (total > limit) throw new SiteWarmException.ResponseTooLarge(limit); + out.write(buf, 0, n); + } + return out.toByteArray(); + } + + /** {@code limit} must be 1..100 (empty or 0 = server default, not sent); invalid values never reach the server. */ + private static Map checkedQuery(Map query) { + String limit = query.get("limit"); + if (limit == null) return query; + String v = limit.trim(); + Map out = new java.util.LinkedHashMap<>(query); + if (v.isEmpty() || v.equals("0")) { + out.remove("limit"); + return out; + } + int n; + try { + n = Integer.parseInt(v); + } catch (NumberFormatException e) { + throw new SiteWarmException("limit must be an integer between 1 and 100"); + } + if (n < 1 || n > 100) throw new SiteWarmException("limit must be an integer between 1 and 100"); + return out; + } + + private static SiteWarmException.Api apiError(int status, String body, java.net.http.HttpHeaders headers, Duration retryAfter) { + JsonNode p; + try { + p = MAPPER.readTree(body); + } catch (IOException | RuntimeException e) { + p = null; + } + if (p == null || !p.isObject()) { + p = MAPPER.createObjectNode().put("type", "about:blank").put("title", "HTTP " + status).put("status", status); + } + String code = p.path("code").isTextual() ? p.get("code").asText() : null; + if (code == null && p.path("type").isTextual()) { + String t = p.get("type").asText().replaceAll("/+$", ""); + String slug = t.substring(t.lastIndexOf('/') + 1); + if (SLUG.matcher(slug).matches()) code = slug; + } + OptionalInt remaining = OptionalInt.empty(); + String rl = headers.firstValue("RateLimit-Remaining").map(String::trim).orElse(""); + if (rl.matches("\\d+")) remaining = OptionalInt.of(Integer.parseInt(rl)); + return new SiteWarmException.Api(status, p, code, retryAfter, remaining); + } + + static Duration parseRetryAfter(String v) { + if (v == null || v.isBlank()) return null; + String s = v.trim(); + if (s.matches("\\d+")) return Duration.ofSeconds(Long.parseLong(s)); + try { + Instant at = ZonedDateTime.parse(s, DateTimeFormatter.RFC_1123_DATE_TIME).toInstant(); + Duration d = Duration.between(Instant.now(), at); + return d.isNegative() ? Duration.ZERO : d; + } catch (RuntimeException e) { + return null; + } + } + + private static String expand(String template, Map values) { + Matcher m = PATH_PARAM.matcher(template); + StringBuilder out = new StringBuilder(); + while (m.find()) { + String v = values.get(m.group(1)); + if (v == null || v.isEmpty()) throw new SiteWarmException("missing path parameter \"" + m.group(1) + "\""); + m.appendReplacement(out, Matcher.quoteReplacement(enc(v))); + } + return m.appendTail(out).toString(); + } + + private static String enc(String s) { + return URLEncoder.encode(s, StandardCharsets.UTF_8).replace("+", "%20"); + } + + // ---- pagination ---- + + /** + * Iterates every item of a list operation across pages. Cursors are opaque. Throws if a cursor repeats or + * if 10,000 pages did not reach the end. + */ + public Iterable items(String operationId, Request req, Class type) { + return items(operationId, req, type, MAX_PAGES); + } + + Iterable items(String operationId, Request req, Class type, int maxPages) { + return () -> new Iterator<>() { + private String cursor = req.query().get("cursor"); + private final Set seen = new HashSet<>(cursor == null ? Set.of() : Set.of(cursor)); + private Iterator page = java.util.Collections.emptyIterator(); + private boolean more = true; + private int pages = 0; + + @Override + public boolean hasNext() { + while (!page.hasNext() && more) { + if (pages >= maxPages) { + throw new SiteWarmException("pagination stopped after " + maxPages + " pages without reaching the end"); + } + pages++; + Request r = cursor == null ? req : req.withQuery("cursor", cursor); + JsonNode n = call(operationId, r); + page = n.path("data").iterator(); + JsonNode info = n.path("page"); + String next = info.path("next_cursor").isTextual() ? info.get("next_cursor").asText() : null; + more = info.path("has_more").asBoolean(false) && next != null && !next.isEmpty(); + if (more && !seen.add(next)) throw new SiteWarmException("pagination cursor did not advance"); + cursor = next; + } + return page.hasNext(); + } + + @Override + public T next() { + if (!hasNext()) throw new NoSuchElementException(); + try { + return MAPPER.treeToValue(page.next(), type); + } catch (IOException e) { + throw new SiteWarmException("response does not match " + type.getSimpleName(), e); + } + } + }; + } + + // ---- typed conveniences ---- + + public final class Sites { + private Sites() {} + + public Site get(String siteId) { + return call("getSite", Request.of().withPath("siteId", siteId), Site.class); + } + + public Site create(SiteCreate body) { + return call("createSite", Request.of().withBody(body), Site.class); + } + + public Iterable all() { + return items("listSites", Request.of(), Site.class); + } + } + + public final class WarmRuns { + private WarmRuns() {} + + /** Starts a run (202). An Idempotency-Key is always sent (random unless {@code idempotencyKey} is given). */ + public WarmRun create(String siteId, WarmRunCreate body, String idempotencyKey) { + return call("createWarmRun", + Request.of().withPath("siteId", siteId).withBody(body).withIdempotencyKey(idempotencyKey), WarmRun.class); + } + + public WarmRun create(String siteId, WarmRunCreate body) { + return create(siteId, body, null); + } + + public WarmRun get(String runId) { + return call("getWarmRun", Request.of().withPath("runId", runId), WarmRun.class); + } + + public WarmRun cancel(String runId) { + return call("cancelWarmRun", Request.of().withPath("runId", runId), WarmRun.class); + } + + /** All results of a run; {@code finalState} (null for all) filters by final cache state. */ + public Iterable results(String runId, String finalState) { + return items("listWarmRunResults", + Request.of().withPath("runId", runId).withQuery("final_state", finalState), Result.class); + } + + /** + * Polls until the run is completed, canceled or failed, honoring Retry-After. Throws + * {@link SiteWarmException.WaitTimeout} on timeout and does NOT cancel the run. + */ + public WarmRun waitFor(String runId, Duration timeout, Duration pollInterval) { + Instant deadline = Instant.now().plus(timeout); + Duration min = Duration.ofSeconds(1); + Duration max = Duration.ofSeconds(60); + while (true) { + Response r = exchange("getWarmRun", Request.of().withPath("runId", runId)); + String status = r.body().path("status").asText(); + if (status.equals("completed") || status.equals("canceled") || status.equals("failed")) { + return convert(r.body()); + } + Duration remaining = Duration.between(Instant.now(), deadline); + if (remaining.isNegative() || remaining.isZero()) throw new SiteWarmException.WaitTimeout(runId, status); + Duration hinted = parseRetryAfter(r.header("Retry-After")); + Duration delay = hinted != null ? hinted : pollInterval; + delay = delay.compareTo(min) < 0 ? min : delay.compareTo(max) > 0 ? max : delay; + if (delay.compareTo(remaining) >= 0) { + pause(remaining); + WarmRun fin = get(runId); + if (isTerminal(fin)) return fin; + throw new SiteWarmException.WaitTimeout(runId, String.valueOf(fin.getStatus())); + } + pause(delay); + } + } + + private boolean isTerminal(WarmRun run) { + String s = String.valueOf(run.getStatus()); + return s.equals("completed") || s.equals("canceled") || s.equals("failed"); + } + + private WarmRun convert(JsonNode n) { + try { + return MAPPER.treeToValue(n, WarmRun.class); + } catch (IOException e) { + throw new SiteWarmException("response does not match WarmRun", e); + } + } + } +} diff --git a/src/main/java/com/sitewarm/sdk/SiteWarmException.java b/src/main/java/com/sitewarm/sdk/SiteWarmException.java new file mode 100644 index 0000000..aa6313d --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/SiteWarmException.java @@ -0,0 +1,139 @@ +package com.sitewarm.sdk; + +import com.fasterxml.jackson.databind.JsonNode; +import java.time.Duration; +import java.util.OptionalInt; + +/** Base class of every exception thrown by this SDK. Messages never contain the API key. */ +public class SiteWarmException extends RuntimeException { + public SiteWarmException(String message) { + super(message); + } + + public SiteWarmException(String message, Throwable cause) { + super(message, cause); + } + + /** The request never produced an HTTP response (DNS, TLS, reset, timeout). */ + public static final class Connection extends SiteWarmException { + private final boolean timeout; + + public Connection(String message, boolean timeout, Throwable cause) { + super(message, cause); + this.timeout = timeout; + } + + public boolean isTimeout() { + return timeout; + } + } + + /** The response body was larger than the SDK reads (32 MiB). Not retried. */ + public static final class ResponseTooLarge extends SiteWarmException { + private final int limit; + + public ResponseTooLarge(int limit) { + super("response body is larger than " + limit + " bytes"); + this.limit = limit; + } + + public int limit() { + return limit; + } + } + + /** A 2xx response body was not valid JSON (for example an HTML page from a proxy). Never includes the body. */ + public static final class Decode extends SiteWarmException { + private final int status; + + public Decode(int status) { + super("invalid JSON in " + status + " response"); + this.status = status; + } + + public int status() { + return status; + } + } + + /** {@code WarmRuns.waitFor} gave up. The run keeps going server side and is NOT canceled. */ + public static final class WaitTimeout extends SiteWarmException { + private final String runId; + private final String lastStatus; + + public WaitTimeout(String runId, String lastStatus) { + super("warm run " + runId + " did not finish in time (last status: " + lastStatus + ")"); + this.runId = runId; + this.lastStatus = lastStatus; + } + + public String runId() { + return runId; + } + + public String lastStatus() { + return lastStatus; + } + } + + /** The API answered with a non-2xx status. */ + public static final class Api extends SiteWarmException { + public enum Kind { AUTHENTICATION, PERMISSION, NOT_FOUND, CONFLICT, VALIDATION, RATE_LIMITED, SERVER, OTHER } + + private final int status; + private final JsonNode problem; + private final String code; + private final Duration retryAfter; + private final OptionalInt rateLimitRemaining; + + Api(int status, JsonNode problem, String code, Duration retryAfter, OptionalInt rateLimitRemaining) { + super(message(status, problem)); + this.status = status; + this.problem = problem; + this.code = code; + this.retryAfter = retryAfter; + this.rateLimitRemaining = rateLimitRemaining; + } + + private static String message(int status, JsonNode p) { + StringBuilder s = new StringBuilder("sitewarm API error ").append(status); + if (p.path("title").isTextual()) s.append(": ").append(p.get("title").asText()); + if (p.path("detail").isTextual()) s.append(" (").append(p.get("detail").asText()).append(')'); + return s.toString(); + } + + public int status() { + return status; + } + + /** The RFC 9457 problem body. */ + public JsonNode problem() { + return problem; + } + + /** The problem type slug (for example {@code site-not-verified}); null when unknown. */ + public String code() { + return code; + } + + /** Parsed {@code Retry-After}; null when absent. */ + public Duration retryAfter() { + return retryAfter; + } + + public OptionalInt rateLimitRemaining() { + return rateLimitRemaining; + } + + public Kind kind() { + if (status == 401) return Kind.AUTHENTICATION; + if (status == 403) return Kind.PERMISSION; + if (status == 404) return Kind.NOT_FOUND; + if (status == 409) return Kind.CONFLICT; + if (status == 400 || status == 422) return Kind.VALIDATION; + if (status == 429) return Kind.RATE_LIMITED; + if (status >= 500) return Kind.SERVER; + return Kind.OTHER; + } + } +} diff --git a/src/main/java/com/sitewarm/sdk/model/AbstractOpenApiSchema.java b/src/main/java/com/sitewarm/sdk/model/AbstractOpenApiSchema.java new file mode 100644 index 0000000..b09ab58 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/AbstractOpenApiSchema.java @@ -0,0 +1,144 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.util.Objects; +import java.lang.reflect.Type; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec + */ +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public abstract class AbstractOpenApiSchema { + + // store the actual instance of the schema/object + private Object instance; + + // is nullable + private Boolean isNullable; + + // schema type (e.g. oneOf, anyOf) + private final String schemaType; + + public AbstractOpenApiSchema(String schemaType, Boolean isNullable) { + this.schemaType = schemaType; + this.isNullable = isNullable; + } + + /** + * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object + * + * @return an instance of the actual schema/object + */ + public abstract Map> getSchemas(); + + /** + * Get the actual instance + * + * @return an instance of the actual schema/object + */ + @JsonValue + public Object getActualInstance() {return instance;} + + /** + * Set the actual instance + * + * @param instance the actual instance of the schema/object + */ + public void setActualInstance(Object instance) {this.instance = instance;} + + /** + * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well + * + * @return an instance of the actual schema/object + */ + public Object getActualInstanceRecursively() { + return getActualInstanceRecursively(this); + } + + private Object getActualInstanceRecursively(AbstractOpenApiSchema object) { + if (object.getActualInstance() == null) { + return null; + } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) { + return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance()); + } else { + return object.getActualInstance(); + } + } + + /** + * Get the schema type (e.g. anyOf, oneOf) + * + * @return the schema type + */ + public String getSchemaType() { + return schemaType; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ").append(getClass()).append(" {\n"); + sb.append(" instance: ").append(toIndentedString(instance)).append("\n"); + sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\n"); + sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AbstractOpenApiSchema a = (AbstractOpenApiSchema) o; + return Objects.equals(this.instance, a.instance) && + Objects.equals(this.isNullable, a.isNullable) && + Objects.equals(this.schemaType, a.schemaType); + } + + @Override + public int hashCode() { + return Objects.hash(instance, isNullable, schemaType); + } + + /** + * Is nullable + * + * @return true if it's nullable + */ + public Boolean isNullable() { + if (Boolean.TRUE.equals(isNullable)) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } + + + +} diff --git a/src/main/java/com/sitewarm/sdk/model/ApiKey.java b/src/main/java/com/sitewarm/sdk/model/ApiKey.java new file mode 100644 index 0000000..84ba10d --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ApiKey.java @@ -0,0 +1,430 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Scope; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ApiKey + */ +@JsonPropertyOrder({ + ApiKey.JSON_PROPERTY_CREATED_AT, + ApiKey.JSON_PROPERTY_EXPIRES_AT, + ApiKey.JSON_PROPERTY_ID, + ApiKey.JSON_PROPERTY_LAST_USED_AT, + ApiKey.JSON_PROPERTY_NAME, + ApiKey.JSON_PROPERTY_PREFIX, + ApiKey.JSON_PROPERTY_SCOPES, + ApiKey.JSON_PROPERTY_SITE_IDS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ApiKey { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_EXPIRES_AT = "expires_at"; + @jakarta.annotation.Nullable + private OffsetDateTime expiresAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_LAST_USED_AT = "last_used_at"; + @jakarta.annotation.Nullable + private OffsetDateTime lastUsedAt; + + public static final String JSON_PROPERTY_NAME = "name"; + @jakarta.annotation.Nonnull + private String name; + + public static final String JSON_PROPERTY_PREFIX = "prefix"; + @jakarta.annotation.Nonnull + private String prefix; + + public static final String JSON_PROPERTY_SCOPES = "scopes"; + @jakarta.annotation.Nonnull + private List scopes = new ArrayList<>(); + + public static final String JSON_PROPERTY_SITE_IDS = "site_ids"; + @jakarta.annotation.Nullable + private List siteIds; + + public ApiKey() { + } + + public ApiKey createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public ApiKey expiresAt(@jakarta.annotation.Nullable OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + return this; + } + + /** + * Get expiresAt + * @return expiresAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getExpiresAt() { + return expiresAt; + } + + + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExpiresAt(@jakarta.annotation.Nullable OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + } + + + public ApiKey id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public ApiKey lastUsedAt(@jakarta.annotation.Nullable OffsetDateTime lastUsedAt) { + this.lastUsedAt = lastUsedAt; + return this; + } + + /** + * Get lastUsedAt + * @return lastUsedAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_LAST_USED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getLastUsedAt() { + return lastUsedAt; + } + + + @JsonProperty(value = JSON_PROPERTY_LAST_USED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLastUsedAt(@jakarta.annotation.Nullable OffsetDateTime lastUsedAt) { + this.lastUsedAt = lastUsedAt; + } + + + public ApiKey name(@jakarta.annotation.Nonnull String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getName() { + return name; + } + + + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setName(@jakarta.annotation.Nonnull String name) { + this.name = name; + } + + + public ApiKey prefix(@jakarta.annotation.Nonnull String prefix) { + this.prefix = prefix; + return this; + } + + /** + * First characters of the key, to recognize it. Not a secret. + * @return prefix + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PREFIX, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getPrefix() { + return prefix; + } + + + @JsonProperty(value = JSON_PROPERTY_PREFIX, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPrefix(@jakarta.annotation.Nonnull String prefix) { + this.prefix = prefix; + } + + + public ApiKey scopes(@jakarta.annotation.Nonnull List scopes) { + this.scopes = scopes; + return this; + } + + public ApiKey addScopesItem(Scope scopesItem) { + if (this.scopes == null) { + this.scopes = new ArrayList<>(); + } + this.scopes.add(scopesItem); + return this; + } + + /** + * Get scopes + * @return scopes + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SCOPES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getScopes() { + return scopes; + } + + + @JsonProperty(value = JSON_PROPERTY_SCOPES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setScopes(@jakarta.annotation.Nonnull List scopes) { + this.scopes = scopes; + } + + + public ApiKey siteIds(@jakarta.annotation.Nullable List siteIds) { + this.siteIds = siteIds; + return this; + } + + public ApiKey addSiteIdsItem(String siteIdsItem) { + if (this.siteIds == null) { + this.siteIds = new ArrayList<>(); + } + this.siteIds.add(siteIdsItem); + return this; + } + + /** + * If set, the key can only act on these sites. A site-restricted key cannot hold `webhooks:*` or `api-keys:*`. Null means all sites of the organization. + * @return siteIds + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SITE_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getSiteIds() { + return siteIds; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSiteIds(@jakarta.annotation.Nullable List siteIds) { + this.siteIds = siteIds; + } + + + /** + * Return true if this ApiKey object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiKey apiKey = (ApiKey) o; + return Objects.equals(this.createdAt, apiKey.createdAt) && + Objects.equals(this.expiresAt, apiKey.expiresAt) && + Objects.equals(this.id, apiKey.id) && + Objects.equals(this.lastUsedAt, apiKey.lastUsedAt) && + Objects.equals(this.name, apiKey.name) && + Objects.equals(this.prefix, apiKey.prefix) && + Objects.equals(this.scopes, apiKey.scopes) && + Objects.equals(this.siteIds, apiKey.siteIds); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, expiresAt, id, lastUsedAt, name, prefix, scopes, siteIds); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiKey {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" expiresAt: ").append(toIndentedString(expiresAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" lastUsedAt: ").append(toIndentedString(lastUsedAt)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" prefix: ").append(toIndentedString(prefix)).append("\n"); + sb.append(" scopes: ").append(toIndentedString(scopes)).append("\n"); + sb.append(" siteIds: ").append(toIndentedString(siteIds)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `expires_at` to the URL query string + if (getExpiresAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sexpires_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getExpiresAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `last_used_at` to the URL query string + if (getLastUsedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%slast_used_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLastUsedAt())))); + } + + // add `name` to the URL query string + if (getName() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sname%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getName())))); + } + + // add `prefix` to the URL query string + if (getPrefix() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sprefix%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPrefix())))); + } + + // add `scopes` to the URL query string + if (getScopes() != null) { + for (int i = 0; i < getScopes().size(); i++) { + if (getScopes().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sscopes%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getScopes().get(i))))); + } + } + } + + // add `site_ids` to the URL query string + if (getSiteIds() != null) { + for (int i = 0; i < getSiteIds().size(); i++) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_ids%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getSiteIds().get(i))))); + } + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ApiKeyCreate.java b/src/main/java/com/sitewarm/sdk/model/ApiKeyCreate.java new file mode 100644 index 0000000..6d4f14b --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ApiKeyCreate.java @@ -0,0 +1,286 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Scope; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ApiKeyCreate + */ +@JsonPropertyOrder({ + ApiKeyCreate.JSON_PROPERTY_EXPIRES_AT, + ApiKeyCreate.JSON_PROPERTY_NAME, + ApiKeyCreate.JSON_PROPERTY_SCOPES, + ApiKeyCreate.JSON_PROPERTY_SITE_IDS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ApiKeyCreate { + public static final String JSON_PROPERTY_EXPIRES_AT = "expires_at"; + @jakarta.annotation.Nullable + private OffsetDateTime expiresAt; + + public static final String JSON_PROPERTY_NAME = "name"; + @jakarta.annotation.Nonnull + private String name; + + public static final String JSON_PROPERTY_SCOPES = "scopes"; + @jakarta.annotation.Nonnull + private List scopes = new ArrayList<>(); + + public static final String JSON_PROPERTY_SITE_IDS = "site_ids"; + @jakarta.annotation.Nullable + private List siteIds; + + public ApiKeyCreate() { + } + + public ApiKeyCreate expiresAt(@jakarta.annotation.Nullable OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + return this; + } + + /** + * Get expiresAt + * @return expiresAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getExpiresAt() { + return expiresAt; + } + + + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExpiresAt(@jakarta.annotation.Nullable OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + } + + + public ApiKeyCreate name(@jakarta.annotation.Nonnull String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getName() { + return name; + } + + + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setName(@jakarta.annotation.Nonnull String name) { + this.name = name; + } + + + public ApiKeyCreate scopes(@jakarta.annotation.Nonnull List scopes) { + this.scopes = scopes; + return this; + } + + public ApiKeyCreate addScopesItem(Scope scopesItem) { + if (this.scopes == null) { + this.scopes = new ArrayList<>(); + } + this.scopes.add(scopesItem); + return this; + } + + /** + * Get scopes + * @return scopes + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SCOPES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getScopes() { + return scopes; + } + + + @JsonProperty(value = JSON_PROPERTY_SCOPES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setScopes(@jakarta.annotation.Nonnull List scopes) { + this.scopes = scopes; + } + + + public ApiKeyCreate siteIds(@jakarta.annotation.Nullable List siteIds) { + this.siteIds = siteIds; + return this; + } + + public ApiKeyCreate addSiteIdsItem(String siteIdsItem) { + if (this.siteIds == null) { + this.siteIds = new ArrayList<>(); + } + this.siteIds.add(siteIdsItem); + return this; + } + + /** + * Get siteIds + * @return siteIds + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SITE_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getSiteIds() { + return siteIds; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSiteIds(@jakarta.annotation.Nullable List siteIds) { + this.siteIds = siteIds; + } + + + /** + * Return true if this ApiKeyCreate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiKeyCreate apiKeyCreate = (ApiKeyCreate) o; + return Objects.equals(this.expiresAt, apiKeyCreate.expiresAt) && + Objects.equals(this.name, apiKeyCreate.name) && + Objects.equals(this.scopes, apiKeyCreate.scopes) && + Objects.equals(this.siteIds, apiKeyCreate.siteIds); + } + + @Override + public int hashCode() { + return Objects.hash(expiresAt, name, scopes, siteIds); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiKeyCreate {\n"); + sb.append(" expiresAt: ").append(toIndentedString(expiresAt)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" scopes: ").append(toIndentedString(scopes)).append("\n"); + sb.append(" siteIds: ").append(toIndentedString(siteIds)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `expires_at` to the URL query string + if (getExpiresAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sexpires_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getExpiresAt())))); + } + + // add `name` to the URL query string + if (getName() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sname%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getName())))); + } + + // add `scopes` to the URL query string + if (getScopes() != null) { + for (int i = 0; i < getScopes().size(); i++) { + if (getScopes().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sscopes%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getScopes().get(i))))); + } + } + } + + // add `site_ids` to the URL query string + if (getSiteIds() != null) { + for (int i = 0; i < getSiteIds().size(); i++) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_ids%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getSiteIds().get(i))))); + } + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ApiKeyList.java b/src/main/java/com/sitewarm/sdk/model/ApiKeyList.java new file mode 100644 index 0000000..c6af46b --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ApiKeyList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.ApiKey; +import com.sitewarm.sdk.model.PageInfo; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ApiKeyList + */ +@JsonPropertyOrder({ + ApiKeyList.JSON_PROPERTY_DATA, + ApiKeyList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ApiKeyList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public ApiKeyList() { + } + + public ApiKeyList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public ApiKeyList addDataItem(ApiKey dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public ApiKeyList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this ApiKeyList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiKeyList apiKeyList = (ApiKeyList) o; + return Objects.equals(this.data, apiKeyList.data) && + Objects.equals(this.page, apiKeyList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiKeyList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ApiKeyWithSecret.java b/src/main/java/com/sitewarm/sdk/model/ApiKeyWithSecret.java new file mode 100644 index 0000000..7638788 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ApiKeyWithSecret.java @@ -0,0 +1,466 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Scope; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ApiKeyWithSecret + */ +@JsonPropertyOrder({ + ApiKeyWithSecret.JSON_PROPERTY_CREATED_AT, + ApiKeyWithSecret.JSON_PROPERTY_EXPIRES_AT, + ApiKeyWithSecret.JSON_PROPERTY_ID, + ApiKeyWithSecret.JSON_PROPERTY_LAST_USED_AT, + ApiKeyWithSecret.JSON_PROPERTY_NAME, + ApiKeyWithSecret.JSON_PROPERTY_PREFIX, + ApiKeyWithSecret.JSON_PROPERTY_SCOPES, + ApiKeyWithSecret.JSON_PROPERTY_SITE_IDS, + ApiKeyWithSecret.JSON_PROPERTY_SECRET +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ApiKeyWithSecret { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_EXPIRES_AT = "expires_at"; + @jakarta.annotation.Nullable + private OffsetDateTime expiresAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_LAST_USED_AT = "last_used_at"; + @jakarta.annotation.Nullable + private OffsetDateTime lastUsedAt; + + public static final String JSON_PROPERTY_NAME = "name"; + @jakarta.annotation.Nonnull + private String name; + + public static final String JSON_PROPERTY_PREFIX = "prefix"; + @jakarta.annotation.Nonnull + private String prefix; + + public static final String JSON_PROPERTY_SCOPES = "scopes"; + @jakarta.annotation.Nonnull + private List scopes = new ArrayList<>(); + + public static final String JSON_PROPERTY_SITE_IDS = "site_ids"; + @jakarta.annotation.Nullable + private List siteIds; + + public static final String JSON_PROPERTY_SECRET = "secret"; + @jakarta.annotation.Nonnull + private String secret; + + public ApiKeyWithSecret() { + } + + public ApiKeyWithSecret createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public ApiKeyWithSecret expiresAt(@jakarta.annotation.Nullable OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + return this; + } + + /** + * Get expiresAt + * @return expiresAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getExpiresAt() { + return expiresAt; + } + + + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExpiresAt(@jakarta.annotation.Nullable OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + } + + + public ApiKeyWithSecret id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public ApiKeyWithSecret lastUsedAt(@jakarta.annotation.Nullable OffsetDateTime lastUsedAt) { + this.lastUsedAt = lastUsedAt; + return this; + } + + /** + * Get lastUsedAt + * @return lastUsedAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_LAST_USED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getLastUsedAt() { + return lastUsedAt; + } + + + @JsonProperty(value = JSON_PROPERTY_LAST_USED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLastUsedAt(@jakarta.annotation.Nullable OffsetDateTime lastUsedAt) { + this.lastUsedAt = lastUsedAt; + } + + + public ApiKeyWithSecret name(@jakarta.annotation.Nonnull String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getName() { + return name; + } + + + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setName(@jakarta.annotation.Nonnull String name) { + this.name = name; + } + + + public ApiKeyWithSecret prefix(@jakarta.annotation.Nonnull String prefix) { + this.prefix = prefix; + return this; + } + + /** + * First characters of the key, to recognize it. Not a secret. + * @return prefix + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PREFIX, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getPrefix() { + return prefix; + } + + + @JsonProperty(value = JSON_PROPERTY_PREFIX, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPrefix(@jakarta.annotation.Nonnull String prefix) { + this.prefix = prefix; + } + + + public ApiKeyWithSecret scopes(@jakarta.annotation.Nonnull List scopes) { + this.scopes = scopes; + return this; + } + + public ApiKeyWithSecret addScopesItem(Scope scopesItem) { + if (this.scopes == null) { + this.scopes = new ArrayList<>(); + } + this.scopes.add(scopesItem); + return this; + } + + /** + * Get scopes + * @return scopes + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SCOPES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getScopes() { + return scopes; + } + + + @JsonProperty(value = JSON_PROPERTY_SCOPES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setScopes(@jakarta.annotation.Nonnull List scopes) { + this.scopes = scopes; + } + + + public ApiKeyWithSecret siteIds(@jakarta.annotation.Nullable List siteIds) { + this.siteIds = siteIds; + return this; + } + + public ApiKeyWithSecret addSiteIdsItem(String siteIdsItem) { + if (this.siteIds == null) { + this.siteIds = new ArrayList<>(); + } + this.siteIds.add(siteIdsItem); + return this; + } + + /** + * If set, the key can only act on these sites. A site-restricted key cannot hold `webhooks:*` or `api-keys:*`. Null means all sites of the organization. + * @return siteIds + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SITE_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getSiteIds() { + return siteIds; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSiteIds(@jakarta.annotation.Nullable List siteIds) { + this.siteIds = siteIds; + } + + + public ApiKeyWithSecret secret(@jakarta.annotation.Nonnull String secret) { + this.secret = secret; + return this; + } + + /** + * The API key. Shown only in this response. + * @return secret + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SECRET, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSecret() { + return secret; + } + + + @JsonProperty(value = JSON_PROPERTY_SECRET, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSecret(@jakarta.annotation.Nonnull String secret) { + this.secret = secret; + } + + + /** + * Return true if this ApiKeyWithSecret object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiKeyWithSecret apiKeyWithSecret = (ApiKeyWithSecret) o; + return Objects.equals(this.createdAt, apiKeyWithSecret.createdAt) && + Objects.equals(this.expiresAt, apiKeyWithSecret.expiresAt) && + Objects.equals(this.id, apiKeyWithSecret.id) && + Objects.equals(this.lastUsedAt, apiKeyWithSecret.lastUsedAt) && + Objects.equals(this.name, apiKeyWithSecret.name) && + Objects.equals(this.prefix, apiKeyWithSecret.prefix) && + Objects.equals(this.scopes, apiKeyWithSecret.scopes) && + Objects.equals(this.siteIds, apiKeyWithSecret.siteIds) && + Objects.equals(this.secret, apiKeyWithSecret.secret); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, expiresAt, id, lastUsedAt, name, prefix, scopes, siteIds, secret); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiKeyWithSecret {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" expiresAt: ").append(toIndentedString(expiresAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" lastUsedAt: ").append(toIndentedString(lastUsedAt)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" prefix: ").append(toIndentedString(prefix)).append("\n"); + sb.append(" scopes: ").append(toIndentedString(scopes)).append("\n"); + sb.append(" siteIds: ").append(toIndentedString(siteIds)).append("\n"); + sb.append(" secret: ").append(toIndentedString(secret)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `expires_at` to the URL query string + if (getExpiresAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sexpires_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getExpiresAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `last_used_at` to the URL query string + if (getLastUsedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%slast_used_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLastUsedAt())))); + } + + // add `name` to the URL query string + if (getName() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sname%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getName())))); + } + + // add `prefix` to the URL query string + if (getPrefix() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sprefix%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPrefix())))); + } + + // add `scopes` to the URL query string + if (getScopes() != null) { + for (int i = 0; i < getScopes().size(); i++) { + if (getScopes().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sscopes%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getScopes().get(i))))); + } + } + } + + // add `site_ids` to the URL query string + if (getSiteIds() != null) { + for (int i = 0; i < getSiteIds().size(); i++) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_ids%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getSiteIds().get(i))))); + } + } + + // add `secret` to the URL query string + if (getSecret() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssecret%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSecret())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/CacheState.java b/src/main/java/com/sitewarm/sdk/model/CacheState.java new file mode 100644 index 0000000..baac5cd --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/CacheState.java @@ -0,0 +1,104 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Normalized cache status of one URL and profile at one vantage point, exactly the engine states. `unknown` means the CDN does not expose a status (see `unknown_reason`). Clients must tolerate new values. + */ +public enum CacheState { + + HIT("hit"), + + STALE("stale"), + + MISS("miss"), + + BYPASS("bypass"), + + VARIANT_UNVERIFIABLE("variant-unverifiable"), + + CHALLENGED("challenged"), + + CLIENT_ERROR("client-error"), + + REDIRECT_ERROR("redirect-error"), + + ERROR("error"), + + INCOMPLETE("incomplete"), + + UNKNOWN("unknown"), + + SKIPPED_ROBOTS("skipped-robots"), + + STALE_REVISION("stale-revision"), + + EXPECTED("expected"), + + UNEXPECTED("unexpected"); + + private String value; + + CacheState(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static CacheState fromValue(String value) { + for (CacheState b : CacheState.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/CacheStatusReport.java b/src/main/java/com/sitewarm/sdk/model/CacheStatusReport.java new file mode 100644 index 0000000..426c062 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/CacheStatusReport.java @@ -0,0 +1,309 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.ReportCell; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * CacheStatusReport + */ +@JsonPropertyOrder({ + CacheStatusReport.JSON_PROPERTY_CREATED_AT, + CacheStatusReport.JSON_PROPERTY_ID, + CacheStatusReport.JSON_PROPERTY_SITE_ID, + CacheStatusReport.JSON_PROPERTY_WARM_RUN_ID, + CacheStatusReport.JSON_PROPERTY_CELLS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class CacheStatusReport { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_SITE_ID = "site_id"; + @jakarta.annotation.Nonnull + private String siteId; + + public static final String JSON_PROPERTY_WARM_RUN_ID = "warm_run_id"; + @jakarta.annotation.Nonnull + private String warmRunId; + + public static final String JSON_PROPERTY_CELLS = "cells"; + @jakarta.annotation.Nonnull + private List cells = new ArrayList<>(); + + public CacheStatusReport() { + } + + public CacheStatusReport createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public CacheStatusReport id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public CacheStatusReport siteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + return this; + } + + /** + * Get siteId + * @return siteId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSiteId() { + return siteId; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSiteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + } + + + public CacheStatusReport warmRunId(@jakarta.annotation.Nonnull String warmRunId) { + this.warmRunId = warmRunId; + return this; + } + + /** + * Get warmRunId + * @return warmRunId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_WARM_RUN_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getWarmRunId() { + return warmRunId; + } + + + @JsonProperty(value = JSON_PROPERTY_WARM_RUN_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setWarmRunId(@jakarta.annotation.Nonnull String warmRunId) { + this.warmRunId = warmRunId; + } + + + public CacheStatusReport cells(@jakarta.annotation.Nonnull List cells) { + this.cells = cells; + return this; + } + + public CacheStatusReport addCellsItem(ReportCell cellsItem) { + if (this.cells == null) { + this.cells = new ArrayList<>(); + } + this.cells.add(cellsItem); + return this; + } + + /** + * Get cells + * @return cells + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CELLS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getCells() { + return cells; + } + + + @JsonProperty(value = JSON_PROPERTY_CELLS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCells(@jakarta.annotation.Nonnull List cells) { + this.cells = cells; + } + + + /** + * Return true if this CacheStatusReport object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheStatusReport cacheStatusReport = (CacheStatusReport) o; + return Objects.equals(this.createdAt, cacheStatusReport.createdAt) && + Objects.equals(this.id, cacheStatusReport.id) && + Objects.equals(this.siteId, cacheStatusReport.siteId) && + Objects.equals(this.warmRunId, cacheStatusReport.warmRunId) && + Objects.equals(this.cells, cacheStatusReport.cells); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, siteId, warmRunId, cells); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CacheStatusReport {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" siteId: ").append(toIndentedString(siteId)).append("\n"); + sb.append(" warmRunId: ").append(toIndentedString(warmRunId)).append("\n"); + sb.append(" cells: ").append(toIndentedString(cells)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `site_id` to the URL query string + if (getSiteId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSiteId())))); + } + + // add `warm_run_id` to the URL query string + if (getWarmRunId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%swarm_run_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getWarmRunId())))); + } + + // add `cells` to the URL query string + if (getCells() != null) { + for (int i = 0; i < getCells().size(); i++) { + if (getCells().get(i) != null) { + joiner.add(getCells().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%scells%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/CacheStatusReportList.java b/src/main/java/com/sitewarm/sdk/model/CacheStatusReportList.java new file mode 100644 index 0000000..7f7502e --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/CacheStatusReportList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.CacheStatusReportSummary; +import com.sitewarm.sdk.model.PageInfo; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * CacheStatusReportList + */ +@JsonPropertyOrder({ + CacheStatusReportList.JSON_PROPERTY_DATA, + CacheStatusReportList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class CacheStatusReportList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public CacheStatusReportList() { + } + + public CacheStatusReportList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public CacheStatusReportList addDataItem(CacheStatusReportSummary dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public CacheStatusReportList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this CacheStatusReportList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheStatusReportList cacheStatusReportList = (CacheStatusReportList) o; + return Objects.equals(this.data, cacheStatusReportList.data) && + Objects.equals(this.page, cacheStatusReportList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CacheStatusReportList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/CacheStatusReportSummary.java b/src/main/java/com/sitewarm/sdk/model/CacheStatusReportSummary.java new file mode 100644 index 0000000..51958de --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/CacheStatusReportSummary.java @@ -0,0 +1,257 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * CacheStatusReportSummary + */ +@JsonPropertyOrder({ + CacheStatusReportSummary.JSON_PROPERTY_CREATED_AT, + CacheStatusReportSummary.JSON_PROPERTY_ID, + CacheStatusReportSummary.JSON_PROPERTY_SITE_ID, + CacheStatusReportSummary.JSON_PROPERTY_WARM_RUN_ID +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class CacheStatusReportSummary { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_SITE_ID = "site_id"; + @jakarta.annotation.Nonnull + private String siteId; + + public static final String JSON_PROPERTY_WARM_RUN_ID = "warm_run_id"; + @jakarta.annotation.Nonnull + private String warmRunId; + + public CacheStatusReportSummary() { + } + + public CacheStatusReportSummary createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public CacheStatusReportSummary id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public CacheStatusReportSummary siteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + return this; + } + + /** + * Get siteId + * @return siteId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSiteId() { + return siteId; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSiteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + } + + + public CacheStatusReportSummary warmRunId(@jakarta.annotation.Nonnull String warmRunId) { + this.warmRunId = warmRunId; + return this; + } + + /** + * Get warmRunId + * @return warmRunId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_WARM_RUN_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getWarmRunId() { + return warmRunId; + } + + + @JsonProperty(value = JSON_PROPERTY_WARM_RUN_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setWarmRunId(@jakarta.annotation.Nonnull String warmRunId) { + this.warmRunId = warmRunId; + } + + + /** + * Return true if this CacheStatusReportSummary object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheStatusReportSummary cacheStatusReportSummary = (CacheStatusReportSummary) o; + return Objects.equals(this.createdAt, cacheStatusReportSummary.createdAt) && + Objects.equals(this.id, cacheStatusReportSummary.id) && + Objects.equals(this.siteId, cacheStatusReportSummary.siteId) && + Objects.equals(this.warmRunId, cacheStatusReportSummary.warmRunId); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, siteId, warmRunId); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CacheStatusReportSummary {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" siteId: ").append(toIndentedString(siteId)).append("\n"); + sb.append(" warmRunId: ").append(toIndentedString(warmRunId)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `site_id` to the URL query string + if (getSiteId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSiteId())))); + } + + // add `warm_run_id` to the URL query string + if (getWarmRunId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%swarm_run_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getWarmRunId())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Cadence.java b/src/main/java/com/sitewarm/sdk/model/Cadence.java new file mode 100644 index 0000000..c2d8628 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Cadence.java @@ -0,0 +1,220 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Run every N hours or days. Allowed values depend on the organization's limits. + */ +@JsonPropertyOrder({ + Cadence.JSON_PROPERTY_EVERY, + Cadence.JSON_PROPERTY_UNIT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Cadence { + public static final String JSON_PROPERTY_EVERY = "every"; + @jakarta.annotation.Nonnull + private Integer every; + + /** + * Gets or Sets unit + */ + public enum UnitEnum { + HOUR(String.valueOf("hour")), + + DAY(String.valueOf("day")); + + private String value; + + UnitEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static UnitEnum fromValue(String value) { + for (UnitEnum b : UnitEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_UNIT = "unit"; + @jakarta.annotation.Nonnull + private UnitEnum unit; + + public Cadence() { + } + + public Cadence every(@jakarta.annotation.Nonnull Integer every) { + this.every = every; + return this; + } + + /** + * Get every + * minimum: 1 + * @return every + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_EVERY, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getEvery() { + return every; + } + + + @JsonProperty(value = JSON_PROPERTY_EVERY, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEvery(@jakarta.annotation.Nonnull Integer every) { + this.every = every; + } + + + public Cadence unit(@jakarta.annotation.Nonnull UnitEnum unit) { + this.unit = unit; + return this; + } + + /** + * Get unit + * @return unit + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_UNIT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public UnitEnum getUnit() { + return unit; + } + + + @JsonProperty(value = JSON_PROPERTY_UNIT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUnit(@jakarta.annotation.Nonnull UnitEnum unit) { + this.unit = unit; + } + + + /** + * Return true if this Cadence object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Cadence cadence = (Cadence) o; + return Objects.equals(this.every, cadence.every) && + Objects.equals(this.unit, cadence.unit); + } + + @Override + public int hashCode() { + return Objects.hash(every, unit); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Cadence {\n"); + sb.append(" every: ").append(toIndentedString(every)).append("\n"); + sb.append(" unit: ").append(toIndentedString(unit)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `every` to the URL query string + if (getEvery() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%severy%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEvery())))); + } + + // add `unit` to the URL query string + if (getUnit() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sunit%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUnit())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Deployment.java b/src/main/java/com/sitewarm/sdk/model/Deployment.java new file mode 100644 index 0000000..bef096f --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Deployment.java @@ -0,0 +1,220 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Context of the deploy that caused the run, echoed to the results and webhooks. + */ +@JsonPropertyOrder({ + Deployment.JSON_PROPERTY_ENVIRONMENT, + Deployment.JSON_PROPERTY_ID, + Deployment.JSON_PROPERTY_REF +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Deployment { + public static final String JSON_PROPERTY_ENVIRONMENT = "environment"; + @jakarta.annotation.Nullable + private String environment; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nullable + private String id; + + public static final String JSON_PROPERTY_REF = "ref"; + @jakarta.annotation.Nullable + private String ref; + + public Deployment() { + } + + public Deployment environment(@jakarta.annotation.Nullable String environment) { + this.environment = environment; + return this; + } + + /** + * Get environment + * @return environment + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ENVIRONMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getEnvironment() { + return environment; + } + + + @JsonProperty(value = JSON_PROPERTY_ENVIRONMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setEnvironment(@jakarta.annotation.Nullable String environment) { + this.environment = environment; + } + + + public Deployment id(@jakarta.annotation.Nullable String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setId(@jakarta.annotation.Nullable String id) { + this.id = id; + } + + + public Deployment ref(@jakarta.annotation.Nullable String ref) { + this.ref = ref; + return this; + } + + /** + * Commit SHA, tag or other revision label. + * @return ref + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REF, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getRef() { + return ref; + } + + + @JsonProperty(value = JSON_PROPERTY_REF, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRef(@jakarta.annotation.Nullable String ref) { + this.ref = ref; + } + + + /** + * Return true if this Deployment object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Deployment deployment = (Deployment) o; + return Objects.equals(this.environment, deployment.environment) && + Objects.equals(this.id, deployment.id) && + Objects.equals(this.ref, deployment.ref); + } + + @Override + public int hashCode() { + return Objects.hash(environment, id, ref); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Deployment {\n"); + sb.append(" environment: ").append(toIndentedString(environment)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" ref: ").append(toIndentedString(ref)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `environment` to the URL query string + if (getEnvironment() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senvironment%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnvironment())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `ref` to the URL query string + if (getRef() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sref%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getRef())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/EffectiveRunOptions.java b/src/main/java/com/sitewarm/sdk/model/EffectiveRunOptions.java new file mode 100644 index 0000000..32e7042 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/EffectiveRunOptions.java @@ -0,0 +1,251 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.FailOnToken; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * The options of a run as accepted. `fail_on` is the list the run was created with, or the list the engine reports it applied once known; it is null until then (no default is invented). + */ +@JsonPropertyOrder({ + EffectiveRunOptions.JSON_PROPERTY_FAIL_ON, + EffectiveRunOptions.JSON_PROPERTY_TOP +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class EffectiveRunOptions { + public static final String JSON_PROPERTY_FAIL_ON = "fail_on"; + @jakarta.annotation.Nullable + private List failOn; + + public static final String JSON_PROPERTY_TOP = "top"; + @jakarta.annotation.Nullable + private Integer top; + + public EffectiveRunOptions() { + } + + public EffectiveRunOptions failOn(@jakarta.annotation.Nullable List failOn) { + this.failOn = failOn; + return this; + } + + public EffectiveRunOptions addFailOnItem(FailOnToken failOnItem) { + if (this.failOn == null) { + this.failOn = new ArrayList<>(); + } + this.failOn.add(failOnItem); + return this; + } + + /** + * The list in effect, or null while the engine default is not yet reported. + * @return failOn + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_FAIL_ON, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getFailOn() { + return failOn; + } + + + @JsonProperty(value = JSON_PROPERTY_FAIL_ON, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFailOn(@jakarta.annotation.Nullable List failOn) { + this.failOn = failOn; + } + + + public EffectiveRunOptions top(@jakarta.annotation.Nullable Integer top) { + this.top = top; + return this; + } + + /** + * Get top + * minimum: 1 + * @return top + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TOP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getTop() { + return top; + } + + + @JsonProperty(value = JSON_PROPERTY_TOP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTop(@jakarta.annotation.Nullable Integer top) { + this.top = top; + } + + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. + * If the property does not already exist, create it otherwise replace it. + * @param key the name of the property + * @param value the value of the property + * @return self reference + */ + @JsonAnySetter + public EffectiveRunOptions putAdditionalProperty(String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) properties. + * @return the additional (undeclared) properties + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * @param key the name of the property + * @return the additional (undeclared) property with the specified name + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + /** + * Return true if this EffectiveRunOptions object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EffectiveRunOptions effectiveRunOptions = (EffectiveRunOptions) o; + return Objects.equals(this.failOn, effectiveRunOptions.failOn) && + Objects.equals(this.top, effectiveRunOptions.top)&& + Objects.equals(this.additionalProperties, effectiveRunOptions.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(failOn, top, additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class EffectiveRunOptions {\n"); + sb.append(" failOn: ").append(toIndentedString(failOn)).append("\n"); + sb.append(" top: ").append(toIndentedString(top)).append("\n"); + sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `fail_on` to the URL query string + if (getFailOn() != null) { + for (int i = 0; i < getFailOn().size(); i++) { + if (getFailOn().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfail_on%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getFailOn().get(i))))); + } + } + } + + // add `top` to the URL query string + if (getTop() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stop%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getTop())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/EventEnvelope.java b/src/main/java/com/sitewarm/sdk/model/EventEnvelope.java new file mode 100644 index 0000000..a739b90 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/EventEnvelope.java @@ -0,0 +1,222 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.EventType; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * EventEnvelope + */ +@JsonPropertyOrder({ + EventEnvelope.JSON_PROPERTY_CREATED_AT, + EventEnvelope.JSON_PROPERTY_ID, + EventEnvelope.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class EventEnvelope { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private EventType type; + + public EventEnvelope() { + } + + public EventEnvelope createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public EventEnvelope id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Unique per event. A redelivery of the same event keeps the id; use it to deduplicate. + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public EventEnvelope type(@jakarta.annotation.Nonnull EventType type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public EventType getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull EventType type) { + this.type = type; + } + + + /** + * Return true if this EventEnvelope object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EventEnvelope eventEnvelope = (EventEnvelope) o; + return Objects.equals(this.createdAt, eventEnvelope.createdAt) && + Objects.equals(this.id, eventEnvelope.id) && + Objects.equals(this.type, eventEnvelope.type); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class EventEnvelope {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/EventType.java b/src/main/java/com/sitewarm/sdk/model/EventType.java new file mode 100644 index 0000000..6474366 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/EventType.java @@ -0,0 +1,80 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Events a webhook endpoint can subscribe to. + */ +public enum EventType { + + WARM_RUN_COMPLETED("warm_run.completed"), + + WARM_RUN_CANCELED("warm_run.canceled"), + + SITE_VERIFICATION_CHANGED("site.verification_changed"); + + private String value; + + EventType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static EventType fromValue(String value) { + for (EventType b : EventType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/FailOnToken.java b/src/main/java/com/sitewarm/sdk/model/FailOnToken.java new file mode 100644 index 0000000..7cc8292 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/FailOnToken.java @@ -0,0 +1,108 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * A value accepted by the engine's `--fail-on`: any cache state, or an indexability token. `noindex` also fails on `indexability-error`. + */ +public enum FailOnToken { + + HIT("hit"), + + STALE("stale"), + + MISS("miss"), + + BYPASS("bypass"), + + VARIANT_UNVERIFIABLE("variant-unverifiable"), + + CHALLENGED("challenged"), + + CLIENT_ERROR("client-error"), + + REDIRECT_ERROR("redirect-error"), + + ERROR("error"), + + INCOMPLETE("incomplete"), + + UNKNOWN("unknown"), + + SKIPPED_ROBOTS("skipped-robots"), + + STALE_REVISION("stale-revision"), + + EXPECTED("expected"), + + UNEXPECTED("unexpected"), + + NOINDEX("noindex"), + + INDEXABILITY_INCONCLUSIVE("indexability-inconclusive"); + + private String value; + + FailOnToken(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static FailOnToken fromValue(String value) { + for (FailOnToken b : FailOnToken.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Indexability.java b/src/main/java/com/sitewarm/sdk/model/Indexability.java new file mode 100644 index 0000000..5f8edaf --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Indexability.java @@ -0,0 +1,293 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Indexability is separate from the cache state. + */ +@JsonPropertyOrder({ + Indexability.JSON_PROPERTY_CANONICAL, + Indexability.JSON_PROPERTY_FINDING, + Indexability.JSON_PROPERTY_META_ROBOTS, + Indexability.JSON_PROPERTY_X_ROBOTS_TAG +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Indexability { + public static final String JSON_PROPERTY_CANONICAL = "canonical"; + @jakarta.annotation.Nullable + private String canonical; + + /** + * The engine's finding; null when none was reported. + */ + public enum FindingEnum { + NOINDEX(String.valueOf("noindex")), + + INDEXABILITY_ERROR(String.valueOf("indexability-error")), + + INDEXABILITY_INCONCLUSIVE(String.valueOf("indexability-inconclusive")); + + private String value; + + FindingEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static FindingEnum fromValue(String value) { + for (FindingEnum b : FindingEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + return null; + } + } + + public static final String JSON_PROPERTY_FINDING = "finding"; + @jakarta.annotation.Nullable + private FindingEnum finding; + + public static final String JSON_PROPERTY_META_ROBOTS = "meta_robots"; + @jakarta.annotation.Nullable + private String metaRobots; + + public static final String JSON_PROPERTY_X_ROBOTS_TAG = "x_robots_tag"; + @jakarta.annotation.Nullable + private String xRobotsTag; + + public Indexability() { + } + + public Indexability canonical(@jakarta.annotation.Nullable String canonical) { + this.canonical = canonical; + return this; + } + + /** + * Get canonical + * @return canonical + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CANONICAL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getCanonical() { + return canonical; + } + + + @JsonProperty(value = JSON_PROPERTY_CANONICAL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCanonical(@jakarta.annotation.Nullable String canonical) { + this.canonical = canonical; + } + + + public Indexability finding(@jakarta.annotation.Nullable FindingEnum finding) { + this.finding = finding; + return this; + } + + /** + * The engine's finding; null when none was reported. + * @return finding + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_FINDING, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public FindingEnum getFinding() { + return finding; + } + + + @JsonProperty(value = JSON_PROPERTY_FINDING, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFinding(@jakarta.annotation.Nullable FindingEnum finding) { + this.finding = finding; + } + + + public Indexability metaRobots(@jakarta.annotation.Nullable String metaRobots) { + this.metaRobots = metaRobots; + return this; + } + + /** + * Get metaRobots + * @return metaRobots + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_META_ROBOTS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getMetaRobots() { + return metaRobots; + } + + + @JsonProperty(value = JSON_PROPERTY_META_ROBOTS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetaRobots(@jakarta.annotation.Nullable String metaRobots) { + this.metaRobots = metaRobots; + } + + + public Indexability xRobotsTag(@jakarta.annotation.Nullable String xRobotsTag) { + this.xRobotsTag = xRobotsTag; + return this; + } + + /** + * Get xRobotsTag + * @return xRobotsTag + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_X_ROBOTS_TAG, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getxRobotsTag() { + return xRobotsTag; + } + + + @JsonProperty(value = JSON_PROPERTY_X_ROBOTS_TAG, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setxRobotsTag(@jakarta.annotation.Nullable String xRobotsTag) { + this.xRobotsTag = xRobotsTag; + } + + + /** + * Return true if this Indexability object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Indexability indexability = (Indexability) o; + return Objects.equals(this.canonical, indexability.canonical) && + Objects.equals(this.finding, indexability.finding) && + Objects.equals(this.metaRobots, indexability.metaRobots) && + Objects.equals(this.xRobotsTag, indexability.xRobotsTag); + } + + @Override + public int hashCode() { + return Objects.hash(canonical, finding, metaRobots, xRobotsTag); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Indexability {\n"); + sb.append(" canonical: ").append(toIndentedString(canonical)).append("\n"); + sb.append(" finding: ").append(toIndentedString(finding)).append("\n"); + sb.append(" metaRobots: ").append(toIndentedString(metaRobots)).append("\n"); + sb.append(" xRobotsTag: ").append(toIndentedString(xRobotsTag)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `canonical` to the URL query string + if (getCanonical() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%scanonical%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCanonical())))); + } + + // add `finding` to the URL query string + if (getFinding() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfinding%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getFinding())))); + } + + // add `meta_robots` to the URL query string + if (getMetaRobots() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smeta_robots%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMetaRobots())))); + } + + // add `x_robots_tag` to the URL query string + if (getxRobotsTag() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sx_robots_tag%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getxRobotsTag())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Outcome.java b/src/main/java/com/sitewarm/sdk/model/Outcome.java new file mode 100644 index 0000000..e512b64 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Outcome.java @@ -0,0 +1,272 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.FailOnToken; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Whether the run passes, by the `--fail-on` contract. + */ +@JsonPropertyOrder({ + Outcome.JSON_PROPERTY_FAILED, + Outcome.JSON_PROPERTY_FAILING_STATES, + Outcome.JSON_PROPERTY_REASON +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Outcome { + public static final String JSON_PROPERTY_FAILED = "failed"; + @jakarta.annotation.Nonnull + private Boolean failed; + + public static final String JSON_PROPERTY_FAILING_STATES = "failing_states"; + @jakarta.annotation.Nonnull + private List failingStates = new ArrayList<>(); + + /** + * `no_verifications`: no URL could be verified (for example all `skipped-robots`), which fails the run even if `skipped-robots` is not in `fail_on`. Null when the run passed. + */ + public enum ReasonEnum { + FAIL_ON_MATCHED(String.valueOf("fail_on_matched")), + + NO_VERIFICATIONS(String.valueOf("no_verifications")); + + private String value; + + ReasonEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ReasonEnum fromValue(String value) { + for (ReasonEnum b : ReasonEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + return null; + } + } + + public static final String JSON_PROPERTY_REASON = "reason"; + @jakarta.annotation.Nullable + private ReasonEnum reason; + + public Outcome() { + } + + public Outcome failed(@jakarta.annotation.Nonnull Boolean failed) { + this.failed = failed; + return this; + } + + /** + * Get failed + * @return failed + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_FAILED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getFailed() { + return failed; + } + + + @JsonProperty(value = JSON_PROPERTY_FAILED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFailed(@jakarta.annotation.Nonnull Boolean failed) { + this.failed = failed; + } + + + public Outcome failingStates(@jakarta.annotation.Nonnull List failingStates) { + this.failingStates = failingStates; + return this; + } + + public Outcome addFailingStatesItem(FailOnToken failingStatesItem) { + if (this.failingStates == null) { + this.failingStates = new ArrayList<>(); + } + this.failingStates.add(failingStatesItem); + return this; + } + + /** + * Tokens from the effective `fail_on` that matched at least one result. + * @return failingStates + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_FAILING_STATES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getFailingStates() { + return failingStates; + } + + + @JsonProperty(value = JSON_PROPERTY_FAILING_STATES, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFailingStates(@jakarta.annotation.Nonnull List failingStates) { + this.failingStates = failingStates; + } + + + public Outcome reason(@jakarta.annotation.Nullable ReasonEnum reason) { + this.reason = reason; + return this; + } + + /** + * `no_verifications`: no URL could be verified (for example all `skipped-robots`), which fails the run even if `skipped-robots` is not in `fail_on`. Null when the run passed. + * @return reason + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public ReasonEnum getReason() { + return reason; + } + + + @JsonProperty(value = JSON_PROPERTY_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setReason(@jakarta.annotation.Nullable ReasonEnum reason) { + this.reason = reason; + } + + + /** + * Return true if this Outcome object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Outcome outcome = (Outcome) o; + return Objects.equals(this.failed, outcome.failed) && + Objects.equals(this.failingStates, outcome.failingStates) && + Objects.equals(this.reason, outcome.reason); + } + + @Override + public int hashCode() { + return Objects.hash(failed, failingStates, reason); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Outcome {\n"); + sb.append(" failed: ").append(toIndentedString(failed)).append("\n"); + sb.append(" failingStates: ").append(toIndentedString(failingStates)).append("\n"); + sb.append(" reason: ").append(toIndentedString(reason)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `failed` to the URL query string + if (getFailed() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfailed%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getFailed())))); + } + + // add `failing_states` to the URL query string + if (getFailingStates() != null) { + for (int i = 0; i < getFailingStates().size(); i++) { + if (getFailingStates().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfailing_states%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getFailingStates().get(i))))); + } + } + } + + // add `reason` to the URL query string + if (getReason() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sreason%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getReason())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/PageInfo.java b/src/main/java/com/sitewarm/sdk/model/PageInfo.java new file mode 100644 index 0000000..60e81e1 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/PageInfo.java @@ -0,0 +1,184 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * PageInfo + */ +@JsonPropertyOrder({ + PageInfo.JSON_PROPERTY_HAS_MORE, + PageInfo.JSON_PROPERTY_NEXT_CURSOR +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class PageInfo { + public static final String JSON_PROPERTY_HAS_MORE = "has_more"; + @jakarta.annotation.Nonnull + private Boolean hasMore; + + public static final String JSON_PROPERTY_NEXT_CURSOR = "next_cursor"; + @jakarta.annotation.Nullable + private String nextCursor; + + public PageInfo() { + } + + public PageInfo hasMore(@jakarta.annotation.Nonnull Boolean hasMore) { + this.hasMore = hasMore; + return this; + } + + /** + * Get hasMore + * @return hasMore + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_HAS_MORE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getHasMore() { + return hasMore; + } + + + @JsonProperty(value = JSON_PROPERTY_HAS_MORE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHasMore(@jakarta.annotation.Nonnull Boolean hasMore) { + this.hasMore = hasMore; + } + + + public PageInfo nextCursor(@jakarta.annotation.Nullable String nextCursor) { + this.nextCursor = nextCursor; + return this; + } + + /** + * Cursor for the next page; null on the last page. + * @return nextCursor + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_NEXT_CURSOR, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getNextCursor() { + return nextCursor; + } + + + @JsonProperty(value = JSON_PROPERTY_NEXT_CURSOR, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNextCursor(@jakarta.annotation.Nullable String nextCursor) { + this.nextCursor = nextCursor; + } + + + /** + * Return true if this PageInfo object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PageInfo pageInfo = (PageInfo) o; + return Objects.equals(this.hasMore, pageInfo.hasMore) && + Objects.equals(this.nextCursor, pageInfo.nextCursor); + } + + @Override + public int hashCode() { + return Objects.hash(hasMore, nextCursor); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PageInfo {\n"); + sb.append(" hasMore: ").append(toIndentedString(hasMore)).append("\n"); + sb.append(" nextCursor: ").append(toIndentedString(nextCursor)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `has_more` to the URL query string + if (getHasMore() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%shas_more%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getHasMore())))); + } + + // add `next_cursor` to the URL query string + if (getNextCursor() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%snext_cursor%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getNextCursor())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Problem.java b/src/main/java/com/sitewarm/sdk/model/Problem.java new file mode 100644 index 0000000..c3f95db --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Problem.java @@ -0,0 +1,502 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.ProblemErrorsInner; +import com.sitewarm.sdk.model.ProblemType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * RFC 9457 problem details. + */ +@JsonPropertyOrder({ + Problem.JSON_PROPERTY_CODE, + Problem.JSON_PROPERTY_DETAIL, + Problem.JSON_PROPERTY_ERRORS, + Problem.JSON_PROPERTY_INSTANCE, + Problem.JSON_PROPERTY_LIMIT, + Problem.JSON_PROPERTY_PLAN, + Problem.JSON_PROPERTY_STATUS, + Problem.JSON_PROPERTY_TITLE, + Problem.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Problem { + public static final String JSON_PROPERTY_CODE = "code"; + @jakarta.annotation.Nullable + private ProblemType code; + + public static final String JSON_PROPERTY_DETAIL = "detail"; + @jakarta.annotation.Nullable + private String detail; + + public static final String JSON_PROPERTY_ERRORS = "errors"; + @jakarta.annotation.Nullable + private List errors = new ArrayList<>(); + + public static final String JSON_PROPERTY_INSTANCE = "instance"; + @jakarta.annotation.Nullable + private String instance; + + public static final String JSON_PROPERTY_LIMIT = "limit"; + @jakarta.annotation.Nullable + private String limit; + + public static final String JSON_PROPERTY_PLAN = "plan"; + @jakarta.annotation.Nullable + private String plan; + + public static final String JSON_PROPERTY_STATUS = "status"; + @jakarta.annotation.Nonnull + private Integer status; + + public static final String JSON_PROPERTY_TITLE = "title"; + @jakarta.annotation.Nonnull + private String title; + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private String type; + + public Problem() { + } + + public Problem code(@jakarta.annotation.Nullable ProblemType code) { + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public ProblemType getCode() { + return code; + } + + + @JsonProperty(value = JSON_PROPERTY_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCode(@jakarta.annotation.Nullable ProblemType code) { + this.code = code; + } + + + public Problem detail(@jakarta.annotation.Nullable String detail) { + this.detail = detail; + return this; + } + + /** + * Get detail + * @return detail + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DETAIL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getDetail() { + return detail; + } + + + @JsonProperty(value = JSON_PROPERTY_DETAIL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDetail(@jakarta.annotation.Nullable String detail) { + this.detail = detail; + } + + + public Problem errors(@jakarta.annotation.Nullable List errors) { + this.errors = errors; + return this; + } + + public Problem addErrorsItem(ProblemErrorsInner errorsItem) { + if (this.errors == null) { + this.errors = new ArrayList<>(); + } + this.errors.add(errorsItem); + return this; + } + + /** + * Field errors, present for `validation-failed` and `invalid-request`. + * @return errors + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ERRORS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getErrors() { + return errors; + } + + + @JsonProperty(value = JSON_PROPERTY_ERRORS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setErrors(@jakarta.annotation.Nullable List errors) { + this.errors = errors; + } + + + public Problem instance(@jakarta.annotation.Nullable String instance) { + this.instance = instance; + return this; + } + + /** + * Get instance + * @return instance + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_INSTANCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getInstance() { + return instance; + } + + + @JsonProperty(value = JSON_PROPERTY_INSTANCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setInstance(@jakarta.annotation.Nullable String instance) { + this.instance = instance; + } + + + public Problem limit(@jakarta.annotation.Nullable String limit) { + this.limit = limit; + return this; + } + + /** + * For `quota-exceeded`, the name of the limit that was reached (for example `sites`). + * @return limit + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_LIMIT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getLimit() { + return limit; + } + + + @JsonProperty(value = JSON_PROPERTY_LIMIT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLimit(@jakarta.annotation.Nullable String limit) { + this.limit = limit; + } + + + public Problem plan(@jakarta.annotation.Nullable String plan) { + this.plan = plan; + return this; + } + + /** + * For `quota-exceeded`, the organization's plan as an opaque label. + * @return plan + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_PLAN, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getPlan() { + return plan; + } + + + @JsonProperty(value = JSON_PROPERTY_PLAN, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPlan(@jakarta.annotation.Nullable String plan) { + this.plan = plan; + } + + + public Problem status(@jakarta.annotation.Nonnull Integer status) { + this.status = status; + return this; + } + + /** + * Get status + * @return status + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getStatus() { + return status; + } + + + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setStatus(@jakarta.annotation.Nonnull Integer status) { + this.status = status; + } + + + public Problem title(@jakarta.annotation.Nonnull String title) { + this.title = title; + return this; + } + + /** + * Get title + * @return title + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TITLE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getTitle() { + return title; + } + + + @JsonProperty(value = JSON_PROPERTY_TITLE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTitle(@jakarta.annotation.Nonnull String title) { + this.title = title; + } + + + public Problem type(@jakarta.annotation.Nonnull String type) { + this.type = type; + return this; + } + + /** + * Identifies the problem type; one of `ProblemType`, as a URI reference such as `/problems/site-not-verified`. + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull String type) { + this.type = type; + } + + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. + * If the property does not already exist, create it otherwise replace it. + * @param key the name of the property + * @param value the value of the property + * @return self reference + */ + @JsonAnySetter + public Problem putAdditionalProperty(String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) properties. + * @return the additional (undeclared) properties + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * @param key the name of the property + * @return the additional (undeclared) property with the specified name + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + /** + * Return true if this Problem object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Problem problem = (Problem) o; + return Objects.equals(this.code, problem.code) && + Objects.equals(this.detail, problem.detail) && + Objects.equals(this.errors, problem.errors) && + Objects.equals(this.instance, problem.instance) && + Objects.equals(this.limit, problem.limit) && + Objects.equals(this.plan, problem.plan) && + Objects.equals(this.status, problem.status) && + Objects.equals(this.title, problem.title) && + Objects.equals(this.type, problem.type)&& + Objects.equals(this.additionalProperties, problem.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(code, detail, errors, instance, limit, plan, status, title, type, additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Problem {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" detail: ").append(toIndentedString(detail)).append("\n"); + sb.append(" errors: ").append(toIndentedString(errors)).append("\n"); + sb.append(" instance: ").append(toIndentedString(instance)).append("\n"); + sb.append(" limit: ").append(toIndentedString(limit)).append("\n"); + sb.append(" plan: ").append(toIndentedString(plan)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `code` to the URL query string + if (getCode() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%scode%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCode())))); + } + + // add `detail` to the URL query string + if (getDetail() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdetail%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDetail())))); + } + + // add `errors` to the URL query string + if (getErrors() != null) { + for (int i = 0; i < getErrors().size(); i++) { + if (getErrors().get(i) != null) { + joiner.add(getErrors().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%serrors%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `instance` to the URL query string + if (getInstance() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sinstance%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getInstance())))); + } + + // add `limit` to the URL query string + if (getLimit() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%slimit%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLimit())))); + } + + // add `plan` to the URL query string + if (getPlan() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%splan%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPlan())))); + } + + // add `status` to the URL query string + if (getStatus() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sstatus%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getStatus())))); + } + + // add `title` to the URL query string + if (getTitle() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stitle%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getTitle())))); + } + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ProblemErrorsInner.java b/src/main/java/com/sitewarm/sdk/model/ProblemErrorsInner.java new file mode 100644 index 0000000..ebb34a7 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ProblemErrorsInner.java @@ -0,0 +1,184 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ProblemErrorsInner + */ +@JsonPropertyOrder({ + ProblemErrorsInner.JSON_PROPERTY_DETAIL, + ProblemErrorsInner.JSON_PROPERTY_POINTER +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ProblemErrorsInner { + public static final String JSON_PROPERTY_DETAIL = "detail"; + @jakarta.annotation.Nonnull + private String detail; + + public static final String JSON_PROPERTY_POINTER = "pointer"; + @jakarta.annotation.Nonnull + private String pointer; + + public ProblemErrorsInner() { + } + + public ProblemErrorsInner detail(@jakarta.annotation.Nonnull String detail) { + this.detail = detail; + return this; + } + + /** + * Get detail + * @return detail + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DETAIL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getDetail() { + return detail; + } + + + @JsonProperty(value = JSON_PROPERTY_DETAIL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setDetail(@jakarta.annotation.Nonnull String detail) { + this.detail = detail; + } + + + public ProblemErrorsInner pointer(@jakarta.annotation.Nonnull String pointer) { + this.pointer = pointer; + return this; + } + + /** + * JSON Pointer to the offending member. + * @return pointer + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_POINTER, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getPointer() { + return pointer; + } + + + @JsonProperty(value = JSON_PROPERTY_POINTER, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPointer(@jakarta.annotation.Nonnull String pointer) { + this.pointer = pointer; + } + + + /** + * Return true if this Problem_errors_inner object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ProblemErrorsInner problemErrorsInner = (ProblemErrorsInner) o; + return Objects.equals(this.detail, problemErrorsInner.detail) && + Objects.equals(this.pointer, problemErrorsInner.pointer); + } + + @Override + public int hashCode() { + return Objects.hash(detail, pointer); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ProblemErrorsInner {\n"); + sb.append(" detail: ").append(toIndentedString(detail)).append("\n"); + sb.append(" pointer: ").append(toIndentedString(pointer)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `detail` to the URL query string + if (getDetail() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdetail%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDetail())))); + } + + // add `pointer` to the URL query string + if (getPointer() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%spointer%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPointer())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ProblemType.java b/src/main/java/com/sitewarm/sdk/model/ProblemType.java new file mode 100644 index 0000000..8464f90 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ProblemType.java @@ -0,0 +1,104 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Documented problem type slugs. Clients must tolerate new values. + */ +public enum ProblemType { + + INVALID_REQUEST("invalid-request"), + + VALIDATION_FAILED("validation-failed"), + + IDEMPOTENCY_KEY_MISSING("idempotency-key-missing"), + + IDEMPOTENCY_KEY_REUSED("idempotency-key-reused"), + + UNAUTHORIZED("unauthorized"), + + INSUFFICIENT_SCOPE("insufficient-scope"), + + SCOPE_NOT_ALLOWED("scope-not-allowed"), + + NOT_ENTITLED("not-entitled"), + + NOT_FOUND("not-found"), + + CONFLICT("conflict"), + + SITE_NOT_VERIFIED("site-not-verified"), + + SITE_PAUSED("site-paused"), + + QUOTA_EXCEEDED("quota-exceeded"), + + RATE_LIMITED("rate-limited"), + + INTERNAL_ERROR("internal-error"); + + private String value; + + ProblemType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ProblemType fromValue(String value) { + for (ProblemType b : ProblemType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ReportCell.java b/src/main/java/com/sitewarm/sdk/model/ReportCell.java new file mode 100644 index 0000000..4bfa56d --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ReportCell.java @@ -0,0 +1,309 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.UnknownReason; +import com.sitewarm.sdk.model.VantagePointRef; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Results of one route group at one vantage point. No percentage is given on purpose. + */ +@JsonPropertyOrder({ + ReportCell.JSON_PROPERTY_COUNTS, + ReportCell.JSON_PROPERTY_N, + ReportCell.JSON_PROPERTY_ROUTE_GROUP, + ReportCell.JSON_PROPERTY_UNKNOWN_REASON, + ReportCell.JSON_PROPERTY_VANTAGE_POINT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ReportCell { + public static final String JSON_PROPERTY_COUNTS = "counts"; + @jakarta.annotation.Nonnull + private Map counts = new HashMap<>(); + + public static final String JSON_PROPERTY_N = "n"; + @jakarta.annotation.Nonnull + private Integer n; + + public static final String JSON_PROPERTY_ROUTE_GROUP = "route_group"; + @jakarta.annotation.Nonnull + private String routeGroup; + + public static final String JSON_PROPERTY_UNKNOWN_REASON = "unknown_reason"; + @jakarta.annotation.Nullable + private UnknownReason unknownReason; + + public static final String JSON_PROPERTY_VANTAGE_POINT = "vantage_point"; + @jakarta.annotation.Nonnull + private VantagePointRef vantagePoint; + + public ReportCell() { + } + + public ReportCell counts(@jakarta.annotation.Nonnull Map counts) { + this.counts = counts; + return this; + } + + public ReportCell putCountsItem(String key, Integer countsItem) { + if (this.counts == null) { + this.counts = new HashMap<>(); + } + this.counts.put(key, countsItem); + return this; + } + + /** + * Number of results per cache state. States with no results may be omitted. + * @return counts + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_COUNTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Map getCounts() { + return counts; + } + + + @JsonProperty(value = JSON_PROPERTY_COUNTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCounts(@jakarta.annotation.Nonnull Map counts) { + this.counts = counts; + } + + + public ReportCell n(@jakarta.annotation.Nonnull Integer n) { + this.n = n; + return this; + } + + /** + * Number of results (URL by profile) in the cell. + * minimum: 0 + * @return n + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_N, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getN() { + return n; + } + + + @JsonProperty(value = JSON_PROPERTY_N, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setN(@jakarta.annotation.Nonnull Integer n) { + this.n = n; + } + + + public ReportCell routeGroup(@jakarta.annotation.Nonnull String routeGroup) { + this.routeGroup = routeGroup; + return this; + } + + /** + * Get routeGroup + * @return routeGroup + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ROUTE_GROUP, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getRouteGroup() { + return routeGroup; + } + + + @JsonProperty(value = JSON_PROPERTY_ROUTE_GROUP, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setRouteGroup(@jakarta.annotation.Nonnull String routeGroup) { + this.routeGroup = routeGroup; + } + + + public ReportCell unknownReason(@jakarta.annotation.Nullable UnknownReason unknownReason) { + this.unknownReason = unknownReason; + return this; + } + + /** + * Get unknownReason + * @return unknownReason + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_UNKNOWN_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public UnknownReason getUnknownReason() { + return unknownReason; + } + + + @JsonProperty(value = JSON_PROPERTY_UNKNOWN_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUnknownReason(@jakarta.annotation.Nullable UnknownReason unknownReason) { + this.unknownReason = unknownReason; + } + + + public ReportCell vantagePoint(@jakarta.annotation.Nonnull VantagePointRef vantagePoint) { + this.vantagePoint = vantagePoint; + return this; + } + + /** + * Get vantagePoint + * @return vantagePoint + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public VantagePointRef getVantagePoint() { + return vantagePoint; + } + + + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setVantagePoint(@jakarta.annotation.Nonnull VantagePointRef vantagePoint) { + this.vantagePoint = vantagePoint; + } + + + /** + * Return true if this ReportCell object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ReportCell reportCell = (ReportCell) o; + return Objects.equals(this.counts, reportCell.counts) && + Objects.equals(this.n, reportCell.n) && + Objects.equals(this.routeGroup, reportCell.routeGroup) && + Objects.equals(this.unknownReason, reportCell.unknownReason) && + Objects.equals(this.vantagePoint, reportCell.vantagePoint); + } + + @Override + public int hashCode() { + return Objects.hash(counts, n, routeGroup, unknownReason, vantagePoint); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ReportCell {\n"); + sb.append(" counts: ").append(toIndentedString(counts)).append("\n"); + sb.append(" n: ").append(toIndentedString(n)).append("\n"); + sb.append(" routeGroup: ").append(toIndentedString(routeGroup)).append("\n"); + sb.append(" unknownReason: ").append(toIndentedString(unknownReason)).append("\n"); + sb.append(" vantagePoint: ").append(toIndentedString(vantagePoint)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `counts` to the URL query string + if (getCounts() != null) { + for (String _key : getCounts().keySet()) { + joiner.add(String.format(java.util.Locale.ROOT, "%scounts%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, _key, containerSuffix), + getCounts().get(_key), ApiClient.urlEncode(ApiClient.valueToString(getCounts().get(_key))))); + } + } + + // add `n` to the URL query string + if (getN() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sn%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getN())))); + } + + // add `route_group` to the URL query string + if (getRouteGroup() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sroute_group%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getRouteGroup())))); + } + + // add `unknown_reason` to the URL query string + if (getUnknownReason() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sunknown_reason%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUnknownReason())))); + } + + // add `vantage_point` to the URL query string + if (getVantagePoint() != null) { + joiner.add(getVantagePoint().toUrlQueryString(prefix + "vantage_point" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Result.java b/src/main/java/com/sitewarm/sdk/model/Result.java new file mode 100644 index 0000000..aaf4c4e --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Result.java @@ -0,0 +1,866 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.CacheState; +import com.sitewarm.sdk.model.Indexability; +import com.sitewarm.sdk.model.UnknownReason; +import com.sitewarm.sdk.model.VantagePointRef; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * What the engine observed for one URL and one profile at one vantage point. Fields marked nullable depend on engine releases that may not be out yet. + */ +@JsonPropertyOrder({ + Result.JSON_PROPERTY_AGE_SECONDS, + Result.JSON_PROPERTY_CACHE_CONTROL, + Result.JSON_PROPERTY_CAUSE, + Result.JSON_PROPERTY_CDN, + Result.JSON_PROPERTY_CDN_CACHE_HEADER, + Result.JSON_PROPERTY_ERROR, + Result.JSON_PROPERTY_FINAL_STATE, + Result.JSON_PROPERTY_FIX, + Result.JSON_PROPERTY_HTTP_STATUS, + Result.JSON_PROPERTY_INDEXABILITY, + Result.JSON_PROPERTY_INITIAL_STATE, + Result.JSON_PROPERTY_POP, + Result.JSON_PROPERTY_PROFILE, + Result.JSON_PROPERTY_ROUTE_GROUP, + Result.JSON_PROPERTY_TIME_TO_HIT_MS, + Result.JSON_PROPERTY_TTFB_MS, + Result.JSON_PROPERTY_UNKNOWN_REASON, + Result.JSON_PROPERTY_URL, + Result.JSON_PROPERTY_VANTAGE_POINT, + Result.JSON_PROPERTY_VARY +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Result { + public static final String JSON_PROPERTY_AGE_SECONDS = "age_seconds"; + @jakarta.annotation.Nullable + private Integer ageSeconds; + + public static final String JSON_PROPERTY_CACHE_CONTROL = "cache_control"; + @jakarta.annotation.Nullable + private String cacheControl; + + public static final String JSON_PROPERTY_CAUSE = "cause"; + @jakarta.annotation.Nullable + private List cause = new ArrayList<>(); + + public static final String JSON_PROPERTY_CDN = "cdn"; + @jakarta.annotation.Nullable + private String cdn; + + public static final String JSON_PROPERTY_CDN_CACHE_HEADER = "cdn_cache_header"; + @jakarta.annotation.Nullable + private String cdnCacheHeader; + + public static final String JSON_PROPERTY_ERROR = "error"; + @jakarta.annotation.Nullable + private String error; + + public static final String JSON_PROPERTY_FINAL_STATE = "final_state"; + @jakarta.annotation.Nonnull + private CacheState finalState; + + public static final String JSON_PROPERTY_FIX = "fix"; + @jakarta.annotation.Nullable + private List fix = new ArrayList<>(); + + public static final String JSON_PROPERTY_HTTP_STATUS = "http_status"; + @jakarta.annotation.Nullable + private Integer httpStatus; + + public static final String JSON_PROPERTY_INDEXABILITY = "indexability"; + @jakarta.annotation.Nullable + private Indexability indexability; + + public static final String JSON_PROPERTY_INITIAL_STATE = "initial_state"; + @jakarta.annotation.Nullable + private CacheState initialState; + + public static final String JSON_PROPERTY_POP = "pop"; + @jakarta.annotation.Nullable + private String pop; + + public static final String JSON_PROPERTY_PROFILE = "profile"; + @jakarta.annotation.Nullable + private String profile; + + public static final String JSON_PROPERTY_ROUTE_GROUP = "route_group"; + @jakarta.annotation.Nullable + private String routeGroup; + + public static final String JSON_PROPERTY_TIME_TO_HIT_MS = "time_to_hit_ms"; + @jakarta.annotation.Nullable + private Integer timeToHitMs; + + public static final String JSON_PROPERTY_TTFB_MS = "ttfb_ms"; + @jakarta.annotation.Nullable + private Integer ttfbMs; + + public static final String JSON_PROPERTY_UNKNOWN_REASON = "unknown_reason"; + @jakarta.annotation.Nullable + private UnknownReason unknownReason; + + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private URI url; + + public static final String JSON_PROPERTY_VANTAGE_POINT = "vantage_point"; + @jakarta.annotation.Nullable + private VantagePointRef vantagePoint; + + public static final String JSON_PROPERTY_VARY = "vary"; + @jakarta.annotation.Nullable + private String vary; + + public Result() { + } + + public Result ageSeconds(@jakarta.annotation.Nullable Integer ageSeconds) { + this.ageSeconds = ageSeconds; + return this; + } + + /** + * Get ageSeconds + * minimum: 0 + * @return ageSeconds + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_AGE_SECONDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getAgeSeconds() { + return ageSeconds; + } + + + @JsonProperty(value = JSON_PROPERTY_AGE_SECONDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAgeSeconds(@jakarta.annotation.Nullable Integer ageSeconds) { + this.ageSeconds = ageSeconds; + } + + + public Result cacheControl(@jakarta.annotation.Nullable String cacheControl) { + this.cacheControl = cacheControl; + return this; + } + + /** + * Get cacheControl + * @return cacheControl + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CACHE_CONTROL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getCacheControl() { + return cacheControl; + } + + + @JsonProperty(value = JSON_PROPERTY_CACHE_CONTROL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCacheControl(@jakarta.annotation.Nullable String cacheControl) { + this.cacheControl = cacheControl; + } + + + public Result cause(@jakarta.annotation.Nullable List cause) { + this.cause = cause; + return this; + } + + public Result addCauseItem(String causeItem) { + if (this.cause == null) { + this.cause = new ArrayList<>(); + } + this.cause.add(causeItem); + return this; + } + + /** + * Engine-provided causes for a non-`hit` state, citing observed headers. `Set-Cookie` values are redacted. + * @return cause + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CAUSE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getCause() { + return cause; + } + + + @JsonProperty(value = JSON_PROPERTY_CAUSE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCause(@jakarta.annotation.Nullable List cause) { + this.cause = cause; + } + + + public Result cdn(@jakarta.annotation.Nullable String cdn) { + this.cdn = cdn; + return this; + } + + /** + * Detected CDN, for example `cloudflare`. + * @return cdn + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CDN, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getCdn() { + return cdn; + } + + + @JsonProperty(value = JSON_PROPERTY_CDN, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCdn(@jakarta.annotation.Nullable String cdn) { + this.cdn = cdn; + } + + + public Result cdnCacheHeader(@jakarta.annotation.Nullable String cdnCacheHeader) { + this.cdnCacheHeader = cdnCacheHeader; + return this; + } + + /** + * Raw cache status header value as observed (for example `EXPIRED`), never normalized. + * @return cdnCacheHeader + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CDN_CACHE_HEADER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getCdnCacheHeader() { + return cdnCacheHeader; + } + + + @JsonProperty(value = JSON_PROPERTY_CDN_CACHE_HEADER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCdnCacheHeader(@jakarta.annotation.Nullable String cdnCacheHeader) { + this.cdnCacheHeader = cdnCacheHeader; + } + + + public Result error(@jakarta.annotation.Nullable String error) { + this.error = error; + return this; + } + + /** + * Get error + * @return error + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ERROR, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getError() { + return error; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setError(@jakarta.annotation.Nullable String error) { + this.error = error; + } + + + public Result finalState(@jakarta.annotation.Nonnull CacheState finalState) { + this.finalState = finalState; + return this; + } + + /** + * Get finalState + * @return finalState + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_FINAL_STATE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public CacheState getFinalState() { + return finalState; + } + + + @JsonProperty(value = JSON_PROPERTY_FINAL_STATE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFinalState(@jakarta.annotation.Nonnull CacheState finalState) { + this.finalState = finalState; + } + + + public Result fix(@jakarta.annotation.Nullable List fix) { + this.fix = fix; + return this; + } + + public Result addFixItem(String fixItem) { + if (this.fix == null) { + this.fix = new ArrayList<>(); + } + this.fix.add(fixItem); + return this; + } + + /** + * Engine-provided suggested fixes. + * @return fix + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_FIX, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getFix() { + return fix; + } + + + @JsonProperty(value = JSON_PROPERTY_FIX, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFix(@jakarta.annotation.Nullable List fix) { + this.fix = fix; + } + + + public Result httpStatus(@jakarta.annotation.Nullable Integer httpStatus) { + this.httpStatus = httpStatus; + return this; + } + + /** + * Get httpStatus + * @return httpStatus + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_HTTP_STATUS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getHttpStatus() { + return httpStatus; + } + + + @JsonProperty(value = JSON_PROPERTY_HTTP_STATUS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setHttpStatus(@jakarta.annotation.Nullable Integer httpStatus) { + this.httpStatus = httpStatus; + } + + + public Result indexability(@jakarta.annotation.Nullable Indexability indexability) { + this.indexability = indexability; + return this; + } + + /** + * Get indexability + * @return indexability + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_INDEXABILITY, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Indexability getIndexability() { + return indexability; + } + + + @JsonProperty(value = JSON_PROPERTY_INDEXABILITY, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setIndexability(@jakarta.annotation.Nullable Indexability indexability) { + this.indexability = indexability; + } + + + public Result initialState(@jakarta.annotation.Nullable CacheState initialState) { + this.initialState = initialState; + return this; + } + + /** + * Omitted when the engine has not reported the first observation separately. + * @return initialState + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_INITIAL_STATE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public CacheState getInitialState() { + return initialState; + } + + + @JsonProperty(value = JSON_PROPERTY_INITIAL_STATE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setInitialState(@jakarta.annotation.Nullable CacheState initialState) { + this.initialState = initialState; + } + + + public Result pop(@jakarta.annotation.Nullable String pop) { + this.pop = pop; + return this; + } + + /** + * Point of presence when the CDN exposes it. + * @return pop + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_POP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getPop() { + return pop; + } + + + @JsonProperty(value = JSON_PROPERTY_POP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPop(@jakarta.annotation.Nullable String pop) { + this.pop = pop; + } + + + public Result profile(@jakarta.annotation.Nullable String profile) { + this.profile = profile; + return this; + } + + /** + * Request profile name, for example `desktop` or `mobile`. + * @return profile + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_PROFILE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getProfile() { + return profile; + } + + + @JsonProperty(value = JSON_PROPERTY_PROFILE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setProfile(@jakarta.annotation.Nullable String profile) { + this.profile = profile; + } + + + public Result routeGroup(@jakarta.annotation.Nullable String routeGroup) { + this.routeGroup = routeGroup; + return this; + } + + /** + * Route template the URL belongs to (for example `/blog/_*`). + * @return routeGroup + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ROUTE_GROUP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getRouteGroup() { + return routeGroup; + } + + + @JsonProperty(value = JSON_PROPERTY_ROUTE_GROUP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRouteGroup(@jakarta.annotation.Nullable String routeGroup) { + this.routeGroup = routeGroup; + } + + + public Result timeToHitMs(@jakarta.annotation.Nullable Integer timeToHitMs) { + this.timeToHitMs = timeToHitMs; + return this; + } + + /** + * Get timeToHitMs + * minimum: 0 + * @return timeToHitMs + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TIME_TO_HIT_MS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getTimeToHitMs() { + return timeToHitMs; + } + + + @JsonProperty(value = JSON_PROPERTY_TIME_TO_HIT_MS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTimeToHitMs(@jakarta.annotation.Nullable Integer timeToHitMs) { + this.timeToHitMs = timeToHitMs; + } + + + public Result ttfbMs(@jakarta.annotation.Nullable Integer ttfbMs) { + this.ttfbMs = ttfbMs; + return this; + } + + /** + * Get ttfbMs + * minimum: 0 + * @return ttfbMs + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TTFB_MS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getTtfbMs() { + return ttfbMs; + } + + + @JsonProperty(value = JSON_PROPERTY_TTFB_MS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTtfbMs(@jakarta.annotation.Nullable Integer ttfbMs) { + this.ttfbMs = ttfbMs; + } + + + public Result unknownReason(@jakarta.annotation.Nullable UnknownReason unknownReason) { + this.unknownReason = unknownReason; + return this; + } + + /** + * Get unknownReason + * @return unknownReason + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_UNKNOWN_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public UnknownReason getUnknownReason() { + return unknownReason; + } + + + @JsonProperty(value = JSON_PROPERTY_UNKNOWN_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUnknownReason(@jakarta.annotation.Nullable UnknownReason unknownReason) { + this.unknownReason = unknownReason; + } + + + public Result url(@jakarta.annotation.Nonnull URI url) { + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public URI getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull URI url) { + this.url = url; + } + + + public Result vantagePoint(@jakarta.annotation.Nullable VantagePointRef vantagePoint) { + this.vantagePoint = vantagePoint; + return this; + } + + /** + * Get vantagePoint + * @return vantagePoint + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public VantagePointRef getVantagePoint() { + return vantagePoint; + } + + + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setVantagePoint(@jakarta.annotation.Nullable VantagePointRef vantagePoint) { + this.vantagePoint = vantagePoint; + } + + + public Result vary(@jakarta.annotation.Nullable String vary) { + this.vary = vary; + return this; + } + + /** + * Get vary + * @return vary + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_VARY, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getVary() { + return vary; + } + + + @JsonProperty(value = JSON_PROPERTY_VARY, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setVary(@jakarta.annotation.Nullable String vary) { + this.vary = vary; + } + + + /** + * Return true if this Result object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Result result = (Result) o; + return Objects.equals(this.ageSeconds, result.ageSeconds) && + Objects.equals(this.cacheControl, result.cacheControl) && + Objects.equals(this.cause, result.cause) && + Objects.equals(this.cdn, result.cdn) && + Objects.equals(this.cdnCacheHeader, result.cdnCacheHeader) && + Objects.equals(this.error, result.error) && + Objects.equals(this.finalState, result.finalState) && + Objects.equals(this.fix, result.fix) && + Objects.equals(this.httpStatus, result.httpStatus) && + Objects.equals(this.indexability, result.indexability) && + Objects.equals(this.initialState, result.initialState) && + Objects.equals(this.pop, result.pop) && + Objects.equals(this.profile, result.profile) && + Objects.equals(this.routeGroup, result.routeGroup) && + Objects.equals(this.timeToHitMs, result.timeToHitMs) && + Objects.equals(this.ttfbMs, result.ttfbMs) && + Objects.equals(this.unknownReason, result.unknownReason) && + Objects.equals(this.url, result.url) && + Objects.equals(this.vantagePoint, result.vantagePoint) && + Objects.equals(this.vary, result.vary); + } + + @Override + public int hashCode() { + return Objects.hash(ageSeconds, cacheControl, cause, cdn, cdnCacheHeader, error, finalState, fix, httpStatus, indexability, initialState, pop, profile, routeGroup, timeToHitMs, ttfbMs, unknownReason, url, vantagePoint, vary); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Result {\n"); + sb.append(" ageSeconds: ").append(toIndentedString(ageSeconds)).append("\n"); + sb.append(" cacheControl: ").append(toIndentedString(cacheControl)).append("\n"); + sb.append(" cause: ").append(toIndentedString(cause)).append("\n"); + sb.append(" cdn: ").append(toIndentedString(cdn)).append("\n"); + sb.append(" cdnCacheHeader: ").append(toIndentedString(cdnCacheHeader)).append("\n"); + sb.append(" error: ").append(toIndentedString(error)).append("\n"); + sb.append(" finalState: ").append(toIndentedString(finalState)).append("\n"); + sb.append(" fix: ").append(toIndentedString(fix)).append("\n"); + sb.append(" httpStatus: ").append(toIndentedString(httpStatus)).append("\n"); + sb.append(" indexability: ").append(toIndentedString(indexability)).append("\n"); + sb.append(" initialState: ").append(toIndentedString(initialState)).append("\n"); + sb.append(" pop: ").append(toIndentedString(pop)).append("\n"); + sb.append(" profile: ").append(toIndentedString(profile)).append("\n"); + sb.append(" routeGroup: ").append(toIndentedString(routeGroup)).append("\n"); + sb.append(" timeToHitMs: ").append(toIndentedString(timeToHitMs)).append("\n"); + sb.append(" ttfbMs: ").append(toIndentedString(ttfbMs)).append("\n"); + sb.append(" unknownReason: ").append(toIndentedString(unknownReason)).append("\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append(" vantagePoint: ").append(toIndentedString(vantagePoint)).append("\n"); + sb.append(" vary: ").append(toIndentedString(vary)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `age_seconds` to the URL query string + if (getAgeSeconds() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sage_seconds%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getAgeSeconds())))); + } + + // add `cache_control` to the URL query string + if (getCacheControl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%scache_control%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCacheControl())))); + } + + // add `cause` to the URL query string + if (getCause() != null) { + for (int i = 0; i < getCause().size(); i++) { + joiner.add(String.format(java.util.Locale.ROOT, "%scause%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getCause().get(i))))); + } + } + + // add `cdn` to the URL query string + if (getCdn() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%scdn%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCdn())))); + } + + // add `cdn_cache_header` to the URL query string + if (getCdnCacheHeader() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%scdn_cache_header%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCdnCacheHeader())))); + } + + // add `error` to the URL query string + if (getError() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serror%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getError())))); + } + + // add `final_state` to the URL query string + if (getFinalState() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfinal_state%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getFinalState())))); + } + + // add `fix` to the URL query string + if (getFix() != null) { + for (int i = 0; i < getFix().size(); i++) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfix%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getFix().get(i))))); + } + } + + // add `http_status` to the URL query string + if (getHttpStatus() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%shttp_status%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getHttpStatus())))); + } + + // add `indexability` to the URL query string + if (getIndexability() != null) { + joiner.add(getIndexability().toUrlQueryString(prefix + "indexability" + suffix)); + } + + // add `initial_state` to the URL query string + if (getInitialState() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sinitial_state%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getInitialState())))); + } + + // add `pop` to the URL query string + if (getPop() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%spop%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPop())))); + } + + // add `profile` to the URL query string + if (getProfile() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sprofile%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getProfile())))); + } + + // add `route_group` to the URL query string + if (getRouteGroup() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sroute_group%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getRouteGroup())))); + } + + // add `time_to_hit_ms` to the URL query string + if (getTimeToHitMs() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stime_to_hit_ms%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getTimeToHitMs())))); + } + + // add `ttfb_ms` to the URL query string + if (getTtfbMs() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sttfb_ms%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getTtfbMs())))); + } + + // add `unknown_reason` to the URL query string + if (getUnknownReason() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sunknown_reason%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUnknownReason())))); + } + + // add `url` to the URL query string + if (getUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrl())))); + } + + // add `vantage_point` to the URL query string + if (getVantagePoint() != null) { + joiner.add(getVantagePoint().toUrlQueryString(prefix + "vantage_point" + suffix)); + } + + // add `vary` to the URL query string + if (getVary() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%svary%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getVary())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ResultList.java b/src/main/java/com/sitewarm/sdk/model/ResultList.java new file mode 100644 index 0000000..95ee2b4 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ResultList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.PageInfo; +import com.sitewarm.sdk.model.Result; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ResultList + */ +@JsonPropertyOrder({ + ResultList.JSON_PROPERTY_DATA, + ResultList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ResultList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public ResultList() { + } + + public ResultList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public ResultList addDataItem(Result dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public ResultList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this ResultList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ResultList resultList = (ResultList) o; + return Objects.equals(this.data, resultList.data) && + Objects.equals(this.page, resultList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ResultList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/RunOptions.java b/src/main/java/com/sitewarm/sdk/model/RunOptions.java new file mode 100644 index 0000000..a131f6b --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/RunOptions.java @@ -0,0 +1,509 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.sitewarm.sdk.model.FailOnToken; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Engine options for a run. Every field is optional; an omitted field takes the engine or organization default, which this document does not define. + */ +@JsonPropertyOrder({ + RunOptions.JSON_PROPERTY_EXPECT_REVISION_HEADER, + RunOptions.JSON_PROPERTY_EXPECT_TEXT, + RunOptions.JSON_PROPERTY_FAIL_ON, + RunOptions.JSON_PROPERTY_MAX_WAIT, + RunOptions.JSON_PROPERTY_RUN_TIMEOUT, + RunOptions.JSON_PROPERTY_SETTLE, + RunOptions.JSON_PROPERTY_TOP, + RunOptions.JSON_PROPERTY_VANTAGE_POINT_IDS, + RunOptions.JSON_PROPERTY_WAIT_FOR_HEADER, + RunOptions.JSON_PROPERTY_WAIT_FOR_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class RunOptions { + public static final String JSON_PROPERTY_EXPECT_REVISION_HEADER = "expect_revision_header"; + @jakarta.annotation.Nullable + private String expectRevisionHeader; + + public static final String JSON_PROPERTY_EXPECT_TEXT = "expect_text"; + @jakarta.annotation.Nullable + private String expectText; + + public static final String JSON_PROPERTY_FAIL_ON = "fail_on"; + @jakarta.annotation.Nullable + private Set failOn = new LinkedHashSet<>(); + + public static final String JSON_PROPERTY_MAX_WAIT = "max_wait"; + @jakarta.annotation.Nullable + private String maxWait; + + public static final String JSON_PROPERTY_RUN_TIMEOUT = "run_timeout"; + @jakarta.annotation.Nullable + private String runTimeout; + + public static final String JSON_PROPERTY_SETTLE = "settle"; + @jakarta.annotation.Nullable + private String settle; + + public static final String JSON_PROPERTY_TOP = "top"; + @jakarta.annotation.Nullable + private Integer top; + + public static final String JSON_PROPERTY_VANTAGE_POINT_IDS = "vantage_point_ids"; + @jakarta.annotation.Nullable + private List vantagePointIds = new ArrayList<>(); + + public static final String JSON_PROPERTY_WAIT_FOR_HEADER = "wait_for_header"; + @jakarta.annotation.Nullable + private String waitForHeader; + + public static final String JSON_PROPERTY_WAIT_FOR_URL = "wait_for_url"; + @jakarta.annotation.Nullable + private URI waitForUrl; + + public RunOptions() { + } + + public RunOptions expectRevisionHeader(@jakarta.annotation.Nullable String expectRevisionHeader) { + this.expectRevisionHeader = expectRevisionHeader; + return this; + } + + /** + * `NAME=VALUE`. Each verified response must carry this revision, otherwise `stale-revision`. + * @return expectRevisionHeader + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_EXPECT_REVISION_HEADER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getExpectRevisionHeader() { + return expectRevisionHeader; + } + + + @JsonProperty(value = JSON_PROPERTY_EXPECT_REVISION_HEADER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExpectRevisionHeader(@jakarta.annotation.Nullable String expectRevisionHeader) { + this.expectRevisionHeader = expectRevisionHeader; + } + + + public RunOptions expectText(@jakarta.annotation.Nullable String expectText) { + this.expectText = expectText; + return this; + } + + /** + * Get expectText + * @return expectText + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_EXPECT_TEXT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getExpectText() { + return expectText; + } + + + @JsonProperty(value = JSON_PROPERTY_EXPECT_TEXT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExpectText(@jakarta.annotation.Nullable String expectText) { + this.expectText = expectText; + } + + + public RunOptions failOn(@jakarta.annotation.Nullable Set failOn) { + this.failOn = failOn; + return this; + } + + public RunOptions addFailOnItem(FailOnToken failOnItem) { + if (this.failOn == null) { + this.failOn = new LinkedHashSet<>(); + } + this.failOn.add(failOnItem); + return this; + } + + /** + * Cache states and indexability tokens that make the run fail. Omitted means the engine default. An empty array means nothing fails the run (the \"no verification\" rule still applies). + * @return failOn + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_FAIL_ON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Set getFailOn() { + return failOn; + } + + + @JsonDeserialize(as = LinkedHashSet.class) + @JsonProperty(value = JSON_PROPERTY_FAIL_ON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFailOn(@jakarta.annotation.Nullable Set failOn) { + this.failOn = failOn; + } + + + public RunOptions maxWait(@jakarta.annotation.Nullable String maxWait) { + this.maxWait = maxWait; + return this; + } + + /** + * How long to retry a URL until it is a `hit`, such as `5m`. + * @return maxWait + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_MAX_WAIT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getMaxWait() { + return maxWait; + } + + + @JsonProperty(value = JSON_PROPERTY_MAX_WAIT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMaxWait(@jakarta.annotation.Nullable String maxWait) { + this.maxWait = maxWait; + } + + + public RunOptions runTimeout(@jakarta.annotation.Nullable String runTimeout) { + this.runTimeout = runTimeout; + return this; + } + + /** + * Cap for the whole run, such as `15m`. URLs left over become `incomplete`. + * @return runTimeout + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_RUN_TIMEOUT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getRunTimeout() { + return runTimeout; + } + + + @JsonProperty(value = JSON_PROPERTY_RUN_TIMEOUT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRunTimeout(@jakarta.annotation.Nullable String runTimeout) { + this.runTimeout = runTimeout; + } + + + public RunOptions settle(@jakarta.annotation.Nullable String settle) { + this.settle = settle; + return this; + } + + /** + * Fixed delay before warming, such as `30s`. + * @return settle + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SETTLE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getSettle() { + return settle; + } + + + @JsonProperty(value = JSON_PROPERTY_SETTLE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSettle(@jakarta.annotation.Nullable String settle) { + this.settle = settle; + } + + + public RunOptions top(@jakarta.annotation.Nullable Integer top) { + this.top = top; + return this; + } + + /** + * Use only the first N URLs of the source, in its order. + * minimum: 1 + * @return top + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TOP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Integer getTop() { + return top; + } + + + @JsonProperty(value = JSON_PROPERTY_TOP, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTop(@jakarta.annotation.Nullable Integer top) { + this.top = top; + } + + + public RunOptions vantagePointIds(@jakarta.annotation.Nullable List vantagePointIds) { + this.vantagePointIds = vantagePointIds; + return this; + } + + public RunOptions addVantagePointIdsItem(String vantagePointIdsItem) { + if (this.vantagePointIds == null) { + this.vantagePointIds = new ArrayList<>(); + } + this.vantagePointIds.add(vantagePointIdsItem); + return this; + } + + /** + * Restrict the run to these vantage points. Omitted means all the organization may use. + * @return vantagePointIds + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getVantagePointIds() { + return vantagePointIds; + } + + + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT_IDS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setVantagePointIds(@jakarta.annotation.Nullable List vantagePointIds) { + this.vantagePointIds = vantagePointIds; + } + + + public RunOptions waitForHeader(@jakarta.annotation.Nullable String waitForHeader) { + this.waitForHeader = waitForHeader; + return this; + } + + /** + * `NAME=VALUE`. Wait until the site serves this header before warming. + * @return waitForHeader + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_WAIT_FOR_HEADER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getWaitForHeader() { + return waitForHeader; + } + + + @JsonProperty(value = JSON_PROPERTY_WAIT_FOR_HEADER, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setWaitForHeader(@jakarta.annotation.Nullable String waitForHeader) { + this.waitForHeader = waitForHeader; + } + + + public RunOptions waitForUrl(@jakarta.annotation.Nullable URI waitForUrl) { + this.waitForUrl = waitForUrl; + return this; + } + + /** + * Wait until this URL is live (use with `expect_text`) before warming. + * @return waitForUrl + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_WAIT_FOR_URL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public URI getWaitForUrl() { + return waitForUrl; + } + + + @JsonProperty(value = JSON_PROPERTY_WAIT_FOR_URL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setWaitForUrl(@jakarta.annotation.Nullable URI waitForUrl) { + this.waitForUrl = waitForUrl; + } + + + /** + * Return true if this RunOptions object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RunOptions runOptions = (RunOptions) o; + return Objects.equals(this.expectRevisionHeader, runOptions.expectRevisionHeader) && + Objects.equals(this.expectText, runOptions.expectText) && + Objects.equals(this.failOn, runOptions.failOn) && + Objects.equals(this.maxWait, runOptions.maxWait) && + Objects.equals(this.runTimeout, runOptions.runTimeout) && + Objects.equals(this.settle, runOptions.settle) && + Objects.equals(this.top, runOptions.top) && + Objects.equals(this.vantagePointIds, runOptions.vantagePointIds) && + Objects.equals(this.waitForHeader, runOptions.waitForHeader) && + Objects.equals(this.waitForUrl, runOptions.waitForUrl); + } + + @Override + public int hashCode() { + return Objects.hash(expectRevisionHeader, expectText, failOn, maxWait, runTimeout, settle, top, vantagePointIds, waitForHeader, waitForUrl); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class RunOptions {\n"); + sb.append(" expectRevisionHeader: ").append(toIndentedString(expectRevisionHeader)).append("\n"); + sb.append(" expectText: ").append(toIndentedString(expectText)).append("\n"); + sb.append(" failOn: ").append(toIndentedString(failOn)).append("\n"); + sb.append(" maxWait: ").append(toIndentedString(maxWait)).append("\n"); + sb.append(" runTimeout: ").append(toIndentedString(runTimeout)).append("\n"); + sb.append(" settle: ").append(toIndentedString(settle)).append("\n"); + sb.append(" top: ").append(toIndentedString(top)).append("\n"); + sb.append(" vantagePointIds: ").append(toIndentedString(vantagePointIds)).append("\n"); + sb.append(" waitForHeader: ").append(toIndentedString(waitForHeader)).append("\n"); + sb.append(" waitForUrl: ").append(toIndentedString(waitForUrl)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `expect_revision_header` to the URL query string + if (getExpectRevisionHeader() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sexpect_revision_header%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getExpectRevisionHeader())))); + } + + // add `expect_text` to the URL query string + if (getExpectText() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sexpect_text%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getExpectText())))); + } + + // add `fail_on` to the URL query string + if (getFailOn() != null) { + int i = 0; + for (FailOnToken _item : getFailOn()) { + if (_item != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfail_on%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(_item)))); + } + i++; + } + } + + // add `max_wait` to the URL query string + if (getMaxWait() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%smax_wait%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getMaxWait())))); + } + + // add `run_timeout` to the URL query string + if (getRunTimeout() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%srun_timeout%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getRunTimeout())))); + } + + // add `settle` to the URL query string + if (getSettle() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssettle%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSettle())))); + } + + // add `top` to the URL query string + if (getTop() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stop%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getTop())))); + } + + // add `vantage_point_ids` to the URL query string + if (getVantagePointIds() != null) { + for (int i = 0; i < getVantagePointIds().size(); i++) { + joiner.add(String.format(java.util.Locale.ROOT, "%svantage_point_ids%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getVantagePointIds().get(i))))); + } + } + + // add `wait_for_header` to the URL query string + if (getWaitForHeader() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%swait_for_header%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getWaitForHeader())))); + } + + // add `wait_for_url` to the URL query string + if (getWaitForUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%swait_for_url%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getWaitForUrl())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/RunSource.java b/src/main/java/com/sitewarm/sdk/model/RunSource.java new file mode 100644 index 0000000..db0b67e --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/RunSource.java @@ -0,0 +1,306 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.RunSourceSitemap; +import com.sitewarm.sdk.model.RunSourceUrlSet; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import com.fasterxml.jackson.core.type.TypeReference; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.sitewarm.sdk.ApiClient; +import com.sitewarm.sdk.JSON; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +@JsonDeserialize(using = RunSource.RunSourceDeserializer.class) +@JsonSerialize(using = RunSource.RunSourceSerializer.class) +public class RunSource extends AbstractOpenApiSchema { + private static final Logger log = Logger.getLogger(RunSource.class.getName()); + + public static class RunSourceSerializer extends StdSerializer { + public RunSourceSerializer(Class t) { + super(t); + } + + public RunSourceSerializer() { + this(null); + } + + @Override + public void serialize(RunSource value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static class RunSourceDeserializer extends StdDeserializer { + public RunSourceDeserializer() { + this(RunSource.class); + } + + public RunSourceDeserializer(Class vc) { + super(vc); + } + + @Override + public RunSource deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode tree = ctxt.readTree(jp); + Object deserialized = null; + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize RunSourceSitemap + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (RunSourceSitemap.class.equals(Integer.class) || RunSourceSitemap.class.equals(Long.class) || RunSourceSitemap.class.equals(Float.class) || RunSourceSitemap.class.equals(Double.class) || RunSourceSitemap.class.equals(Boolean.class) || RunSourceSitemap.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((RunSourceSitemap.class.equals(Integer.class) || RunSourceSitemap.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((RunSourceSitemap.class.equals(Float.class) || RunSourceSitemap.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (RunSourceSitemap.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (RunSourceSitemap.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(RunSourceSitemap.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'RunSourceSitemap'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'RunSourceSitemap'", e); + } + + // deserialize RunSourceUrlSet + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (RunSourceUrlSet.class.equals(Integer.class) || RunSourceUrlSet.class.equals(Long.class) || RunSourceUrlSet.class.equals(Float.class) || RunSourceUrlSet.class.equals(Double.class) || RunSourceUrlSet.class.equals(Boolean.class) || RunSourceUrlSet.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((RunSourceUrlSet.class.equals(Integer.class) || RunSourceUrlSet.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((RunSourceUrlSet.class.equals(Float.class) || RunSourceUrlSet.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (RunSourceUrlSet.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (RunSourceUrlSet.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(RunSourceUrlSet.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'RunSourceUrlSet'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'RunSourceUrlSet'", e); + } + + if (match == 1) { + RunSource ret = new RunSource(); + ret.setActualInstance(deserialized); + return ret; + } + throw new IOException(String.format(java.util.Locale.ROOT, "Failed deserialization for RunSource: %d classes match result, expected 1", match)); + } + + /** + * Handle deserialization of the 'null' value. + */ + @Override + public RunSource getNullValue(DeserializationContext ctxt) throws JsonMappingException { + throw new JsonMappingException(ctxt.getParser(), "RunSource cannot be null"); + } + } + + // store a list of schema names defined in oneOf + public static final Map> schemas = new HashMap<>(); + + public RunSource() { + super("oneOf", Boolean.FALSE); + } + + public RunSource(RunSourceSitemap o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public RunSource(RunSourceUrlSet o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + static { + schemas.put("RunSourceSitemap", RunSourceSitemap.class); + schemas.put("RunSourceUrlSet", RunSourceUrlSet.class); + JSON.registerDescendants(RunSource.class, Collections.unmodifiableMap(schemas)); + // Initialize and register the discriminator mappings. + Map> mappings = new HashMap>(); + mappings.put("sitemap", RunSourceSitemap.class); + mappings.put("url_set", RunSourceUrlSet.class); + mappings.put("RunSource", RunSource.class); + JSON.registerDiscriminator(RunSource.class, "type", mappings); + } + + @Override + public Map> getSchemas() { + return RunSource.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check + * the instance parameter is valid against the oneOf child schemas: + * RunSourceSitemap, RunSourceUrlSet + * + * It could be an instance of the 'oneOf' schemas. + * The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (JSON.isInstanceOf(RunSourceSitemap.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(RunSourceUrlSet.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException("Invalid instance type. Must be RunSourceSitemap, RunSourceUrlSet"); + } + + /** + * Get the actual instance, which can be the following: + * RunSourceSitemap, RunSourceUrlSet + * + * @return The actual instance (RunSourceSitemap, RunSourceUrlSet) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `RunSourceSitemap`. If the actual instance is not `RunSourceSitemap`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `RunSourceSitemap` + * @throws ClassCastException if the instance is not `RunSourceSitemap` + */ + public RunSourceSitemap getRunSourceSitemap() throws ClassCastException { + return (RunSourceSitemap)super.getActualInstance(); + } + + /** + * Get the actual instance of `RunSourceUrlSet`. If the actual instance is not `RunSourceUrlSet`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `RunSourceUrlSet` + * @throws ClassCastException if the instance is not `RunSourceUrlSet` + */ + public RunSourceUrlSet getRunSourceUrlSet() throws ClassCastException { + return (RunSourceUrlSet)super.getActualInstance(); + } + + + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + if (getActualInstance() instanceof RunSourceSitemap) { + if (getActualInstance() != null) { + joiner.add(((RunSourceSitemap)getActualInstance()).toUrlQueryString(prefix + "one_of_0" + suffix)); + } + return joiner.toString(); + } + if (getActualInstance() instanceof RunSourceUrlSet) { + if (getActualInstance() != null) { + joiner.add(((RunSourceUrlSet)getActualInstance()).toUrlQueryString(prefix + "one_of_1" + suffix)); + } + return joiner.toString(); + } + return null; + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/RunSourceSitemap.java b/src/main/java/com/sitewarm/sdk/model/RunSourceSitemap.java new file mode 100644 index 0000000..7c77d4f --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/RunSourceSitemap.java @@ -0,0 +1,184 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * RunSourceSitemap + */ +@JsonPropertyOrder({ + RunSourceSitemap.JSON_PROPERTY_SITEMAP_ID, + RunSourceSitemap.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class RunSourceSitemap { + public static final String JSON_PROPERTY_SITEMAP_ID = "sitemap_id"; + @jakarta.annotation.Nonnull + private String sitemapId; + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nullable + private Object type = null; + + public RunSourceSitemap() { + } + + public RunSourceSitemap sitemapId(@jakarta.annotation.Nonnull String sitemapId) { + this.sitemapId = sitemapId; + return this; + } + + /** + * Get sitemapId + * @return sitemapId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SITEMAP_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSitemapId() { + return sitemapId; + } + + + @JsonProperty(value = JSON_PROPERTY_SITEMAP_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSitemapId(@jakarta.annotation.Nonnull String sitemapId) { + this.sitemapId = sitemapId; + } + + + public RunSourceSitemap type(@jakarta.annotation.Nullable Object type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Object getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nullable Object type) { + this.type = type; + } + + + /** + * Return true if this RunSourceSitemap object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RunSourceSitemap runSourceSitemap = (RunSourceSitemap) o; + return Objects.equals(this.sitemapId, runSourceSitemap.sitemapId) && + Objects.equals(this.type, runSourceSitemap.type); + } + + @Override + public int hashCode() { + return Objects.hash(sitemapId, type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class RunSourceSitemap {\n"); + sb.append(" sitemapId: ").append(toIndentedString(sitemapId)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `sitemap_id` to the URL query string + if (getSitemapId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssitemap_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSitemapId())))); + } + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/RunSourceUrlSet.java b/src/main/java/com/sitewarm/sdk/model/RunSourceUrlSet.java new file mode 100644 index 0000000..dc38c0a --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/RunSourceUrlSet.java @@ -0,0 +1,184 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * RunSourceUrlSet + */ +@JsonPropertyOrder({ + RunSourceUrlSet.JSON_PROPERTY_TYPE, + RunSourceUrlSet.JSON_PROPERTY_URL_SET_ID +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class RunSourceUrlSet { + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nullable + private Object type = null; + + public static final String JSON_PROPERTY_URL_SET_ID = "url_set_id"; + @jakarta.annotation.Nonnull + private String urlSetId; + + public RunSourceUrlSet() { + } + + public RunSourceUrlSet type(@jakarta.annotation.Nullable Object type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Object getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nullable Object type) { + this.type = type; + } + + + public RunSourceUrlSet urlSetId(@jakarta.annotation.Nonnull String urlSetId) { + this.urlSetId = urlSetId; + return this; + } + + /** + * Get urlSetId + * @return urlSetId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL_SET_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getUrlSetId() { + return urlSetId; + } + + + @JsonProperty(value = JSON_PROPERTY_URL_SET_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrlSetId(@jakarta.annotation.Nonnull String urlSetId) { + this.urlSetId = urlSetId; + } + + + /** + * Return true if this RunSourceUrlSet object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RunSourceUrlSet runSourceUrlSet = (RunSourceUrlSet) o; + return Objects.equals(this.type, runSourceUrlSet.type) && + Objects.equals(this.urlSetId, runSourceUrlSet.urlSetId); + } + + @Override + public int hashCode() { + return Objects.hash(type, urlSetId); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class RunSourceUrlSet {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" urlSetId: ").append(toIndentedString(urlSetId)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `url_set_id` to the URL query string + if (getUrlSetId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl_set_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrlSetId())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/RunStatus.java b/src/main/java/com/sitewarm/sdk/model/RunStatus.java new file mode 100644 index 0000000..d4a0e0c --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/RunStatus.java @@ -0,0 +1,84 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Lifecycle of a run. Whether the run passed is `outcome`, not the status. `failed` means the run itself broke (see `error_code`); it is never a verdict about the site. + */ +public enum RunStatus { + + QUEUED("queued"), + + RUNNING("running"), + + COMPLETED("completed"), + + CANCELED("canceled"), + + FAILED("failed"); + + private String value; + + RunStatus(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static RunStatus fromValue(String value) { + for (RunStatus b : RunStatus.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Schedule.java b/src/main/java/com/sitewarm/sdk/model/Schedule.java new file mode 100644 index 0000000..664e610 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Schedule.java @@ -0,0 +1,440 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Cadence; +import com.sitewarm.sdk.model.RunOptions; +import com.sitewarm.sdk.model.RunSource; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Schedule + */ +@JsonPropertyOrder({ + Schedule.JSON_PROPERTY_CADENCE, + Schedule.JSON_PROPERTY_CREATED_AT, + Schedule.JSON_PROPERTY_ENABLED, + Schedule.JSON_PROPERTY_ID, + Schedule.JSON_PROPERTY_LAST_RUN_ID, + Schedule.JSON_PROPERTY_NEXT_RUN_AT, + Schedule.JSON_PROPERTY_OPTIONS, + Schedule.JSON_PROPERTY_SITE_ID, + Schedule.JSON_PROPERTY_SOURCE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Schedule { + public static final String JSON_PROPERTY_CADENCE = "cadence"; + @jakarta.annotation.Nonnull + private Cadence cadence; + + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ENABLED = "enabled"; + @jakarta.annotation.Nonnull + private Boolean enabled; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_LAST_RUN_ID = "last_run_id"; + @jakarta.annotation.Nullable + private String lastRunId; + + public static final String JSON_PROPERTY_NEXT_RUN_AT = "next_run_at"; + @jakarta.annotation.Nullable + private OffsetDateTime nextRunAt; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nonnull + private RunOptions options; + + public static final String JSON_PROPERTY_SITE_ID = "site_id"; + @jakarta.annotation.Nonnull + private String siteId; + + public static final String JSON_PROPERTY_SOURCE = "source"; + @jakarta.annotation.Nonnull + private RunSource source; + + public Schedule() { + } + + public Schedule cadence(@jakarta.annotation.Nonnull Cadence cadence) { + this.cadence = cadence; + return this; + } + + /** + * Get cadence + * @return cadence + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CADENCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Cadence getCadence() { + return cadence; + } + + + @JsonProperty(value = JSON_PROPERTY_CADENCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCadence(@jakarta.annotation.Nonnull Cadence cadence) { + this.cadence = cadence; + } + + + public Schedule createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public Schedule enabled(@jakarta.annotation.Nonnull Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Get enabled + * @return enabled + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getEnabled() { + return enabled; + } + + + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEnabled(@jakarta.annotation.Nonnull Boolean enabled) { + this.enabled = enabled; + } + + + public Schedule id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public Schedule lastRunId(@jakarta.annotation.Nullable String lastRunId) { + this.lastRunId = lastRunId; + return this; + } + + /** + * Get lastRunId + * @return lastRunId + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_LAST_RUN_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getLastRunId() { + return lastRunId; + } + + + @JsonProperty(value = JSON_PROPERTY_LAST_RUN_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLastRunId(@jakarta.annotation.Nullable String lastRunId) { + this.lastRunId = lastRunId; + } + + + public Schedule nextRunAt(@jakarta.annotation.Nullable OffsetDateTime nextRunAt) { + this.nextRunAt = nextRunAt; + return this; + } + + /** + * Get nextRunAt + * @return nextRunAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_NEXT_RUN_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getNextRunAt() { + return nextRunAt; + } + + + @JsonProperty(value = JSON_PROPERTY_NEXT_RUN_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setNextRunAt(@jakarta.annotation.Nullable OffsetDateTime nextRunAt) { + this.nextRunAt = nextRunAt; + } + + + public Schedule options(@jakarta.annotation.Nonnull RunOptions options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public RunOptions getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOptions(@jakarta.annotation.Nonnull RunOptions options) { + this.options = options; + } + + + public Schedule siteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + return this; + } + + /** + * Get siteId + * @return siteId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSiteId() { + return siteId; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSiteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + } + + + public Schedule source(@jakarta.annotation.Nonnull RunSource source) { + this.source = source; + return this; + } + + /** + * Get source + * @return source + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public RunSource getSource() { + return source; + } + + + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSource(@jakarta.annotation.Nonnull RunSource source) { + this.source = source; + } + + + /** + * Return true if this Schedule object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Schedule schedule = (Schedule) o; + return Objects.equals(this.cadence, schedule.cadence) && + Objects.equals(this.createdAt, schedule.createdAt) && + Objects.equals(this.enabled, schedule.enabled) && + Objects.equals(this.id, schedule.id) && + Objects.equals(this.lastRunId, schedule.lastRunId) && + Objects.equals(this.nextRunAt, schedule.nextRunAt) && + Objects.equals(this.options, schedule.options) && + Objects.equals(this.siteId, schedule.siteId) && + Objects.equals(this.source, schedule.source); + } + + @Override + public int hashCode() { + return Objects.hash(cadence, createdAt, enabled, id, lastRunId, nextRunAt, options, siteId, source); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Schedule {\n"); + sb.append(" cadence: ").append(toIndentedString(cadence)).append("\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" lastRunId: ").append(toIndentedString(lastRunId)).append("\n"); + sb.append(" nextRunAt: ").append(toIndentedString(nextRunAt)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append(" siteId: ").append(toIndentedString(siteId)).append("\n"); + sb.append(" source: ").append(toIndentedString(source)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `cadence` to the URL query string + if (getCadence() != null) { + joiner.add(getCadence().toUrlQueryString(prefix + "cadence" + suffix)); + } + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `enabled` to the URL query string + if (getEnabled() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senabled%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnabled())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `last_run_id` to the URL query string + if (getLastRunId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%slast_run_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLastRunId())))); + } + + // add `next_run_at` to the URL query string + if (getNextRunAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%snext_run_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getNextRunAt())))); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + // add `site_id` to the URL query string + if (getSiteId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSiteId())))); + } + + // add `source` to the URL query string + if (getSource() != null) { + joiner.add(getSource().toUrlQueryString(prefix + "source" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ScheduleCreate.java b/src/main/java/com/sitewarm/sdk/model/ScheduleCreate.java new file mode 100644 index 0000000..5cd7044 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ScheduleCreate.java @@ -0,0 +1,259 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Cadence; +import com.sitewarm.sdk.model.RunOptions; +import com.sitewarm.sdk.model.RunSource; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ScheduleCreate + */ +@JsonPropertyOrder({ + ScheduleCreate.JSON_PROPERTY_CADENCE, + ScheduleCreate.JSON_PROPERTY_ENABLED, + ScheduleCreate.JSON_PROPERTY_OPTIONS, + ScheduleCreate.JSON_PROPERTY_SOURCE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ScheduleCreate { + public static final String JSON_PROPERTY_CADENCE = "cadence"; + @jakarta.annotation.Nonnull + private Cadence cadence; + + public static final String JSON_PROPERTY_ENABLED = "enabled"; + @jakarta.annotation.Nullable + private Boolean enabled; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RunOptions options; + + public static final String JSON_PROPERTY_SOURCE = "source"; + @jakarta.annotation.Nonnull + private RunSource source; + + public ScheduleCreate() { + } + + public ScheduleCreate cadence(@jakarta.annotation.Nonnull Cadence cadence) { + this.cadence = cadence; + return this; + } + + /** + * Get cadence + * @return cadence + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CADENCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Cadence getCadence() { + return cadence; + } + + + @JsonProperty(value = JSON_PROPERTY_CADENCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCadence(@jakarta.annotation.Nonnull Cadence cadence) { + this.cadence = cadence; + } + + + public ScheduleCreate enabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Get enabled + * @return enabled + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getEnabled() { + return enabled; + } + + + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setEnabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + } + + + public ScheduleCreate options(@jakarta.annotation.Nullable RunOptions options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RunOptions getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RunOptions options) { + this.options = options; + } + + + public ScheduleCreate source(@jakarta.annotation.Nonnull RunSource source) { + this.source = source; + return this; + } + + /** + * Get source + * @return source + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public RunSource getSource() { + return source; + } + + + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSource(@jakarta.annotation.Nonnull RunSource source) { + this.source = source; + } + + + /** + * Return true if this ScheduleCreate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ScheduleCreate scheduleCreate = (ScheduleCreate) o; + return Objects.equals(this.cadence, scheduleCreate.cadence) && + Objects.equals(this.enabled, scheduleCreate.enabled) && + Objects.equals(this.options, scheduleCreate.options) && + Objects.equals(this.source, scheduleCreate.source); + } + + @Override + public int hashCode() { + return Objects.hash(cadence, enabled, options, source); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ScheduleCreate {\n"); + sb.append(" cadence: ").append(toIndentedString(cadence)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append(" source: ").append(toIndentedString(source)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `cadence` to the URL query string + if (getCadence() != null) { + joiner.add(getCadence().toUrlQueryString(prefix + "cadence" + suffix)); + } + + // add `enabled` to the URL query string + if (getEnabled() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senabled%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnabled())))); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + // add `source` to the URL query string + if (getSource() != null) { + joiner.add(getSource().toUrlQueryString(prefix + "source" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ScheduleList.java b/src/main/java/com/sitewarm/sdk/model/ScheduleList.java new file mode 100644 index 0000000..aefa0d7 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ScheduleList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.PageInfo; +import com.sitewarm.sdk.model.Schedule; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ScheduleList + */ +@JsonPropertyOrder({ + ScheduleList.JSON_PROPERTY_DATA, + ScheduleList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ScheduleList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public ScheduleList() { + } + + public ScheduleList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public ScheduleList addDataItem(Schedule dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public ScheduleList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this ScheduleList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ScheduleList scheduleList = (ScheduleList) o; + return Objects.equals(this.data, scheduleList.data) && + Objects.equals(this.page, scheduleList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ScheduleList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/ScheduleUpdate.java b/src/main/java/com/sitewarm/sdk/model/ScheduleUpdate.java new file mode 100644 index 0000000..b58e80e --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/ScheduleUpdate.java @@ -0,0 +1,259 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Cadence; +import com.sitewarm.sdk.model.RunOptions; +import com.sitewarm.sdk.model.RunSource; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * ScheduleUpdate + */ +@JsonPropertyOrder({ + ScheduleUpdate.JSON_PROPERTY_CADENCE, + ScheduleUpdate.JSON_PROPERTY_ENABLED, + ScheduleUpdate.JSON_PROPERTY_OPTIONS, + ScheduleUpdate.JSON_PROPERTY_SOURCE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ScheduleUpdate { + public static final String JSON_PROPERTY_CADENCE = "cadence"; + @jakarta.annotation.Nullable + private Cadence cadence; + + public static final String JSON_PROPERTY_ENABLED = "enabled"; + @jakarta.annotation.Nullable + private Boolean enabled; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RunOptions options; + + public static final String JSON_PROPERTY_SOURCE = "source"; + @jakarta.annotation.Nullable + private RunSource source; + + public ScheduleUpdate() { + } + + public ScheduleUpdate cadence(@jakarta.annotation.Nullable Cadence cadence) { + this.cadence = cadence; + return this; + } + + /** + * Get cadence + * @return cadence + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CADENCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Cadence getCadence() { + return cadence; + } + + + @JsonProperty(value = JSON_PROPERTY_CADENCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCadence(@jakarta.annotation.Nullable Cadence cadence) { + this.cadence = cadence; + } + + + public ScheduleUpdate enabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Get enabled + * @return enabled + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getEnabled() { + return enabled; + } + + + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setEnabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + } + + + public ScheduleUpdate options(@jakarta.annotation.Nullable RunOptions options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RunOptions getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RunOptions options) { + this.options = options; + } + + + public ScheduleUpdate source(@jakarta.annotation.Nullable RunSource source) { + this.source = source; + return this; + } + + /** + * Get source + * @return source + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RunSource getSource() { + return source; + } + + + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSource(@jakarta.annotation.Nullable RunSource source) { + this.source = source; + } + + + /** + * Return true if this ScheduleUpdate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ScheduleUpdate scheduleUpdate = (ScheduleUpdate) o; + return Objects.equals(this.cadence, scheduleUpdate.cadence) && + Objects.equals(this.enabled, scheduleUpdate.enabled) && + Objects.equals(this.options, scheduleUpdate.options) && + Objects.equals(this.source, scheduleUpdate.source); + } + + @Override + public int hashCode() { + return Objects.hash(cadence, enabled, options, source); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ScheduleUpdate {\n"); + sb.append(" cadence: ").append(toIndentedString(cadence)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append(" source: ").append(toIndentedString(source)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `cadence` to the URL query string + if (getCadence() != null) { + joiner.add(getCadence().toUrlQueryString(prefix + "cadence" + suffix)); + } + + // add `enabled` to the URL query string + if (getEnabled() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senabled%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnabled())))); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + // add `source` to the URL query string + if (getSource() != null) { + joiner.add(getSource().toUrlQueryString(prefix + "source" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Scope.java b/src/main/java/com/sitewarm/sdk/model/Scope.java new file mode 100644 index 0000000..cb5394d --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Scope.java @@ -0,0 +1,96 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Gets or Sets Scope + */ +public enum Scope { + + SITES_READ("sites:read"), + + SITES_WRITE("sites:write"), + + WARM_RUNS_READ("warm-runs:read"), + + WARM_RUNS_WRITE("warm-runs:write"), + + CACHE_REPORTS_READ("cache-reports:read"), + + SCHEDULES_READ("schedules:read"), + + SCHEDULES_WRITE("schedules:write"), + + WEBHOOKS_READ("webhooks:read"), + + WEBHOOKS_WRITE("webhooks:write"), + + API_KEYS_READ("api-keys:read"), + + API_KEYS_WRITE("api-keys:write"); + + private String value; + + Scope(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static Scope fromValue(String value) { + for (Scope b : Scope.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Site.java b/src/main/java/com/sitewarm/sdk/model/Site.java new file mode 100644 index 0000000..3b88cee --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Site.java @@ -0,0 +1,331 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.SiteSettings; +import com.sitewarm.sdk.model.SiteVerification; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Site + */ +@JsonPropertyOrder({ + Site.JSON_PROPERTY_CREATED_AT, + Site.JSON_PROPERTY_HOSTNAME, + Site.JSON_PROPERTY_ID, + Site.JSON_PROPERTY_PAUSED, + Site.JSON_PROPERTY_SETTINGS, + Site.JSON_PROPERTY_VERIFICATION +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Site { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_HOSTNAME = "hostname"; + @jakarta.annotation.Nonnull + private String hostname; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_PAUSED = "paused"; + @jakarta.annotation.Nullable + private Boolean paused; + + public static final String JSON_PROPERTY_SETTINGS = "settings"; + @jakarta.annotation.Nullable + private SiteSettings settings; + + public static final String JSON_PROPERTY_VERIFICATION = "verification"; + @jakarta.annotation.Nonnull + private SiteVerification verification; + + public Site() { + } + + public Site createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public Site hostname(@jakarta.annotation.Nonnull String hostname) { + this.hostname = hostname; + return this; + } + + /** + * The site's hostname; apex and `www` are the same site. + * @return hostname + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_HOSTNAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getHostname() { + return hostname; + } + + + @JsonProperty(value = JSON_PROPERTY_HOSTNAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHostname(@jakarta.annotation.Nonnull String hostname) { + this.hostname = hostname; + } + + + public Site id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public Site paused(@jakarta.annotation.Nullable Boolean paused) { + this.paused = paused; + return this; + } + + /** + * Read-only here. A paused site gets no new jobs. Omitted until sites can be paused. + * @return paused + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_PAUSED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getPaused() { + return paused; + } + + + @JsonProperty(value = JSON_PROPERTY_PAUSED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPaused(@jakarta.annotation.Nullable Boolean paused) { + this.paused = paused; + } + + + public Site settings(@jakarta.annotation.Nullable SiteSettings settings) { + this.settings = settings; + return this; + } + + /** + * Omitted until site settings are stored. + * @return settings + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SETTINGS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public SiteSettings getSettings() { + return settings; + } + + + @JsonProperty(value = JSON_PROPERTY_SETTINGS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSettings(@jakarta.annotation.Nullable SiteSettings settings) { + this.settings = settings; + } + + + public Site verification(@jakarta.annotation.Nonnull SiteVerification verification) { + this.verification = verification; + return this; + } + + /** + * Get verification + * @return verification + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VERIFICATION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public SiteVerification getVerification() { + return verification; + } + + + @JsonProperty(value = JSON_PROPERTY_VERIFICATION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setVerification(@jakarta.annotation.Nonnull SiteVerification verification) { + this.verification = verification; + } + + + /** + * Return true if this Site object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Site site = (Site) o; + return Objects.equals(this.createdAt, site.createdAt) && + Objects.equals(this.hostname, site.hostname) && + Objects.equals(this.id, site.id) && + Objects.equals(this.paused, site.paused) && + Objects.equals(this.settings, site.settings) && + Objects.equals(this.verification, site.verification); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, hostname, id, paused, settings, verification); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Site {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" hostname: ").append(toIndentedString(hostname)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" paused: ").append(toIndentedString(paused)).append("\n"); + sb.append(" settings: ").append(toIndentedString(settings)).append("\n"); + sb.append(" verification: ").append(toIndentedString(verification)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `hostname` to the URL query string + if (getHostname() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%shostname%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getHostname())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `paused` to the URL query string + if (getPaused() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%spaused%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPaused())))); + } + + // add `settings` to the URL query string + if (getSettings() != null) { + joiner.add(getSettings().toUrlQueryString(prefix + "settings" + suffix)); + } + + // add `verification` to the URL query string + if (getVerification() != null) { + joiner.add(getVerification().toUrlQueryString(prefix + "verification" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SiteCreate.java b/src/main/java/com/sitewarm/sdk/model/SiteCreate.java new file mode 100644 index 0000000..d383df3 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SiteCreate.java @@ -0,0 +1,185 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.SiteSettings; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * SiteCreate + */ +@JsonPropertyOrder({ + SiteCreate.JSON_PROPERTY_HOSTNAME, + SiteCreate.JSON_PROPERTY_SETTINGS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SiteCreate { + public static final String JSON_PROPERTY_HOSTNAME = "hostname"; + @jakarta.annotation.Nonnull + private String hostname; + + public static final String JSON_PROPERTY_SETTINGS = "settings"; + @jakarta.annotation.Nullable + private SiteSettings settings; + + public SiteCreate() { + } + + public SiteCreate hostname(@jakarta.annotation.Nonnull String hostname) { + this.hostname = hostname; + return this; + } + + /** + * Get hostname + * @return hostname + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_HOSTNAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getHostname() { + return hostname; + } + + + @JsonProperty(value = JSON_PROPERTY_HOSTNAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHostname(@jakarta.annotation.Nonnull String hostname) { + this.hostname = hostname; + } + + + public SiteCreate settings(@jakarta.annotation.Nullable SiteSettings settings) { + this.settings = settings; + return this; + } + + /** + * Get settings + * @return settings + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SETTINGS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public SiteSettings getSettings() { + return settings; + } + + + @JsonProperty(value = JSON_PROPERTY_SETTINGS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSettings(@jakarta.annotation.Nullable SiteSettings settings) { + this.settings = settings; + } + + + /** + * Return true if this SiteCreate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SiteCreate siteCreate = (SiteCreate) o; + return Objects.equals(this.hostname, siteCreate.hostname) && + Objects.equals(this.settings, siteCreate.settings); + } + + @Override + public int hashCode() { + return Objects.hash(hostname, settings); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SiteCreate {\n"); + sb.append(" hostname: ").append(toIndentedString(hostname)).append("\n"); + sb.append(" settings: ").append(toIndentedString(settings)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `hostname` to the URL query string + if (getHostname() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%shostname%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getHostname())))); + } + + // add `settings` to the URL query string + if (getSettings() != null) { + joiner.add(getSettings().toUrlQueryString(prefix + "settings" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SiteList.java b/src/main/java/com/sitewarm/sdk/model/SiteList.java new file mode 100644 index 0000000..f571303 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SiteList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.PageInfo; +import com.sitewarm.sdk.model.Site; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * SiteList + */ +@JsonPropertyOrder({ + SiteList.JSON_PROPERTY_DATA, + SiteList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SiteList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public SiteList() { + } + + public SiteList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public SiteList addDataItem(Site dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public SiteList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this SiteList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SiteList siteList = (SiteList) o; + return Objects.equals(this.data, siteList.data) && + Objects.equals(this.page, siteList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SiteList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SiteSettings.java b/src/main/java/com/sitewarm/sdk/model/SiteSettings.java new file mode 100644 index 0000000..82d3be4 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SiteSettings.java @@ -0,0 +1,148 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * SiteSettings + */ +@JsonPropertyOrder({ + SiteSettings.JSON_PROPERTY_DEVICE_VARIANTS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SiteSettings { + public static final String JSON_PROPERTY_DEVICE_VARIANTS = "device_variants"; + @jakarta.annotation.Nullable + private Boolean deviceVariants; + + public SiteSettings() { + } + + public SiteSettings deviceVariants(@jakarta.annotation.Nullable Boolean deviceVariants) { + this.deviceVariants = deviceVariants; + return this; + } + + /** + * The operator declares that the CDN segments the cache by device, so affected URLs are reported `variant-unverifiable`. + * @return deviceVariants + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DEVICE_VARIANTS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getDeviceVariants() { + return deviceVariants; + } + + + @JsonProperty(value = JSON_PROPERTY_DEVICE_VARIANTS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDeviceVariants(@jakarta.annotation.Nullable Boolean deviceVariants) { + this.deviceVariants = deviceVariants; + } + + + /** + * Return true if this SiteSettings object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SiteSettings siteSettings = (SiteSettings) o; + return Objects.equals(this.deviceVariants, siteSettings.deviceVariants); + } + + @Override + public int hashCode() { + return Objects.hash(deviceVariants); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SiteSettings {\n"); + sb.append(" deviceVariants: ").append(toIndentedString(deviceVariants)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `device_variants` to the URL query string + if (getDeviceVariants() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdevice_variants%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDeviceVariants())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SiteUpdate.java b/src/main/java/com/sitewarm/sdk/model/SiteUpdate.java new file mode 100644 index 0000000..6493455 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SiteUpdate.java @@ -0,0 +1,149 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.SiteSettings; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * SiteUpdate + */ +@JsonPropertyOrder({ + SiteUpdate.JSON_PROPERTY_SETTINGS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SiteUpdate { + public static final String JSON_PROPERTY_SETTINGS = "settings"; + @jakarta.annotation.Nullable + private SiteSettings settings; + + public SiteUpdate() { + } + + public SiteUpdate settings(@jakarta.annotation.Nullable SiteSettings settings) { + this.settings = settings; + return this; + } + + /** + * Get settings + * @return settings + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SETTINGS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public SiteSettings getSettings() { + return settings; + } + + + @JsonProperty(value = JSON_PROPERTY_SETTINGS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSettings(@jakarta.annotation.Nullable SiteSettings settings) { + this.settings = settings; + } + + + /** + * Return true if this SiteUpdate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SiteUpdate siteUpdate = (SiteUpdate) o; + return Objects.equals(this.settings, siteUpdate.settings); + } + + @Override + public int hashCode() { + return Objects.hash(settings); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SiteUpdate {\n"); + sb.append(" settings: ").append(toIndentedString(settings)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `settings` to the URL query string + if (getSettings() != null) { + joiner.add(getSettings().toUrlQueryString(prefix + "settings" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SiteVerification.java b/src/main/java/com/sitewarm/sdk/model/SiteVerification.java new file mode 100644 index 0000000..89860bc --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SiteVerification.java @@ -0,0 +1,220 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Read-only. Verification is done outside this API. + */ +@JsonPropertyOrder({ + SiteVerification.JSON_PROPERTY_STATUS, + SiteVerification.JSON_PROPERTY_VERIFIED_AT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SiteVerification { + /** + * `verified` only while the proof is valid. A pending, expired or lapsed proof is `unverified`. + */ + public enum StatusEnum { + UNVERIFIED(String.valueOf("unverified")), + + VERIFIED(String.valueOf("verified")); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + public static final String JSON_PROPERTY_STATUS = "status"; + @jakarta.annotation.Nonnull + private StatusEnum status; + + public static final String JSON_PROPERTY_VERIFIED_AT = "verified_at"; + @jakarta.annotation.Nullable + private OffsetDateTime verifiedAt; + + public SiteVerification() { + } + + public SiteVerification status(@jakarta.annotation.Nonnull StatusEnum status) { + this.status = status; + return this; + } + + /** + * `verified` only while the proof is valid. A pending, expired or lapsed proof is `unverified`. + * @return status + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public StatusEnum getStatus() { + return status; + } + + + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setStatus(@jakarta.annotation.Nonnull StatusEnum status) { + this.status = status; + } + + + public SiteVerification verifiedAt(@jakarta.annotation.Nullable OffsetDateTime verifiedAt) { + this.verifiedAt = verifiedAt; + return this; + } + + /** + * Get verifiedAt + * @return verifiedAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_VERIFIED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getVerifiedAt() { + return verifiedAt; + } + + + @JsonProperty(value = JSON_PROPERTY_VERIFIED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setVerifiedAt(@jakarta.annotation.Nullable OffsetDateTime verifiedAt) { + this.verifiedAt = verifiedAt; + } + + + /** + * Return true if this Site_verification object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SiteVerification siteVerification = (SiteVerification) o; + return Objects.equals(this.status, siteVerification.status) && + Objects.equals(this.verifiedAt, siteVerification.verifiedAt); + } + + @Override + public int hashCode() { + return Objects.hash(status, verifiedAt); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SiteVerification {\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" verifiedAt: ").append(toIndentedString(verifiedAt)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `status` to the URL query string + if (getStatus() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sstatus%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getStatus())))); + } + + // add `verified_at` to the URL query string + if (getVerifiedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sverified_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getVerifiedAt())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SiteVerificationChangedEvent.java b/src/main/java/com/sitewarm/sdk/model/SiteVerificationChangedEvent.java new file mode 100644 index 0000000..c20d044 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SiteVerificationChangedEvent.java @@ -0,0 +1,258 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Site; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * SiteVerificationChangedEvent + */ +@JsonPropertyOrder({ + SiteVerificationChangedEvent.JSON_PROPERTY_CREATED_AT, + SiteVerificationChangedEvent.JSON_PROPERTY_ID, + SiteVerificationChangedEvent.JSON_PROPERTY_TYPE, + SiteVerificationChangedEvent.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SiteVerificationChangedEvent { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nullable + private Object type = null; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private Site data; + + public SiteVerificationChangedEvent() { + } + + public SiteVerificationChangedEvent createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public SiteVerificationChangedEvent id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Unique per event. A redelivery of the same event keeps the id; use it to deduplicate. + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public SiteVerificationChangedEvent type(@jakarta.annotation.Nullable Object type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Object getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nullable Object type) { + this.type = type; + } + + + public SiteVerificationChangedEvent data(@jakarta.annotation.Nonnull Site data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Site getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull Site data) { + this.data = data; + } + + + /** + * Return true if this SiteVerificationChangedEvent object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SiteVerificationChangedEvent siteVerificationChangedEvent = (SiteVerificationChangedEvent) o; + return Objects.equals(this.createdAt, siteVerificationChangedEvent.createdAt) && + Objects.equals(this.id, siteVerificationChangedEvent.id) && + Objects.equals(this.type, siteVerificationChangedEvent.type) && + Objects.equals(this.data, siteVerificationChangedEvent.data); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, type, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SiteVerificationChangedEvent {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Sitemap.java b/src/main/java/com/sitewarm/sdk/model/Sitemap.java new file mode 100644 index 0000000..bb28618 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Sitemap.java @@ -0,0 +1,258 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.net.URI; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Sitemap + */ +@JsonPropertyOrder({ + Sitemap.JSON_PROPERTY_CREATED_AT, + Sitemap.JSON_PROPERTY_ID, + Sitemap.JSON_PROPERTY_SITE_ID, + Sitemap.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Sitemap { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_SITE_ID = "site_id"; + @jakarta.annotation.Nonnull + private String siteId; + + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private URI url; + + public Sitemap() { + } + + public Sitemap createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public Sitemap id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public Sitemap siteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + return this; + } + + /** + * Get siteId + * @return siteId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSiteId() { + return siteId; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSiteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + } + + + public Sitemap url(@jakarta.annotation.Nonnull URI url) { + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public URI getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull URI url) { + this.url = url; + } + + + /** + * Return true if this Sitemap object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Sitemap sitemap = (Sitemap) o; + return Objects.equals(this.createdAt, sitemap.createdAt) && + Objects.equals(this.id, sitemap.id) && + Objects.equals(this.siteId, sitemap.siteId) && + Objects.equals(this.url, sitemap.url); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, siteId, url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Sitemap {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" siteId: ").append(toIndentedString(siteId)).append("\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `site_id` to the URL query string + if (getSiteId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSiteId())))); + } + + // add `url` to the URL query string + if (getUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrl())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SitemapCreate.java b/src/main/java/com/sitewarm/sdk/model/SitemapCreate.java new file mode 100644 index 0000000..00ba7be --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SitemapCreate.java @@ -0,0 +1,149 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.net.URI; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * SitemapCreate + */ +@JsonPropertyOrder({ + SitemapCreate.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SitemapCreate { + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private URI url; + + public SitemapCreate() { + } + + public SitemapCreate url(@jakarta.annotation.Nonnull URI url) { + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public URI getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull URI url) { + this.url = url; + } + + + /** + * Return true if this SitemapCreate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SitemapCreate sitemapCreate = (SitemapCreate) o; + return Objects.equals(this.url, sitemapCreate.url); + } + + @Override + public int hashCode() { + return Objects.hash(url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SitemapCreate {\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `url` to the URL query string + if (getUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrl())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/SitemapList.java b/src/main/java/com/sitewarm/sdk/model/SitemapList.java new file mode 100644 index 0000000..bff4e30 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/SitemapList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.PageInfo; +import com.sitewarm.sdk.model.Sitemap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * SitemapList + */ +@JsonPropertyOrder({ + SitemapList.JSON_PROPERTY_DATA, + SitemapList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class SitemapList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public SitemapList() { + } + + public SitemapList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public SitemapList addDataItem(Sitemap dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public SitemapList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this SitemapList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SitemapList sitemapList = (SitemapList) o; + return Objects.equals(this.data, sitemapList.data) && + Objects.equals(this.page, sitemapList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SitemapList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Trigger.java b/src/main/java/com/sitewarm/sdk/model/Trigger.java new file mode 100644 index 0000000..83a3b31 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Trigger.java @@ -0,0 +1,221 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.TriggerType; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Trigger + */ +@JsonPropertyOrder({ + Trigger.JSON_PROPERTY_API_KEY_ID, + Trigger.JSON_PROPERTY_SCHEDULE_ID, + Trigger.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Trigger { + public static final String JSON_PROPERTY_API_KEY_ID = "api_key_id"; + @jakarta.annotation.Nullable + private String apiKeyId; + + public static final String JSON_PROPERTY_SCHEDULE_ID = "schedule_id"; + @jakarta.annotation.Nullable + private String scheduleId; + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nonnull + private TriggerType type; + + public Trigger() { + } + + public Trigger apiKeyId(@jakarta.annotation.Nullable String apiKeyId) { + this.apiKeyId = apiKeyId; + return this; + } + + /** + * Get apiKeyId + * @return apiKeyId + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_API_KEY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getApiKeyId() { + return apiKeyId; + } + + + @JsonProperty(value = JSON_PROPERTY_API_KEY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setApiKeyId(@jakarta.annotation.Nullable String apiKeyId) { + this.apiKeyId = apiKeyId; + } + + + public Trigger scheduleId(@jakarta.annotation.Nullable String scheduleId) { + this.scheduleId = scheduleId; + return this; + } + + /** + * Get scheduleId + * @return scheduleId + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SCHEDULE_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getScheduleId() { + return scheduleId; + } + + + @JsonProperty(value = JSON_PROPERTY_SCHEDULE_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setScheduleId(@jakarta.annotation.Nullable String scheduleId) { + this.scheduleId = scheduleId; + } + + + public Trigger type(@jakarta.annotation.Nonnull TriggerType type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TriggerType getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nonnull TriggerType type) { + this.type = type; + } + + + /** + * Return true if this Trigger object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Trigger trigger = (Trigger) o; + return Objects.equals(this.apiKeyId, trigger.apiKeyId) && + Objects.equals(this.scheduleId, trigger.scheduleId) && + Objects.equals(this.type, trigger.type); + } + + @Override + public int hashCode() { + return Objects.hash(apiKeyId, scheduleId, type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Trigger {\n"); + sb.append(" apiKeyId: ").append(toIndentedString(apiKeyId)).append("\n"); + sb.append(" scheduleId: ").append(toIndentedString(scheduleId)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `api_key_id` to the URL query string + if (getApiKeyId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sapi_key_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getApiKeyId())))); + } + + // add `schedule_id` to the URL query string + if (getScheduleId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sschedule_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getScheduleId())))); + } + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/TriggerType.java b/src/main/java/com/sitewarm/sdk/model/TriggerType.java new file mode 100644 index 0000000..9bf6483 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/TriggerType.java @@ -0,0 +1,80 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Gets or Sets TriggerType + */ +public enum TriggerType { + + API("api"), + + SCHEDULE("schedule"), + + PANEL("panel"); + + private String value; + + TriggerType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TriggerType fromValue(String value) { + for (TriggerType b : TriggerType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/UnknownReason.java b/src/main/java/com/sitewarm/sdk/model/UnknownReason.java new file mode 100644 index 0000000..4c26723 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/UnknownReason.java @@ -0,0 +1,78 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Why a state is `unknown`. + */ +public enum UnknownReason { + + CDN_HIDDEN("cdn-hidden"), + + REGION_UNAVAILABLE("region-unavailable"); + + private String value; + + UnknownReason(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static UnknownReason fromValue(String value) { + for (UnknownReason b : UnknownReason.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + if (prefix == null) { + prefix = ""; + } + + return String.format(java.util.Locale.ROOT, "%s=%s", prefix, this.toString()); + } + +} + diff --git a/src/main/java/com/sitewarm/sdk/model/UrlSet.java b/src/main/java/com/sitewarm/sdk/model/UrlSet.java new file mode 100644 index 0000000..bfb6a32 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/UrlSet.java @@ -0,0 +1,347 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.net.URI; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * UrlSet + */ +@JsonPropertyOrder({ + UrlSet.JSON_PROPERTY_CREATED_AT, + UrlSet.JSON_PROPERTY_ID, + UrlSet.JSON_PROPERTY_NAME, + UrlSet.JSON_PROPERTY_SITE_ID, + UrlSet.JSON_PROPERTY_URL_COUNT, + UrlSet.JSON_PROPERTY_URLS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class UrlSet { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_NAME = "name"; + @jakarta.annotation.Nonnull + private String name; + + public static final String JSON_PROPERTY_SITE_ID = "site_id"; + @jakarta.annotation.Nonnull + private String siteId; + + public static final String JSON_PROPERTY_URL_COUNT = "url_count"; + @jakarta.annotation.Nonnull + private Integer urlCount; + + public static final String JSON_PROPERTY_URLS = "urls"; + @jakarta.annotation.Nullable + private List urls = new ArrayList<>(); + + public UrlSet() { + } + + public UrlSet createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public UrlSet id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public UrlSet name(@jakarta.annotation.Nonnull String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getName() { + return name; + } + + + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setName(@jakarta.annotation.Nonnull String name) { + this.name = name; + } + + + public UrlSet siteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + return this; + } + + /** + * Get siteId + * @return siteId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSiteId() { + return siteId; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSiteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + } + + + public UrlSet urlCount(@jakarta.annotation.Nonnull Integer urlCount) { + this.urlCount = urlCount; + return this; + } + + /** + * Get urlCount + * minimum: 0 + * @return urlCount + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getUrlCount() { + return urlCount; + } + + + @JsonProperty(value = JSON_PROPERTY_URL_COUNT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrlCount(@jakarta.annotation.Nonnull Integer urlCount) { + this.urlCount = urlCount; + } + + + public UrlSet urls(@jakarta.annotation.Nullable List urls) { + this.urls = urls; + return this; + } + + public UrlSet addUrlsItem(URI urlsItem) { + if (this.urls == null) { + this.urls = new ArrayList<>(); + } + this.urls.add(urlsItem); + return this; + } + + /** + * The URLs in warming priority order. Returned by `getUrlSet`, omitted in lists. + * @return urls + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_URLS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getUrls() { + return urls; + } + + + @JsonProperty(value = JSON_PROPERTY_URLS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUrls(@jakarta.annotation.Nullable List urls) { + this.urls = urls; + } + + + /** + * Return true if this UrlSet object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UrlSet urlSet = (UrlSet) o; + return Objects.equals(this.createdAt, urlSet.createdAt) && + Objects.equals(this.id, urlSet.id) && + Objects.equals(this.name, urlSet.name) && + Objects.equals(this.siteId, urlSet.siteId) && + Objects.equals(this.urlCount, urlSet.urlCount) && + Objects.equals(this.urls, urlSet.urls); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, name, siteId, urlCount, urls); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UrlSet {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" siteId: ").append(toIndentedString(siteId)).append("\n"); + sb.append(" urlCount: ").append(toIndentedString(urlCount)).append("\n"); + sb.append(" urls: ").append(toIndentedString(urls)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `name` to the URL query string + if (getName() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sname%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getName())))); + } + + // add `site_id` to the URL query string + if (getSiteId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSiteId())))); + } + + // add `url_count` to the URL query string + if (getUrlCount() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl_count%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrlCount())))); + } + + // add `urls` to the URL query string + if (getUrls() != null) { + for (int i = 0; i < getUrls().size(); i++) { + if (getUrls().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surls%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getUrls().get(i))))); + } + } + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/UrlSetList.java b/src/main/java/com/sitewarm/sdk/model/UrlSetList.java new file mode 100644 index 0000000..7da98fe --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/UrlSetList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.PageInfo; +import com.sitewarm.sdk.model.UrlSet; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * UrlSetList + */ +@JsonPropertyOrder({ + UrlSetList.JSON_PROPERTY_DATA, + UrlSetList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class UrlSetList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public UrlSetList() { + } + + public UrlSetList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public UrlSetList addDataItem(UrlSet dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public UrlSetList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this UrlSetList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UrlSetList urlSetList = (UrlSetList) o; + return Objects.equals(this.data, urlSetList.data) && + Objects.equals(this.page, urlSetList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UrlSetList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/UrlSetWrite.java b/src/main/java/com/sitewarm/sdk/model/UrlSetWrite.java new file mode 100644 index 0000000..c01795f --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/UrlSetWrite.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * UrlSetWrite + */ +@JsonPropertyOrder({ + UrlSetWrite.JSON_PROPERTY_NAME, + UrlSetWrite.JSON_PROPERTY_URLS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class UrlSetWrite { + public static final String JSON_PROPERTY_NAME = "name"; + @jakarta.annotation.Nonnull + private String name; + + public static final String JSON_PROPERTY_URLS = "urls"; + @jakarta.annotation.Nonnull + private List urls = new ArrayList<>(); + + public UrlSetWrite() { + } + + public UrlSetWrite name(@jakarta.annotation.Nonnull String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getName() { + return name; + } + + + @JsonProperty(value = JSON_PROPERTY_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setName(@jakarta.annotation.Nonnull String name) { + this.name = name; + } + + + public UrlSetWrite urls(@jakarta.annotation.Nonnull List urls) { + this.urls = urls; + return this; + } + + public UrlSetWrite addUrlsItem(URI urlsItem) { + if (this.urls == null) { + this.urls = new ArrayList<>(); + } + this.urls.add(urlsItem); + return this; + } + + /** + * Absolute URLs on the site's hostname, in priority order. + * @return urls + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URLS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getUrls() { + return urls; + } + + + @JsonProperty(value = JSON_PROPERTY_URLS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrls(@jakarta.annotation.Nonnull List urls) { + this.urls = urls; + } + + + /** + * Return true if this UrlSetWrite object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UrlSetWrite urlSetWrite = (UrlSetWrite) o; + return Objects.equals(this.name, urlSetWrite.name) && + Objects.equals(this.urls, urlSetWrite.urls); + } + + @Override + public int hashCode() { + return Objects.hash(name, urls); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UrlSetWrite {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" urls: ").append(toIndentedString(urls)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `name` to the URL query string + if (getName() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sname%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getName())))); + } + + // add `urls` to the URL query string + if (getUrls() != null) { + for (int i = 0; i < getUrls().size(); i++) { + if (getUrls().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surls%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getUrls().get(i))))); + } + } + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/VantagePointRef.java b/src/main/java/com/sitewarm/sdk/model/VantagePointRef.java new file mode 100644 index 0000000..f88869b --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/VantagePointRef.java @@ -0,0 +1,184 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * VantagePointRef + */ +@JsonPropertyOrder({ + VantagePointRef.JSON_PROPERTY_ID, + VantagePointRef.JSON_PROPERTY_REGION +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class VantagePointRef { + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_REGION = "region"; + @jakarta.annotation.Nonnull + private String region; + + public VantagePointRef() { + } + + public VantagePointRef id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public VantagePointRef region(@jakarta.annotation.Nonnull String region) { + this.region = region; + return this; + } + + /** + * Get region + * @return region + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_REGION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getRegion() { + return region; + } + + + @JsonProperty(value = JSON_PROPERTY_REGION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setRegion(@jakarta.annotation.Nonnull String region) { + this.region = region; + } + + + /** + * Return true if this VantagePointRef object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + VantagePointRef vantagePointRef = (VantagePointRef) o; + return Objects.equals(this.id, vantagePointRef.id) && + Objects.equals(this.region, vantagePointRef.region); + } + + @Override + public int hashCode() { + return Objects.hash(id, region); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class VantagePointRef {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" region: ").append(toIndentedString(region)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `region` to the URL query string + if (getRegion() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sregion%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getRegion())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/VantagePointSummary.java b/src/main/java/com/sitewarm/sdk/model/VantagePointSummary.java new file mode 100644 index 0000000..5ad497d --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/VantagePointSummary.java @@ -0,0 +1,345 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.RunStatus; +import com.sitewarm.sdk.model.UnknownReason; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * VantagePointSummary + */ +@JsonPropertyOrder({ + VantagePointSummary.JSON_PROPERTY_COUNTS, + VantagePointSummary.JSON_PROPERTY_N, + VantagePointSummary.JSON_PROPERTY_REGION, + VantagePointSummary.JSON_PROPERTY_STATUS, + VantagePointSummary.JSON_PROPERTY_UNKNOWN_REASON, + VantagePointSummary.JSON_PROPERTY_VANTAGE_POINT_ID +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class VantagePointSummary { + public static final String JSON_PROPERTY_COUNTS = "counts"; + @jakarta.annotation.Nonnull + private Map counts = new HashMap<>(); + + public static final String JSON_PROPERTY_N = "n"; + @jakarta.annotation.Nonnull + private Integer n; + + public static final String JSON_PROPERTY_REGION = "region"; + @jakarta.annotation.Nonnull + private String region; + + public static final String JSON_PROPERTY_STATUS = "status"; + @jakarta.annotation.Nonnull + private RunStatus status; + + public static final String JSON_PROPERTY_UNKNOWN_REASON = "unknown_reason"; + @jakarta.annotation.Nullable + private UnknownReason unknownReason; + + public static final String JSON_PROPERTY_VANTAGE_POINT_ID = "vantage_point_id"; + @jakarta.annotation.Nonnull + private String vantagePointId; + + public VantagePointSummary() { + } + + public VantagePointSummary counts(@jakarta.annotation.Nonnull Map counts) { + this.counts = counts; + return this; + } + + public VantagePointSummary putCountsItem(String key, Integer countsItem) { + if (this.counts == null) { + this.counts = new HashMap<>(); + } + this.counts.put(key, countsItem); + return this; + } + + /** + * Number of results per cache state. States with no results may be omitted. + * @return counts + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_COUNTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Map getCounts() { + return counts; + } + + + @JsonProperty(value = JSON_PROPERTY_COUNTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCounts(@jakarta.annotation.Nonnull Map counts) { + this.counts = counts; + } + + + public VantagePointSummary n(@jakarta.annotation.Nonnull Integer n) { + this.n = n; + return this; + } + + /** + * Number of results (URL by profile) for this vantage point. + * minimum: 0 + * @return n + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_N, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Integer getN() { + return n; + } + + + @JsonProperty(value = JSON_PROPERTY_N, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setN(@jakarta.annotation.Nonnull Integer n) { + this.n = n; + } + + + public VantagePointSummary region(@jakarta.annotation.Nonnull String region) { + this.region = region; + return this; + } + + /** + * Get region + * @return region + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_REGION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getRegion() { + return region; + } + + + @JsonProperty(value = JSON_PROPERTY_REGION, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setRegion(@jakarta.annotation.Nonnull String region) { + this.region = region; + } + + + public VantagePointSummary status(@jakarta.annotation.Nonnull RunStatus status) { + this.status = status; + return this; + } + + /** + * Get status + * @return status + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public RunStatus getStatus() { + return status; + } + + + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setStatus(@jakarta.annotation.Nonnull RunStatus status) { + this.status = status; + } + + + public VantagePointSummary unknownReason(@jakarta.annotation.Nullable UnknownReason unknownReason) { + this.unknownReason = unknownReason; + return this; + } + + /** + * Get unknownReason + * @return unknownReason + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_UNKNOWN_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public UnknownReason getUnknownReason() { + return unknownReason; + } + + + @JsonProperty(value = JSON_PROPERTY_UNKNOWN_REASON, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUnknownReason(@jakarta.annotation.Nullable UnknownReason unknownReason) { + this.unknownReason = unknownReason; + } + + + public VantagePointSummary vantagePointId(@jakarta.annotation.Nonnull String vantagePointId) { + this.vantagePointId = vantagePointId; + return this; + } + + /** + * Get vantagePointId + * @return vantagePointId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getVantagePointId() { + return vantagePointId; + } + + + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINT_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setVantagePointId(@jakarta.annotation.Nonnull String vantagePointId) { + this.vantagePointId = vantagePointId; + } + + + /** + * Return true if this VantagePointSummary object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + VantagePointSummary vantagePointSummary = (VantagePointSummary) o; + return Objects.equals(this.counts, vantagePointSummary.counts) && + Objects.equals(this.n, vantagePointSummary.n) && + Objects.equals(this.region, vantagePointSummary.region) && + Objects.equals(this.status, vantagePointSummary.status) && + Objects.equals(this.unknownReason, vantagePointSummary.unknownReason) && + Objects.equals(this.vantagePointId, vantagePointSummary.vantagePointId); + } + + @Override + public int hashCode() { + return Objects.hash(counts, n, region, status, unknownReason, vantagePointId); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class VantagePointSummary {\n"); + sb.append(" counts: ").append(toIndentedString(counts)).append("\n"); + sb.append(" n: ").append(toIndentedString(n)).append("\n"); + sb.append(" region: ").append(toIndentedString(region)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" unknownReason: ").append(toIndentedString(unknownReason)).append("\n"); + sb.append(" vantagePointId: ").append(toIndentedString(vantagePointId)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `counts` to the URL query string + if (getCounts() != null) { + for (String _key : getCounts().keySet()) { + joiner.add(String.format(java.util.Locale.ROOT, "%scounts%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, _key, containerSuffix), + getCounts().get(_key), ApiClient.urlEncode(ApiClient.valueToString(getCounts().get(_key))))); + } + } + + // add `n` to the URL query string + if (getN() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sn%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getN())))); + } + + // add `region` to the URL query string + if (getRegion() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sregion%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getRegion())))); + } + + // add `status` to the URL query string + if (getStatus() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sstatus%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getStatus())))); + } + + // add `unknown_reason` to the URL query string + if (getUnknownReason() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sunknown_reason%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUnknownReason())))); + } + + // add `vantage_point_id` to the URL query string + if (getVantagePointId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%svantage_point_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getVantagePointId())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WarmRun.java b/src/main/java/com/sitewarm/sdk/model/WarmRun.java new file mode 100644 index 0000000..3baed29 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WarmRun.java @@ -0,0 +1,603 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Deployment; +import com.sitewarm.sdk.model.EffectiveRunOptions; +import com.sitewarm.sdk.model.Outcome; +import com.sitewarm.sdk.model.RunSource; +import com.sitewarm.sdk.model.RunStatus; +import com.sitewarm.sdk.model.Trigger; +import com.sitewarm.sdk.model.VantagePointSummary; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WarmRun + */ +@JsonPropertyOrder({ + WarmRun.JSON_PROPERTY_CREATED_AT, + WarmRun.JSON_PROPERTY_DEPLOYMENT, + WarmRun.JSON_PROPERTY_ERROR_CODE, + WarmRun.JSON_PROPERTY_FINISHED_AT, + WarmRun.JSON_PROPERTY_ID, + WarmRun.JSON_PROPERTY_OPTIONS, + WarmRun.JSON_PROPERTY_OUTCOME, + WarmRun.JSON_PROPERTY_SITE_ID, + WarmRun.JSON_PROPERTY_SOURCE, + WarmRun.JSON_PROPERTY_STARTED_AT, + WarmRun.JSON_PROPERTY_STATUS, + WarmRun.JSON_PROPERTY_TRIGGER, + WarmRun.JSON_PROPERTY_VANTAGE_POINTS +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WarmRun { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_DEPLOYMENT = "deployment"; + @jakarta.annotation.Nullable + private Deployment deployment; + + public static final String JSON_PROPERTY_ERROR_CODE = "error_code"; + @jakarta.annotation.Nullable + private String errorCode; + + public static final String JSON_PROPERTY_FINISHED_AT = "finished_at"; + @jakarta.annotation.Nullable + private OffsetDateTime finishedAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nonnull + private EffectiveRunOptions options; + + public static final String JSON_PROPERTY_OUTCOME = "outcome"; + @jakarta.annotation.Nullable + private Outcome outcome; + + public static final String JSON_PROPERTY_SITE_ID = "site_id"; + @jakarta.annotation.Nonnull + private String siteId; + + public static final String JSON_PROPERTY_SOURCE = "source"; + @jakarta.annotation.Nullable + private RunSource source; + + public static final String JSON_PROPERTY_STARTED_AT = "started_at"; + @jakarta.annotation.Nullable + private OffsetDateTime startedAt; + + public static final String JSON_PROPERTY_STATUS = "status"; + @jakarta.annotation.Nonnull + private RunStatus status; + + public static final String JSON_PROPERTY_TRIGGER = "trigger"; + @jakarta.annotation.Nonnull + private Trigger trigger; + + public static final String JSON_PROPERTY_VANTAGE_POINTS = "vantage_points"; + @jakarta.annotation.Nonnull + private List vantagePoints = new ArrayList<>(); + + public WarmRun() { + } + + public WarmRun createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public WarmRun deployment(@jakarta.annotation.Nullable Deployment deployment) { + this.deployment = deployment; + return this; + } + + /** + * Get deployment + * @return deployment + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DEPLOYMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Deployment getDeployment() { + return deployment; + } + + + @JsonProperty(value = JSON_PROPERTY_DEPLOYMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDeployment(@jakarta.annotation.Nullable Deployment deployment) { + this.deployment = deployment; + } + + + public WarmRun errorCode(@jakarta.annotation.Nullable String errorCode) { + this.errorCode = errorCode; + return this; + } + + /** + * A short code when `status` is `failed`; null otherwise. + * @return errorCode + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getErrorCode() { + return errorCode; + } + + + @JsonProperty(value = JSON_PROPERTY_ERROR_CODE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setErrorCode(@jakarta.annotation.Nullable String errorCode) { + this.errorCode = errorCode; + } + + + public WarmRun finishedAt(@jakarta.annotation.Nullable OffsetDateTime finishedAt) { + this.finishedAt = finishedAt; + return this; + } + + /** + * Get finishedAt + * @return finishedAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_FINISHED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getFinishedAt() { + return finishedAt; + } + + + @JsonProperty(value = JSON_PROPERTY_FINISHED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFinishedAt(@jakarta.annotation.Nullable OffsetDateTime finishedAt) { + this.finishedAt = finishedAt; + } + + + public WarmRun id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public WarmRun options(@jakarta.annotation.Nonnull EffectiveRunOptions options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public EffectiveRunOptions getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOptions(@jakarta.annotation.Nonnull EffectiveRunOptions options) { + this.options = options; + } + + + public WarmRun outcome(@jakarta.annotation.Nullable Outcome outcome) { + this.outcome = outcome; + return this; + } + + /** + * Null until the run is `completed`. + * @return outcome + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OUTCOME, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Outcome getOutcome() { + return outcome; + } + + + @JsonProperty(value = JSON_PROPERTY_OUTCOME, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOutcome(@jakarta.annotation.Nullable Outcome outcome) { + this.outcome = outcome; + } + + + public WarmRun siteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + return this; + } + + /** + * Get siteId + * @return siteId + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSiteId() { + return siteId; + } + + + @JsonProperty(value = JSON_PROPERTY_SITE_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSiteId(@jakarta.annotation.Nonnull String siteId) { + this.siteId = siteId; + } + + + public WarmRun source(@jakarta.annotation.Nullable RunSource source) { + this.source = source; + return this; + } + + /** + * Get source + * @return source + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RunSource getSource() { + return source; + } + + + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSource(@jakarta.annotation.Nullable RunSource source) { + this.source = source; + } + + + public WarmRun startedAt(@jakarta.annotation.Nullable OffsetDateTime startedAt) { + this.startedAt = startedAt; + return this; + } + + /** + * Get startedAt + * @return startedAt + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_STARTED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OffsetDateTime getStartedAt() { + return startedAt; + } + + + @JsonProperty(value = JSON_PROPERTY_STARTED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setStartedAt(@jakarta.annotation.Nullable OffsetDateTime startedAt) { + this.startedAt = startedAt; + } + + + public WarmRun status(@jakarta.annotation.Nonnull RunStatus status) { + this.status = status; + return this; + } + + /** + * Get status + * @return status + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public RunStatus getStatus() { + return status; + } + + + @JsonProperty(value = JSON_PROPERTY_STATUS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setStatus(@jakarta.annotation.Nonnull RunStatus status) { + this.status = status; + } + + + public WarmRun trigger(@jakarta.annotation.Nonnull Trigger trigger) { + this.trigger = trigger; + return this; + } + + /** + * Get trigger + * @return trigger + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_TRIGGER, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Trigger getTrigger() { + return trigger; + } + + + @JsonProperty(value = JSON_PROPERTY_TRIGGER, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTrigger(@jakarta.annotation.Nonnull Trigger trigger) { + this.trigger = trigger; + } + + + public WarmRun vantagePoints(@jakarta.annotation.Nonnull List vantagePoints) { + this.vantagePoints = vantagePoints; + return this; + } + + public WarmRun addVantagePointsItem(VantagePointSummary vantagePointsItem) { + if (this.vantagePoints == null) { + this.vantagePoints = new ArrayList<>(); + } + this.vantagePoints.add(vantagePointsItem); + return this; + } + + /** + * Get vantagePoints + * @return vantagePoints + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getVantagePoints() { + return vantagePoints; + } + + + @JsonProperty(value = JSON_PROPERTY_VANTAGE_POINTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setVantagePoints(@jakarta.annotation.Nonnull List vantagePoints) { + this.vantagePoints = vantagePoints; + } + + + /** + * Return true if this WarmRun object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WarmRun warmRun = (WarmRun) o; + return Objects.equals(this.createdAt, warmRun.createdAt) && + Objects.equals(this.deployment, warmRun.deployment) && + Objects.equals(this.errorCode, warmRun.errorCode) && + Objects.equals(this.finishedAt, warmRun.finishedAt) && + Objects.equals(this.id, warmRun.id) && + Objects.equals(this.options, warmRun.options) && + Objects.equals(this.outcome, warmRun.outcome) && + Objects.equals(this.siteId, warmRun.siteId) && + Objects.equals(this.source, warmRun.source) && + Objects.equals(this.startedAt, warmRun.startedAt) && + Objects.equals(this.status, warmRun.status) && + Objects.equals(this.trigger, warmRun.trigger) && + Objects.equals(this.vantagePoints, warmRun.vantagePoints); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, deployment, errorCode, finishedAt, id, options, outcome, siteId, source, startedAt, status, trigger, vantagePoints); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WarmRun {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" deployment: ").append(toIndentedString(deployment)).append("\n"); + sb.append(" errorCode: ").append(toIndentedString(errorCode)).append("\n"); + sb.append(" finishedAt: ").append(toIndentedString(finishedAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append(" outcome: ").append(toIndentedString(outcome)).append("\n"); + sb.append(" siteId: ").append(toIndentedString(siteId)).append("\n"); + sb.append(" source: ").append(toIndentedString(source)).append("\n"); + sb.append(" startedAt: ").append(toIndentedString(startedAt)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" trigger: ").append(toIndentedString(trigger)).append("\n"); + sb.append(" vantagePoints: ").append(toIndentedString(vantagePoints)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `deployment` to the URL query string + if (getDeployment() != null) { + joiner.add(getDeployment().toUrlQueryString(prefix + "deployment" + suffix)); + } + + // add `error_code` to the URL query string + if (getErrorCode() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%serror_code%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getErrorCode())))); + } + + // add `finished_at` to the URL query string + if (getFinishedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sfinished_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getFinishedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%soptions%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getOptions())))); + } + + // add `outcome` to the URL query string + if (getOutcome() != null) { + joiner.add(getOutcome().toUrlQueryString(prefix + "outcome" + suffix)); + } + + // add `site_id` to the URL query string + if (getSiteId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssite_id%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSiteId())))); + } + + // add `source` to the URL query string + if (getSource() != null) { + joiner.add(getSource().toUrlQueryString(prefix + "source" + suffix)); + } + + // add `started_at` to the URL query string + if (getStartedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sstarted_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getStartedAt())))); + } + + // add `status` to the URL query string + if (getStatus() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sstatus%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getStatus())))); + } + + // add `trigger` to the URL query string + if (getTrigger() != null) { + joiner.add(getTrigger().toUrlQueryString(prefix + "trigger" + suffix)); + } + + // add `vantage_points` to the URL query string + if (getVantagePoints() != null) { + for (int i = 0; i < getVantagePoints().size(); i++) { + if (getVantagePoints().get(i) != null) { + joiner.add(getVantagePoints().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%svantage_points%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WarmRunCanceledEvent.java b/src/main/java/com/sitewarm/sdk/model/WarmRunCanceledEvent.java new file mode 100644 index 0000000..0750194 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WarmRunCanceledEvent.java @@ -0,0 +1,258 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.WarmRun; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WarmRunCanceledEvent + */ +@JsonPropertyOrder({ + WarmRunCanceledEvent.JSON_PROPERTY_CREATED_AT, + WarmRunCanceledEvent.JSON_PROPERTY_ID, + WarmRunCanceledEvent.JSON_PROPERTY_TYPE, + WarmRunCanceledEvent.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WarmRunCanceledEvent { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nullable + private Object type = null; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private WarmRun data; + + public WarmRunCanceledEvent() { + } + + public WarmRunCanceledEvent createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public WarmRunCanceledEvent id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Unique per event. A redelivery of the same event keeps the id; use it to deduplicate. + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public WarmRunCanceledEvent type(@jakarta.annotation.Nullable Object type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Object getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nullable Object type) { + this.type = type; + } + + + public WarmRunCanceledEvent data(@jakarta.annotation.Nonnull WarmRun data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public WarmRun getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull WarmRun data) { + this.data = data; + } + + + /** + * Return true if this WarmRunCanceledEvent object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WarmRunCanceledEvent warmRunCanceledEvent = (WarmRunCanceledEvent) o; + return Objects.equals(this.createdAt, warmRunCanceledEvent.createdAt) && + Objects.equals(this.id, warmRunCanceledEvent.id) && + Objects.equals(this.type, warmRunCanceledEvent.type) && + Objects.equals(this.data, warmRunCanceledEvent.data); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, type, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WarmRunCanceledEvent {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WarmRunCompletedEvent.java b/src/main/java/com/sitewarm/sdk/model/WarmRunCompletedEvent.java new file mode 100644 index 0000000..0290486 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WarmRunCompletedEvent.java @@ -0,0 +1,258 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.WarmRun; +import java.time.OffsetDateTime; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WarmRunCompletedEvent + */ +@JsonPropertyOrder({ + WarmRunCompletedEvent.JSON_PROPERTY_CREATED_AT, + WarmRunCompletedEvent.JSON_PROPERTY_ID, + WarmRunCompletedEvent.JSON_PROPERTY_TYPE, + WarmRunCompletedEvent.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WarmRunCompletedEvent { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_TYPE = "type"; + @jakarta.annotation.Nullable + private Object type = null; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private WarmRun data; + + public WarmRunCompletedEvent() { + } + + public WarmRunCompletedEvent createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public WarmRunCompletedEvent id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Unique per event. A redelivery of the same event keeps the id; use it to deduplicate. + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public WarmRunCompletedEvent type(@jakarta.annotation.Nullable Object type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Object getType() { + return type; + } + + + @JsonProperty(value = JSON_PROPERTY_TYPE, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(@jakarta.annotation.Nullable Object type) { + this.type = type; + } + + + public WarmRunCompletedEvent data(@jakarta.annotation.Nonnull WarmRun data) { + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public WarmRun getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull WarmRun data) { + this.data = data; + } + + + /** + * Return true if this WarmRunCompletedEvent object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WarmRunCompletedEvent warmRunCompletedEvent = (WarmRunCompletedEvent) o; + return Objects.equals(this.createdAt, warmRunCompletedEvent.createdAt) && + Objects.equals(this.id, warmRunCompletedEvent.id) && + Objects.equals(this.type, warmRunCompletedEvent.type) && + Objects.equals(this.data, warmRunCompletedEvent.data); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, id, type, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WarmRunCompletedEvent {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `type` to the URL query string + if (getType() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%stype%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getType())))); + } + + // add `data` to the URL query string + if (getData() != null) { + joiner.add(getData().toUrlQueryString(prefix + "data" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WarmRunCreate.java b/src/main/java/com/sitewarm/sdk/model/WarmRunCreate.java new file mode 100644 index 0000000..b7aa78b --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WarmRunCreate.java @@ -0,0 +1,223 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.Deployment; +import com.sitewarm.sdk.model.RunOptions; +import com.sitewarm.sdk.model.RunSource; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WarmRunCreate + */ +@JsonPropertyOrder({ + WarmRunCreate.JSON_PROPERTY_DEPLOYMENT, + WarmRunCreate.JSON_PROPERTY_OPTIONS, + WarmRunCreate.JSON_PROPERTY_SOURCE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WarmRunCreate { + public static final String JSON_PROPERTY_DEPLOYMENT = "deployment"; + @jakarta.annotation.Nullable + private Deployment deployment; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + @jakarta.annotation.Nullable + private RunOptions options; + + public static final String JSON_PROPERTY_SOURCE = "source"; + @jakarta.annotation.Nullable + private RunSource source; + + public WarmRunCreate() { + } + + public WarmRunCreate deployment(@jakarta.annotation.Nullable Deployment deployment) { + this.deployment = deployment; + return this; + } + + /** + * Get deployment + * @return deployment + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DEPLOYMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Deployment getDeployment() { + return deployment; + } + + + @JsonProperty(value = JSON_PROPERTY_DEPLOYMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDeployment(@jakarta.annotation.Nullable Deployment deployment) { + this.deployment = deployment; + } + + + public WarmRunCreate options(@jakarta.annotation.Nullable RunOptions options) { + this.options = options; + return this; + } + + /** + * Get options + * @return options + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RunOptions getOptions() { + return options; + } + + + @JsonProperty(value = JSON_PROPERTY_OPTIONS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(@jakarta.annotation.Nullable RunOptions options) { + this.options = options; + } + + + public WarmRunCreate source(@jakarta.annotation.Nullable RunSource source) { + this.source = source; + return this; + } + + /** + * Get source + * @return source + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public RunSource getSource() { + return source; + } + + + @JsonProperty(value = JSON_PROPERTY_SOURCE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSource(@jakarta.annotation.Nullable RunSource source) { + this.source = source; + } + + + /** + * Return true if this WarmRunCreate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WarmRunCreate warmRunCreate = (WarmRunCreate) o; + return Objects.equals(this.deployment, warmRunCreate.deployment) && + Objects.equals(this.options, warmRunCreate.options) && + Objects.equals(this.source, warmRunCreate.source); + } + + @Override + public int hashCode() { + return Objects.hash(deployment, options, source); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WarmRunCreate {\n"); + sb.append(" deployment: ").append(toIndentedString(deployment)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append(" source: ").append(toIndentedString(source)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `deployment` to the URL query string + if (getDeployment() != null) { + joiner.add(getDeployment().toUrlQueryString(prefix + "deployment" + suffix)); + } + + // add `options` to the URL query string + if (getOptions() != null) { + joiner.add(getOptions().toUrlQueryString(prefix + "options" + suffix)); + } + + // add `source` to the URL query string + if (getSource() != null) { + joiner.add(getSource().toUrlQueryString(prefix + "source" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WarmRunList.java b/src/main/java/com/sitewarm/sdk/model/WarmRunList.java new file mode 100644 index 0000000..5c9ef02 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WarmRunList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.PageInfo; +import com.sitewarm.sdk.model.WarmRun; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WarmRunList + */ +@JsonPropertyOrder({ + WarmRunList.JSON_PROPERTY_DATA, + WarmRunList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WarmRunList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public WarmRunList() { + } + + public WarmRunList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public WarmRunList addDataItem(WarmRun dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public WarmRunList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this WarmRunList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WarmRunList warmRunList = (WarmRunList) o; + return Objects.equals(this.data, warmRunList.data) && + Objects.equals(this.page, warmRunList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WarmRunList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/Webhook.java b/src/main/java/com/sitewarm/sdk/model/Webhook.java new file mode 100644 index 0000000..44781a0 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/Webhook.java @@ -0,0 +1,347 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.EventType; +import java.net.URI; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * Webhook + */ +@JsonPropertyOrder({ + Webhook.JSON_PROPERTY_CREATED_AT, + Webhook.JSON_PROPERTY_DESCRIPTION, + Webhook.JSON_PROPERTY_ENABLED, + Webhook.JSON_PROPERTY_EVENTS, + Webhook.JSON_PROPERTY_ID, + Webhook.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Webhook { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_DESCRIPTION = "description"; + @jakarta.annotation.Nullable + private String description; + + public static final String JSON_PROPERTY_ENABLED = "enabled"; + @jakarta.annotation.Nonnull + private Boolean enabled; + + public static final String JSON_PROPERTY_EVENTS = "events"; + @jakarta.annotation.Nonnull + private List events = new ArrayList<>(); + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private URI url; + + public Webhook() { + } + + public Webhook createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public Webhook description(@jakarta.annotation.Nullable String description) { + this.description = description; + return this; + } + + /** + * Get description + * @return description + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getDescription() { + return description; + } + + + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDescription(@jakarta.annotation.Nullable String description) { + this.description = description; + } + + + public Webhook enabled(@jakarta.annotation.Nonnull Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Get enabled + * @return enabled + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getEnabled() { + return enabled; + } + + + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEnabled(@jakarta.annotation.Nonnull Boolean enabled) { + this.enabled = enabled; + } + + + public Webhook events(@jakarta.annotation.Nonnull List events) { + this.events = events; + return this; + } + + public Webhook addEventsItem(EventType eventsItem) { + if (this.events == null) { + this.events = new ArrayList<>(); + } + this.events.add(eventsItem); + return this; + } + + /** + * Get events + * @return events + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getEvents() { + return events; + } + + + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEvents(@jakarta.annotation.Nonnull List events) { + this.events = events; + } + + + public Webhook id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public Webhook url(@jakarta.annotation.Nonnull URI url) { + this.url = url; + return this; + } + + /** + * HTTPS endpoint that receives deliveries. + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public URI getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull URI url) { + this.url = url; + } + + + /** + * Return true if this Webhook object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Webhook webhook = (Webhook) o; + return Objects.equals(this.createdAt, webhook.createdAt) && + Objects.equals(this.description, webhook.description) && + Objects.equals(this.enabled, webhook.enabled) && + Objects.equals(this.events, webhook.events) && + Objects.equals(this.id, webhook.id) && + Objects.equals(this.url, webhook.url); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, description, enabled, events, id, url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Webhook {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" events: ").append(toIndentedString(events)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `description` to the URL query string + if (getDescription() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdescription%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDescription())))); + } + + // add `enabled` to the URL query string + if (getEnabled() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senabled%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnabled())))); + } + + // add `events` to the URL query string + if (getEvents() != null) { + for (int i = 0; i < getEvents().size(); i++) { + if (getEvents().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sevents%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getEvents().get(i))))); + } + } + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `url` to the URL query string + if (getUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrl())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WebhookCreate.java b/src/main/java/com/sitewarm/sdk/model/WebhookCreate.java new file mode 100644 index 0000000..74f93de --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WebhookCreate.java @@ -0,0 +1,274 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.EventType; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WebhookCreate + */ +@JsonPropertyOrder({ + WebhookCreate.JSON_PROPERTY_DESCRIPTION, + WebhookCreate.JSON_PROPERTY_ENABLED, + WebhookCreate.JSON_PROPERTY_EVENTS, + WebhookCreate.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WebhookCreate { + public static final String JSON_PROPERTY_DESCRIPTION = "description"; + @jakarta.annotation.Nullable + private String description; + + public static final String JSON_PROPERTY_ENABLED = "enabled"; + @jakarta.annotation.Nullable + private Boolean enabled; + + public static final String JSON_PROPERTY_EVENTS = "events"; + @jakarta.annotation.Nonnull + private List events = new ArrayList<>(); + + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private URI url; + + public WebhookCreate() { + } + + public WebhookCreate description(@jakarta.annotation.Nullable String description) { + this.description = description; + return this; + } + + /** + * Get description + * @return description + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getDescription() { + return description; + } + + + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDescription(@jakarta.annotation.Nullable String description) { + this.description = description; + } + + + public WebhookCreate enabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Get enabled + * @return enabled + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getEnabled() { + return enabled; + } + + + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setEnabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + } + + + public WebhookCreate events(@jakarta.annotation.Nonnull List events) { + this.events = events; + return this; + } + + public WebhookCreate addEventsItem(EventType eventsItem) { + if (this.events == null) { + this.events = new ArrayList<>(); + } + this.events.add(eventsItem); + return this; + } + + /** + * Get events + * @return events + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getEvents() { + return events; + } + + + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEvents(@jakarta.annotation.Nonnull List events) { + this.events = events; + } + + + public WebhookCreate url(@jakarta.annotation.Nonnull URI url) { + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public URI getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull URI url) { + this.url = url; + } + + + /** + * Return true if this WebhookCreate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WebhookCreate webhookCreate = (WebhookCreate) o; + return Objects.equals(this.description, webhookCreate.description) && + Objects.equals(this.enabled, webhookCreate.enabled) && + Objects.equals(this.events, webhookCreate.events) && + Objects.equals(this.url, webhookCreate.url); + } + + @Override + public int hashCode() { + return Objects.hash(description, enabled, events, url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WebhookCreate {\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" events: ").append(toIndentedString(events)).append("\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `description` to the URL query string + if (getDescription() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdescription%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDescription())))); + } + + // add `enabled` to the URL query string + if (getEnabled() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senabled%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnabled())))); + } + + // add `events` to the URL query string + if (getEvents() != null) { + for (int i = 0; i < getEvents().size(); i++) { + if (getEvents().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sevents%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getEvents().get(i))))); + } + } + } + + // add `url` to the URL query string + if (getUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrl())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WebhookList.java b/src/main/java/com/sitewarm/sdk/model/WebhookList.java new file mode 100644 index 0000000..0c33710 --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WebhookList.java @@ -0,0 +1,201 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.PageInfo; +import com.sitewarm.sdk.model.Webhook; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WebhookList + */ +@JsonPropertyOrder({ + WebhookList.JSON_PROPERTY_DATA, + WebhookList.JSON_PROPERTY_PAGE +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WebhookList { + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data = new ArrayList<>(); + + public static final String JSON_PROPERTY_PAGE = "page"; + @jakarta.annotation.Nonnull + private PageInfo page; + + public WebhookList() { + } + + public WebhookList data(@jakarta.annotation.Nonnull List data) { + this.data = data; + return this; + } + + public WebhookList addDataItem(Webhook dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + public WebhookList page(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + return this; + } + + /** + * Get page + * @return page + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public PageInfo getPage() { + return page; + } + + + @JsonProperty(value = JSON_PROPERTY_PAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPage(@jakarta.annotation.Nonnull PageInfo page) { + this.page = page; + } + + + /** + * Return true if this WebhookList object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WebhookList webhookList = (WebhookList) o; + return Objects.equals(this.data, webhookList.data) && + Objects.equals(this.page, webhookList.page); + } + + @Override + public int hashCode() { + return Objects.hash(data, page); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WebhookList {\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `data` to the URL query string + if (getData() != null) { + for (int i = 0; i < getData().size(); i++) { + if (getData().get(i) != null) { + joiner.add(getData().get(i).toUrlQueryString(String.format(java.util.Locale.ROOT, "%sdata%s%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + // add `page` to the URL query string + if (getPage() != null) { + joiner.add(getPage().toUrlQueryString(prefix + "page" + suffix)); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WebhookUpdate.java b/src/main/java/com/sitewarm/sdk/model/WebhookUpdate.java new file mode 100644 index 0000000..e7a713b --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WebhookUpdate.java @@ -0,0 +1,274 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.EventType; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WebhookUpdate + */ +@JsonPropertyOrder({ + WebhookUpdate.JSON_PROPERTY_DESCRIPTION, + WebhookUpdate.JSON_PROPERTY_ENABLED, + WebhookUpdate.JSON_PROPERTY_EVENTS, + WebhookUpdate.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WebhookUpdate { + public static final String JSON_PROPERTY_DESCRIPTION = "description"; + @jakarta.annotation.Nullable + private String description; + + public static final String JSON_PROPERTY_ENABLED = "enabled"; + @jakarta.annotation.Nullable + private Boolean enabled; + + public static final String JSON_PROPERTY_EVENTS = "events"; + @jakarta.annotation.Nullable + private List events = new ArrayList<>(); + + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nullable + private URI url; + + public WebhookUpdate() { + } + + public WebhookUpdate description(@jakarta.annotation.Nullable String description) { + this.description = description; + return this; + } + + /** + * Get description + * @return description + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getDescription() { + return description; + } + + + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDescription(@jakarta.annotation.Nullable String description) { + this.description = description; + } + + + public WebhookUpdate enabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Get enabled + * @return enabled + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getEnabled() { + return enabled; + } + + + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setEnabled(@jakarta.annotation.Nullable Boolean enabled) { + this.enabled = enabled; + } + + + public WebhookUpdate events(@jakarta.annotation.Nullable List events) { + this.events = events; + return this; + } + + public WebhookUpdate addEventsItem(EventType eventsItem) { + if (this.events == null) { + this.events = new ArrayList<>(); + } + this.events.add(eventsItem); + return this; + } + + /** + * Get events + * @return events + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getEvents() { + return events; + } + + + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setEvents(@jakarta.annotation.Nullable List events) { + this.events = events; + } + + + public WebhookUpdate url(@jakarta.annotation.Nullable URI url) { + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_URL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public URI getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUrl(@jakarta.annotation.Nullable URI url) { + this.url = url; + } + + + /** + * Return true if this WebhookUpdate object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WebhookUpdate webhookUpdate = (WebhookUpdate) o; + return Objects.equals(this.description, webhookUpdate.description) && + Objects.equals(this.enabled, webhookUpdate.enabled) && + Objects.equals(this.events, webhookUpdate.events) && + Objects.equals(this.url, webhookUpdate.url); + } + + @Override + public int hashCode() { + return Objects.hash(description, enabled, events, url); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WebhookUpdate {\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" events: ").append(toIndentedString(events)).append("\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `description` to the URL query string + if (getDescription() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdescription%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDescription())))); + } + + // add `enabled` to the URL query string + if (getEnabled() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senabled%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnabled())))); + } + + // add `events` to the URL query string + if (getEvents() != null) { + for (int i = 0; i < getEvents().size(); i++) { + if (getEvents().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sevents%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getEvents().get(i))))); + } + } + } + + // add `url` to the URL query string + if (getUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrl())))); + } + + return joiner.toString(); + } +} + diff --git a/src/main/java/com/sitewarm/sdk/model/WebhookWithSecret.java b/src/main/java/com/sitewarm/sdk/model/WebhookWithSecret.java new file mode 100644 index 0000000..d286e9d --- /dev/null +++ b/src/main/java/com/sitewarm/sdk/model/WebhookWithSecret.java @@ -0,0 +1,383 @@ +/* + * sitewarm public API + * This document is the source of truth for the public REST API; the server, the SDKs and the contract tests are built from it. ## Vocabulary A **site** is one hostname. A **vantage point** is the place a run's requests are sent from (`region` is an attribute of it). The **cache status** of a URL is one of the normalized states in `CacheState`; `GET` results also carry the raw CDN header value untouched in `cdn_cache_header`. Indexability is a separate field, never a cache state. ## Conventions - **Versioning.** The base path is `/v1`. Breaking changes need a new major path. - **Authentication.** Every operation takes a scoped API key as a bearer token (`Authorization: Bearer `). Session cookies are never accepted. Each operation lists the scope it needs. A request for a resource of another organization returns `404`, not `403`. - **Idempotency.** Send `Idempotency-Key` on `POST`. Repeating a request with the same key and the same body returns the first response and sets `Idempotent-Replayed: true`. The same key with a different body is a `409` problem of type `idempotency-key-reused`. The warm-run trigger requires the header; the other `POST` operations accept it. - **Pagination.** Lists use opaque cursors: pass `cursor` from `page.next_cursor` of the previous page. Clients must not parse cursors. - **Errors.** Every error is `application/problem+json` as in RFC 9457. The `type` member is a URI reference naming one of the problem types listed in `ProblemType`. - **Rate limits.** Every response except `500` carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. A `429` also carries `Retry-After`. - **Async work.** Starting a warm run answers `202 Accepted` with a `Location` header pointing at the warm-run resource, which is the status resource to poll. Cancelling is also asynchronous. - **Webhooks.** Events are delivered with an HMAC-SHA256 signature, see the `webhooks` section. - **Time and ids.** Timestamps are RFC 3339 UTC. Ids are opaque strings. Durations are strings such as `10s` or `5m`, as in the CLI. - **Sensitive data.** The API never returns `Cookie`, `Set-Cookie` or `Authorization` values from a customer site, and never accepts them. Header names such as `Cache-Control`, `Age` and `Vary` are returned as observed. - **Safety.** A site must be verified before any run. Triggering a run for an unverified or paused site is rejected with a problem. + * + * The version of the OpenAPI document: 0.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.sitewarm.sdk.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.sitewarm.sdk.model.EventType; +import java.net.URI; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.sitewarm.sdk.ApiClient; +/** + * WebhookWithSecret + */ +@JsonPropertyOrder({ + WebhookWithSecret.JSON_PROPERTY_CREATED_AT, + WebhookWithSecret.JSON_PROPERTY_DESCRIPTION, + WebhookWithSecret.JSON_PROPERTY_ENABLED, + WebhookWithSecret.JSON_PROPERTY_EVENTS, + WebhookWithSecret.JSON_PROPERTY_ID, + WebhookWithSecret.JSON_PROPERTY_URL, + WebhookWithSecret.JSON_PROPERTY_SECRET +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class WebhookWithSecret { + public static final String JSON_PROPERTY_CREATED_AT = "created_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime createdAt; + + public static final String JSON_PROPERTY_DESCRIPTION = "description"; + @jakarta.annotation.Nullable + private String description; + + public static final String JSON_PROPERTY_ENABLED = "enabled"; + @jakarta.annotation.Nonnull + private Boolean enabled; + + public static final String JSON_PROPERTY_EVENTS = "events"; + @jakarta.annotation.Nonnull + private List events = new ArrayList<>(); + + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private String id; + + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private URI url; + + public static final String JSON_PROPERTY_SECRET = "secret"; + @jakarta.annotation.Nonnull + private String secret; + + public WebhookWithSecret() { + } + + public WebhookWithSecret createdAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCreatedAt(@jakarta.annotation.Nonnull OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + + public WebhookWithSecret description(@jakarta.annotation.Nullable String description) { + this.description = description; + return this; + } + + /** + * Get description + * @return description + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getDescription() { + return description; + } + + + @JsonProperty(value = JSON_PROPERTY_DESCRIPTION, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDescription(@jakarta.annotation.Nullable String description) { + this.description = description; + } + + + public WebhookWithSecret enabled(@jakarta.annotation.Nonnull Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Get enabled + * @return enabled + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Boolean getEnabled() { + return enabled; + } + + + @JsonProperty(value = JSON_PROPERTY_ENABLED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEnabled(@jakarta.annotation.Nonnull Boolean enabled) { + this.enabled = enabled; + } + + + public WebhookWithSecret events(@jakarta.annotation.Nonnull List events) { + this.events = events; + return this; + } + + public WebhookWithSecret addEventsItem(EventType eventsItem) { + if (this.events == null) { + this.events = new ArrayList<>(); + } + this.events.add(eventsItem); + return this; + } + + /** + * Get events + * @return events + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getEvents() { + return events; + } + + + @JsonProperty(value = JSON_PROPERTY_EVENTS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEvents(@jakarta.annotation.Nonnull List events) { + this.events = events; + } + + + public WebhookWithSecret id(@jakarta.annotation.Nonnull String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull String id) { + this.id = id; + } + + + public WebhookWithSecret url(@jakarta.annotation.Nonnull URI url) { + this.url = url; + return this; + } + + /** + * HTTPS endpoint that receives deliveries. + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public URI getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull URI url) { + this.url = url; + } + + + public WebhookWithSecret secret(@jakarta.annotation.Nonnull String secret) { + this.secret = secret; + return this; + } + + /** + * HMAC signing secret. Shown only in this response. + * @return secret + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SECRET, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSecret() { + return secret; + } + + + @JsonProperty(value = JSON_PROPERTY_SECRET, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSecret(@jakarta.annotation.Nonnull String secret) { + this.secret = secret; + } + + + /** + * Return true if this WebhookWithSecret object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WebhookWithSecret webhookWithSecret = (WebhookWithSecret) o; + return Objects.equals(this.createdAt, webhookWithSecret.createdAt) && + Objects.equals(this.description, webhookWithSecret.description) && + Objects.equals(this.enabled, webhookWithSecret.enabled) && + Objects.equals(this.events, webhookWithSecret.events) && + Objects.equals(this.id, webhookWithSecret.id) && + Objects.equals(this.url, webhookWithSecret.url) && + Objects.equals(this.secret, webhookWithSecret.secret); + } + + @Override + public int hashCode() { + return Objects.hash(createdAt, description, enabled, events, id, url, secret); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class WebhookWithSecret {\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" events: ").append(toIndentedString(events)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append(" secret: ").append(toIndentedString(secret)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `created_at` to the URL query string + if (getCreatedAt() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%screated_at%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getCreatedAt())))); + } + + // add `description` to the URL query string + if (getDescription() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sdescription%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getDescription())))); + } + + // add `enabled` to the URL query string + if (getEnabled() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%senabled%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getEnabled())))); + } + + // add `events` to the URL query string + if (getEvents() != null) { + for (int i = 0; i < getEvents().size(); i++) { + if (getEvents().get(i) != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sevents%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getEvents().get(i))))); + } + } + } + + // add `id` to the URL query string + if (getId() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%sid%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getId())))); + } + + // add `url` to the URL query string + if (getUrl() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%surl%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getUrl())))); + } + + // add `secret` to the URL query string + if (getSecret() != null) { + joiner.add(String.format(java.util.Locale.ROOT, "%ssecret%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getSecret())))); + } + + return joiner.toString(); + } +} + diff --git a/src/test/java/com/sitewarm/sdk/HardeningTest.java b/src/test/java/com/sitewarm/sdk/HardeningTest.java new file mode 100644 index 0000000..c8bbc0c --- /dev/null +++ b/src/test/java/com/sitewarm/sdk/HardeningTest.java @@ -0,0 +1,210 @@ +package com.sitewarm.sdk; + +import static org.junit.jupiter.api.Assertions.*; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class HardeningTest { + static final String KEY = "swk_secret_key"; + + interface Handler { + void handle(HttpExchange ex, int n) throws IOException; + } + + HttpServer server; + final AtomicInteger calls = new AtomicInteger(); + + SiteWarm client(Handler h, Consumer cfg) throws IOException { + server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0); + server.createContext("/", ex -> { + try { + h.handle(ex, calls.incrementAndGet()); + } finally { + try { + ex.close(); + } catch (RuntimeException ignored) { + // a deliberately short body makes close() complain + } + } + }); + server.start(); + SiteWarm.Builder b = SiteWarm.builder(KEY, "http://127.0.0.1:" + server.getAddress().getPort() + "/v1") + .retryDelays(Duration.ZERO, Duration.ZERO).sleeper(d -> { }); + cfg.accept(b); + return b.build(); + } + + SiteWarm client(Handler h) throws IOException { + return client(h, b -> { }); + } + + static void reply(HttpExchange ex, int status, String body) throws IOException { + byte[] b = body.getBytes(StandardCharsets.UTF_8); + ex.getResponseHeaders().add("Content-Type", "application/json"); + ex.sendResponseHeaders(status, b.length == 0 ? -1 : b.length); + if (b.length > 0) ex.getResponseBody().write(b); + } + + /** Promises 100 bytes, sends 5 and drops the connection. */ + static void broken(HttpExchange ex, int status) throws IOException { + ex.sendResponseHeaders(status, 100); + ex.getResponseBody().write("{\"id\"".getBytes(StandardCharsets.UTF_8)); + ex.getResponseBody().flush(); + throw new IOException("drop"); // the wrapper closes the exchange with fewer bytes than promised + } + + @AfterEach + void stop() { + if (server != null) server.stop(0); + } + + static Request site() { + return Request.of().withPath("siteId", "s1"); + } + + @Test + void nonPositiveTimeoutAndNegativeRetriesKeepDefaults() throws Exception { + for (Duration d : new Duration[] {Duration.ZERO, Duration.ofSeconds(-1), null}) { + SiteWarm c = client((ex, n) -> reply(ex, 200, "{\"id\":\"s1\"}"), b -> b.timeout(d)); + assertEquals("s1", c.call("getSite", site()).get("id").asText()); // a zero timeout would throw + stop(); + } + calls.set(0); + SiteWarm c = client((ex, n) -> reply(ex, 503, "{}"), b -> b.maxRetries(-1)); + assertThrows(SiteWarmException.Api.class, () -> c.call("getSite", site())); + assertEquals(4, calls.get()); // default of 3 retries + } + + @Test + void bodyReadErrorIsRetriedOnRepeatableCalls() throws Exception { + SiteWarm c = client((ex, n) -> { + if (n == 1) broken(ex, 200); + else reply(ex, 200, "{\"id\":\"s1\"}"); + }); + assertEquals("s1", c.call("getSite", site()).get("id").asText()); + assertEquals(2, calls.get()); + } + + @Test + void bodyReadErrorOnDeleteIsNotRetried() throws Exception { + SiteWarm c = client((ex, n) -> broken(ex, 200), b -> b.maxRetries(2)); + assertThrows(SiteWarmException.Connection.class, () -> c.call("deleteSite", site())); + assertEquals(1, calls.get()); + } + + @Test + void bodyReadErrorAfter429IsRetriedForAnyMethod() throws Exception { + SiteWarm c = client((ex, n) -> { + if (n == 1) broken(ex, 429); + else reply(ex, 200, "{}"); + }); + c.call("deleteSite", site()); + assertEquals(2, calls.get()); + } + + @Test + void oversizedBodyIsTypedAndNotRetried() throws Exception { + SiteWarm c = client((ex, n) -> { + ex.sendResponseHeaders(200, 0); // chunked + byte[] chunk = new byte[1 << 20]; + try { + for (int i = 0; i < 40; i++) ex.getResponseBody().write(chunk); + } catch (IOException closedByClient) { + // expected: the SDK stops reading + } + }); + assertThrows(SiteWarmException.ResponseTooLarge.class, () -> c.call("getSite", site())); + assertEquals(1, calls.get()); + } + + @Test + void readLimitedAllowsExactlyTheLimit() throws Exception { + assertEquals(10, SiteWarm.readLimited(new java.io.ByteArrayInputStream(new byte[10]), 10).length); + assertThrows(SiteWarmException.ResponseTooLarge.class, + () -> SiteWarm.readLimited(new java.io.ByteArrayInputStream(new byte[11]), 10)); + } + + @Test + void onlyRepeatableMethodsRetryServerErrors() throws Exception { + record Case(String op, Request req, int want) { } + List cases = List.of( + new Case("getSite", site(), 3), + new Case("replaceUrlSet", site().withPath("urlSetId", "u1"), 3), + new Case("deleteSite", site(), 1), + new Case("updateSite", site(), 1)); + for (Case cs : cases) { + calls.set(0); + SiteWarm c = client((ex, n) -> reply(ex, 503, "{}"), b -> b.maxRetries(2)); + assertThrows(SiteWarmException.Api.class, () -> c.call(cs.op(), cs.req()), cs.op()); + assertEquals(cs.want(), calls.get(), cs.op()); + stop(); + } + // 429 is retried for every method + calls.set(0); + SiteWarm c = client((ex, n) -> { + ex.getResponseHeaders().add("Retry-After", "0"); + if (n < 3) reply(ex, 429, "{}"); + else reply(ex, 200, "{}"); + }); + c.call("deleteSite", site()); + assertEquals(3, calls.get()); + } + + @Test + void paginationErrorsOnRepeatedCursorAndAtPageCap() throws Exception { + SiteWarm cyc = client((ex, n) -> { + String q = ex.getRequestURI().getQuery(); + String next = q != null && q.contains("cursor=b") ? "a" : "b"; + reply(ex, 200, "{\"data\":[{\"id\":\"x\"}],\"page\":{\"has_more\":true,\"next_cursor\":\"" + next + "\"}}"); + }); + var e = assertThrows(SiteWarmException.class, () -> cyc.sites.all().forEach(s -> { })); + assertTrue(e.getMessage().contains("did not advance")); + stop(); + + calls.set(0); + SiteWarm endless = client((ex, n) -> reply(ex, 200, + "{\"data\":[],\"page\":{\"has_more\":true,\"next_cursor\":\"c" + n + "\"}}")); + var cap = assertThrows(SiteWarmException.class, + () -> endless.items("listSites", Request.of(), com.sitewarm.sdk.model.Site.class, 5).forEach(s -> { })); + assertTrue(cap.getMessage().contains("stopped after 5 pages")); + assertEquals(5, calls.get()); + } + + @Test + void listLimitIsValidatedBeforeSending() throws Exception { + List queries = new ArrayList<>(); + SiteWarm c = client((ex, n) -> { + queries.add(String.valueOf(ex.getRequestURI().getQuery())); + reply(ex, 200, "{\"data\":[],\"page\":{\"has_more\":false}}"); + }); + for (String bad : new String[] {"-1", "101", "x", "1.5"}) { + assertThrows(SiteWarmException.class, () -> c.call("listSites", Request.of().withQuery("limit", bad)), bad); + } + assertEquals(0, calls.get()); + for (String ok : new String[] {"1", "100", "0", ""}) c.call("listSites", Request.of().withQuery("limit", ok)); + assertEquals(List.of("limit=1", "limit=100", "null", "null"), queries); + } + + @Test + void keyIsNotInToStringOrErrors() throws Exception { + SiteWarm c = client((ex, n) -> reply(ex, 401, "{\"title\":\"T\"}"), b -> b.maxRetries(0)); + assertFalse(c.toString().contains(KEY)); + assertFalse(c.sites.toString().contains(KEY)); + assertFalse(c.warmRuns.toString().contains(KEY)); + assertFalse(SiteWarm.builder(KEY, "https://x.test/v1").toString().contains(KEY)); + var e = assertThrows(SiteWarmException.Api.class, () -> c.call("getSite", site())); + assertFalse(e.toString().contains(KEY)); + assertFalse(java.io.Serializable.class.isAssignableFrom(SiteWarm.class), "client must not be serializable"); + } +} diff --git a/src/test/java/com/sitewarm/sdk/LowsTest.java b/src/test/java/com/sitewarm/sdk/LowsTest.java new file mode 100644 index 0000000..50477a1 --- /dev/null +++ b/src/test/java/com/sitewarm/sdk/LowsTest.java @@ -0,0 +1,182 @@ +package com.sitewarm.sdk; + +import static org.junit.jupiter.api.Assertions.*; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class LowsTest { + static final String KEY = "swk_secret_key"; + + interface Handler { + void handle(HttpExchange ex, int n) throws IOException; + } + + HttpServer server; + final AtomicInteger calls = new AtomicInteger(); + final List pauses = new ArrayList<>(); + final List userAgents = new ArrayList<>(); + + SiteWarm.Builder builder(Handler h) throws IOException { + server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0); + server.createContext("/", ex -> { + try { + userAgents.add(ex.getRequestHeaders().getFirst("User-Agent")); + h.handle(ex, calls.incrementAndGet()); + } finally { + ex.close(); + } + }); + server.start(); + return SiteWarm.builder(KEY, "http://127.0.0.1:" + server.getAddress().getPort() + "/v1") + .retryDelays(Duration.ZERO, Duration.ZERO).sleeper(pauses::add); + } + + @AfterEach + void stop() { + if (server != null) server.stop(0); + } + + static void reply(HttpExchange ex, int status, String body, String... headers) throws IOException { + byte[] b = body.getBytes(StandardCharsets.UTF_8); + ex.getResponseHeaders().add("Content-Type", "application/json"); + for (int i = 0; i < headers.length; i += 2) ex.getResponseHeaders().add(headers[i], headers[i + 1]); + ex.sendResponseHeaders(status, b.length == 0 ? -1 : b.length); + if (b.length > 0) ex.getResponseBody().write(b); + } + + static Request site() { + return Request.of().withPath("siteId", "s1"); + } + + static String problem(String slug) { + return "{\"type\":\"https://x.test/problems/" + slug + "\",\"title\":\"c\",\"status\":409}"; + } + + @Test + void conflictOnKeyedPostIsRetriedButKeyReusedIsNot() throws Exception { + for (String[] c : new String[][] {{"conflict", "3"}, {"idempotency-key-reused", "1"}}) { + calls.set(0); + SiteWarm sw = builder((ex, n) -> reply(ex, 409, problem(c[0]))).maxRetries(2).build(); + SiteWarmException.Api e = assertThrows(SiteWarmException.Api.class, + () -> sw.call("createSite", Request.of().withBody(java.util.Map.of("hostname", "example.com")))); + assertEquals(c[0], e.code()); + assertEquals(Integer.parseInt(c[1]), calls.get(), c[0]); + stop(); + } + } + + @Test + void conflictOnUnkeyedOperationIsNotRetried() throws Exception { + SiteWarm sw = builder((ex, n) -> reply(ex, 409, problem("conflict"))).maxRetries(2).build(); + assertThrows(SiteWarmException.Api.class, () -> sw.call("deleteSite", site())); + assertEquals(1, calls.get()); + } + + @Test + void networkErrorClasses() { + assertFalse(SiteWarm.isTransient(new java.net.UnknownHostException("nope.invalid"))); + assertFalse(SiteWarm.isTransient(new java.net.ConnectException("x") {{ initCause(new java.nio.channels.UnresolvedAddressException()); }})); + javax.net.ssl.SSLHandshakeException hs = new javax.net.ssl.SSLHandshakeException("handshake failed"); + hs.initCause(new java.security.cert.CertificateException("PKIX path building failed")); + assertFalse(SiteWarm.isTransient(hs)); + assertFalse(SiteWarm.isTransient(new IOException("x", new java.security.cert.CertPathValidatorException("bad")))); + assertFalse(SiteWarm.isTransient(new javax.net.ssl.SSLPeerUnverifiedException("hostname mismatch"))); + assertFalse(SiteWarm.isTransient(new IOException("invalid header field"))); + assertTrue(SiteWarm.isTransient(new IOException("Connection reset"))); + assertTrue(SiteWarm.isTransient(new java.net.ConnectException("refused"))); + } + + @Test + void unknownHostIsNotRetriedButRefusedConnectionIs() throws Exception { + SiteWarm bad = SiteWarm.builder(KEY, "https://nonexistent.invalid/v1").maxRetries(2) + .retryDelays(Duration.ZERO, Duration.ZERO).sleeper(pauses::add).build(); + assertThrows(SiteWarmException.Connection.class, () -> bad.call("getSite", site())); + assertTrue(pauses.isEmpty(), "unknown host was retried"); + + int port; + try (var s = new java.net.ServerSocket(0)) { + port = s.getLocalPort(); + } + SiteWarm refused = SiteWarm.builder(KEY, "http://127.0.0.1:" + port + "/v1").maxRetries(2) + .retryDelays(Duration.ZERO, Duration.ZERO).sleeper(pauses::add).build(); + assertThrows(SiteWarmException.Connection.class, () -> refused.call("getSite", site())); + assertEquals(2, pauses.size()); + } + + @Test + void retryAfterZeroWaitsTheBaseWithJitter() throws Exception { + SiteWarm sw = builder((ex, n) -> { + if (n == 1) reply(ex, 429, "{}", "Retry-After", "0"); + else reply(ex, 200, "{\"id\":\"s1\"}"); + }).retryDelays(Duration.ofMillis(200), Duration.ofSeconds(5)).build(); + sw.call("getSite", site()); + assertEquals(1, pauses.size()); + long ms = pauses.get(0).toMillis(); + assertTrue(ms >= 200 && ms <= 250, "waited " + ms); + } + + @Test + void pastHttpDateIsFlooredToo() throws Exception { + SiteWarm sw = builder((ex, n) -> { + if (n == 1) reply(ex, 429, "{}", "Retry-After", "Mon, 01 Jan 2001 00:00:00 GMT"); + else reply(ex, 200, "{\"id\":\"s1\"}"); + }).retryDelays(Duration.ofMillis(200), Duration.ofSeconds(5)).build(); + sw.call("getSite", site()); + assertTrue(pauses.get(0).toMillis() >= 200); + } + + @Test + void retryAfterAboveTheCapIsSurfacedNotSlept() throws Exception { + SiteWarm sw = builder((ex, n) -> reply(ex, 429, "{}", "Retry-After", "60")) + .retryDelays(Duration.ofMillis(200), Duration.ofSeconds(5)).build(); + SiteWarmException.Api e = assertThrows(SiteWarmException.Api.class, () -> sw.call("getSite", site())); + assertEquals(Duration.ofSeconds(60), e.retryAfter()); + assertEquals(1, calls.get()); + assertTrue(pauses.isEmpty()); + } + + @Test + void nonJsonSuccessIsATypedDecodeError() throws Exception { + SiteWarm sw = builder((ex, n) -> reply(ex, 200, "secret-proxy-page")).build(); + SiteWarmException.Decode e = assertThrows(SiteWarmException.Decode.class, () -> sw.call("getSite", site())); + assertEquals(200, e.status()); + assertFalse(e.getMessage().contains("secret-proxy-page")); + assertNull(e.getCause()); + assertInstanceOf(SiteWarmException.class, e); + } + + @Test + void userAgentCarriesVersionAndUrlAndEmptyKeepsTheDefault() throws Exception { + String def = "sitewarm-java/" + SiteWarm.VERSION + " (+https://github.com/sitewarm/sdk-java)"; + builder((ex, n) -> reply(ex, 200, "{\"id\":\"s1\"}")).build().call("getSite", site()); + stop(); + builder((ex, n) -> reply(ex, 200, "{\"id\":\"s1\"}")).userAgent("").build().call("getSite", site()); + stop(); + builder((ex, n) -> reply(ex, 200, "{\"id\":\"s1\"}")).userAgent("mine/1").build().call("getSite", site()); + assertEquals(List.of(def, def, "mine/1"), userAgents); + } + + @Test + void versionConstantMatchesThePom() throws Exception { + String pom = Files.readString(Path.of("pom.xml")); + assertTrue(pom.contains("sitewarm-sdk\n " + SiteWarm.VERSION + "")); + } + + @Test + void basePathKeepsPercentEncoding() throws Exception { + SiteWarm sw = SiteWarm.builder(KEY, "https://x.test/a%2Fb/v1").build(); + assertTrue(sw.toString().contains("https://x.test/a%2Fb/v1")); + } +} diff --git a/src/test/java/com/sitewarm/sdk/SiteWarmTest.java b/src/test/java/com/sitewarm/sdk/SiteWarmTest.java new file mode 100644 index 0000000..db852ae --- /dev/null +++ b/src/test/java/com/sitewarm/sdk/SiteWarmTest.java @@ -0,0 +1,225 @@ +package com.sitewarm.sdk; + +import static org.junit.jupiter.api.Assertions.*; + +import com.fasterxml.jackson.databind.JsonNode; +import com.sitewarm.sdk.model.WarmRunCreate; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class SiteWarmTest { + static final String KEY = "swk_secret_key"; + + interface Handler { + void handle(HttpExchange ex, int n) throws IOException; + } + + HttpServer server; + final AtomicInteger calls = new AtomicInteger(); + final List seen = new CopyOnWriteArrayList<>(); + final List idemKeys = new CopyOnWriteArrayList<>(); + + SiteWarm client(Handler h, Consumer cfg) throws IOException { + server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0); + server.createContext("/", ex -> { + seen.add(ex); + idemKeys.add(String.valueOf(ex.getRequestHeaders().getFirst("Idempotency-Key"))); + h.handle(ex, calls.incrementAndGet()); + ex.close(); + }); + server.start(); + SiteWarm.Builder b = SiteWarm.builder(KEY, "http://127.0.0.1:" + server.getAddress().getPort() + "/v1") + .retryDelays(Duration.ZERO, Duration.ZERO).sleeper(d -> { }); + cfg.accept(b); + return b.build(); + } + + SiteWarm client(Handler h) throws IOException { + return client(h, b -> { }); + } + + static void reply(HttpExchange ex, int status, String body, String... headers) throws IOException { + for (int i = 0; i + 1 < headers.length; i += 2) ex.getResponseHeaders().add(headers[i], headers[i + 1]); + byte[] b = body.getBytes(StandardCharsets.UTF_8); + ex.getResponseHeaders().add("Content-Type", "application/json"); + ex.sendResponseHeaders(status, b.length == 0 ? -1 : b.length); + if (b.length > 0) ex.getResponseBody().write(b); + } + + @AfterEach + void stop() { + if (server != null) server.stop(0); + } + + @Test + void requestShapeAndAuth() throws Exception { + SiteWarm c = client((ex, n) -> reply(ex, 200, "{\"id\":\"s1\"}")); + JsonNode r = c.call("getSite", Request.of().withPath("siteId", "a/b")); + assertEquals("s1", r.get("id").asText()); + assertEquals("/v1/sites/a%2Fb", seen.get(0).getRequestURI().getRawPath()); + assertEquals("Bearer " + KEY, seen.get(0).getRequestHeaders().getFirst("Authorization")); + } + + @Test + void problemBecomesTypedErrorWithoutKey() throws Exception { + Object[][] cases = {{401, SiteWarmException.Api.Kind.AUTHENTICATION}, {403, SiteWarmException.Api.Kind.PERMISSION}, + {404, SiteWarmException.Api.Kind.NOT_FOUND}, {409, SiteWarmException.Api.Kind.CONFLICT}, + {422, SiteWarmException.Api.Kind.VALIDATION}, {429, SiteWarmException.Api.Kind.RATE_LIMITED}, + {500, SiteWarmException.Api.Kind.SERVER}}; + for (Object[] cs : cases) { + int status = (Integer) cs[0]; + SiteWarm c = client((ex, n) -> reply(ex, status, + "{\"type\":\"https://x.test/problems/some-slug\",\"title\":\"T\",\"detail\":\"D\"}", + "Retry-After", "0", "RateLimit-Remaining", "0"), b -> b.maxRetries(0)); + var e = assertThrows(SiteWarmException.Api.class, () -> c.call("getSite", Request.of().withPath("siteId", "s1"))); + assertEquals(cs[1], e.kind()); + assertEquals(status, e.status()); + assertEquals("some-slug", e.code()); + assertEquals(0, e.rateLimitRemaining().getAsInt()); + assertFalse(e.getMessage().contains(KEY)); + stop(); + } + } + + @Test + void retries429ThenSucceeds() throws Exception { + SiteWarm c = client((ex, n) -> { + if (n < 3) reply(ex, 429, "{}", "Retry-After", "0"); + else reply(ex, 200, "{\"id\":\"s1\"}"); + }); + c.call("getSite", Request.of().withPath("siteId", "s1")); + assertEquals(3, calls.get()); + } + + @Test + void retryAfterBeyondCapIsSurfaced() throws Exception { + SiteWarm c = client((ex, n) -> reply(ex, 429, "{}", "Retry-After", "120"), + b -> b.retryDelays(Duration.ZERO, Duration.ofSeconds(5))); + var e = assertThrows(SiteWarmException.Api.class, () -> c.call("getSite", Request.of().withPath("siteId", "s1"))); + assertEquals(1, calls.get()); + assertEquals(Duration.ofSeconds(120), e.retryAfter()); + } + + @Test + void keyedPostIsRetriedWithOneKey() throws Exception { + SiteWarm c = client((ex, n) -> reply(ex, 503, "{}"), b -> b.maxRetries(2)); + assertThrows(SiteWarmException.Api.class, () -> c.warmRuns.create("s1", new WarmRunCreate())); + assertEquals(3, calls.get()); + assertEquals(1, new java.util.HashSet<>(idemKeys).size()); + assertNotEquals("null", idemKeys.get(0)); + java.util.UUID.fromString(idemKeys.get(0)); + } + + @Test + void givenIdempotencyKeyIsSent() throws Exception { + SiteWarm c = client((ex, n) -> reply(ex, 202, "{\"id\":\"run1\"}")); + c.call("createWarmRun", Request.of().withPath("siteId", "s1").withBody(new WarmRunCreate()).withIdempotencyKey("mine")); + assertEquals("mine", idemKeys.get(0)); + } + + @Test + void redirectsAreNotFollowed() throws Exception { + SiteWarm c = client((ex, n) -> { + ex.getResponseHeaders().add("Location", "http://127.0.0.1:1/elsewhere"); + ex.sendResponseHeaders(302, -1); + }, b -> b.maxRetries(0)); + var e = assertThrows(SiteWarmException.Api.class, () -> c.call("getSite", Request.of().withPath("siteId", "s1"))); + assertEquals(302, e.status()); + } + + @Test + void connectionErrorHasNoKeyOrCause() { + SiteWarm c = SiteWarm.builder(KEY, "http://127.0.0.1:1/v1").maxRetries(0).build(); + var e = assertThrows(SiteWarmException.Connection.class, () -> c.call("getSite", Request.of().withPath("siteId", "s1"))); + assertFalse(e.getMessage().contains(KEY)); + assertNull(e.getCause()); + } + + @Test + void paginationFollowsCursorAndDetectsStall() throws Exception { + SiteWarm c = client((ex, n) -> { + if (ex.getRequestURI().getQuery() == null) { + reply(ex, 200, "{\"data\":[{\"id\":\"a\"},{\"id\":\"b\"}],\"page\":{\"has_more\":true,\"next_cursor\":\"c1\"}}"); + } else { + reply(ex, 200, "{\"data\":[{\"id\":\"c\"}],\"page\":{\"has_more\":false,\"next_cursor\":null}}"); + } + }); + List ids = new ArrayList<>(); + for (var s : c.sites.all()) ids.add(s.getId()); + assertEquals(List.of("a", "b", "c"), ids); + stop(); + + SiteWarm stuck = client((ex, n) -> reply(ex, 200, + "{\"data\":[{\"id\":\"a\"}],\"page\":{\"has_more\":true,\"next_cursor\":\"c1\"}}")); + var ex = assertThrows(SiteWarmException.class, () -> stuck.sites.all().forEach(s -> { })); + assertTrue(ex.getMessage().contains("did not advance")); + } + + @Test + void waitPollsUntilTerminalAndTimesOutWithoutCancel() throws Exception { + String[] statuses = {"queued", "running", "completed"}; + SiteWarm c = client((ex, n) -> reply(ex, 200, + "{\"id\":\"r1\",\"site_id\":\"s\",\"status\":\"" + statuses[Math.min(n, 3) - 1] + "\"}", "Retry-After", "0")); + var run = c.warmRuns.waitFor("r1", Duration.ofMinutes(1), Duration.ofSeconds(1)); + assertEquals("completed", String.valueOf(run.getStatus())); + stop(); + + List methods = new CopyOnWriteArrayList<>(); + SiteWarm never = client((ex, n) -> { + methods.add(ex.getRequestMethod()); + reply(ex, 200, "{\"id\":\"r1\",\"status\":\"running\"}"); + }); + assertThrows(SiteWarmException.WaitTimeout.class, () -> never.warmRuns.waitFor("r1", Duration.ofMillis(20), Duration.ofMillis(1))); + assertTrue(methods.stream().allMatch("GET"::equals)); + } + + @Test + void validation() { + for (String u : new String[] {"http://api.example.test/v1", "https://u:p@api.example.test", "https://x.test/v1?a=1", "api.example.test", ""}) { + assertThrows(SiteWarmException.class, () -> SiteWarm.builder(KEY, u), u); + } + assertDoesNotThrow(() -> SiteWarm.builder(KEY, "http://localhost:8080/v1")); + for (String k : new String[] {"", "has space", "tab\t"}) { + var e = assertThrows(SiteWarmException.class, () -> SiteWarm.builder(k, "https://x.test/v1")); + assertFalse(!k.isEmpty() && e.getMessage().contains(k)); + } + assertFalse(SiteWarm.builder(KEY, "https://x.test/v1").build().toString().contains(KEY)); + } + + @Test + void unknownOperationAndMissingPathParam() throws Exception { + SiteWarm c = client((ex, n) -> reply(ex, 200, "{}")); + assertTrue(assertThrows(SiteWarmException.class, () -> c.call("nope", Request.of())).getMessage().contains("unknown operation")); + assertTrue(assertThrows(SiteWarmException.class, () -> c.call("getSite", Request.of())).getMessage().contains("missing path parameter")); + } + + @Test + void operationTableMatchesSpec() throws Exception { + assertEquals(36, Operations.TABLE.size()); + assertEquals(Operation.Idempotency.REQUIRED, Operations.TABLE.get("createWarmRun").idempotency()); + assertEquals(Operation.Idempotency.NONE, Operations.TABLE.get("getWarmRun").idempotency()); + String spec = Files.readString(Path.of("openapi/openapi.yaml")); + assertFalse(spec.contains("x-open-question")); + for (var e : Operations.TABLE.entrySet()) assertTrue(spec.contains("operationId: " + e.getKey()), e.getKey()); + } + + @Test + void retryAfterParsing() { + assertEquals(Duration.ofSeconds(7), SiteWarm.parseRetryAfter("7")); + assertNull(SiteWarm.parseRetryAfter("garbage")); + assertNull(SiteWarm.parseRetryAfter(null)); + } +}