From 51620c35c10cfe120e3412acb95441b92c89e991 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Wed, 20 Mar 2024 13:27:28 -0400 Subject: [PATCH] ci(schema): enable and check in graphql schema --- .github/workflows/pr-ci.yaml | 56 +++---- schema/schema.graphql | 295 +++++++++++++++++++++++++++++++++++ schema/update.bash | 2 +- 3 files changed, 324 insertions(+), 29 deletions(-) create mode 100644 schema/schema.graphql diff --git a/.github/workflows/pr-ci.yaml b/.github/workflows/pr-ci.yaml index 1c573f57e..3e2dbbc3c 100644 --- a/.github/workflows/pr-ci.yaml +++ b/.github/workflows/pr-ci.yaml @@ -189,8 +189,8 @@ jobs: outputs: OPENAPI_STATUS: ${{ steps.schema-update.outputs.openapi_status }} OPENAPI_DIFF_FILE: ${{ steps.schema-update.outputs.openapi_diff_file }} - # GRAPHQL_STATUS: ${{ steps.schema-update.outputs.graphql_status }} - # GRAPHQL_DIFF_FILE: ${{ steps.schema-update.outputs.graphql_diff_file }} + GRAPHQL_STATUS: ${{ steps.schema-update.outputs.graphql_status }} + GRAPHQL_DIFF_FILE: ${{ steps.schema-update.outputs.graphql_diff_file }} steps: - uses: actions/checkout@v3 with: @@ -231,9 +231,9 @@ jobs: git diff -U10 --exit-code /home/runner/work/cryostat3/cryostat3/schema/openapi.yaml > /home/runner/work/openapi.diff echo "openapi_status=$?" >> "$GITHUB_OUTPUT" echo "openapi_diff_file=openapi.diff" >> "$GITHUB_OUTPUT" - # git diff -U10 --exit-code /home/runner/work/cryostat3/cryostat3/schema/schema.graphql > /home/runner/work/graphql.diff - # echo "graphql_status=$?" >> "$GITHUB_OUTPUT" - # echo "graphql_diff_file=graphql.diff" >> "$GITHUB_OUTPUT" + git diff -U10 --exit-code /home/runner/work/cryostat3/cryostat3/schema/schema.graphql > /home/runner/work/graphql.diff + echo "graphql_status=$?" >> "$GITHUB_OUTPUT" + echo "graphql_diff_file=graphql.diff" >> "$GITHUB_OUTPUT" - uses: actions/upload-artifact@v3 with: name: openapi-diff @@ -267,26 +267,26 @@ jobs: body: commentBody }); - # compare-graphql-schema: - # needs: [update-schemas] - # runs-on: ubuntu-latest - # steps: - # - uses: actions/download-artifact@v3 - # with: - # name: graphql-diff - # - name: Comment schema check result - # uses: actions/github-script@v6 - # with: - # script: | - # const diffFmt = s => { - # return "```diff\n" + s + "\n```"; - # }; - # const commentBody = ${{ needs.update-schemas.outputs.GRAPHQL_STATUS }} == '0' - # ? `No GraphQL schema changes detected.` - # : `GraphQL schema change detected:\n\n${diffFmt(require('fs').readFileSync('${{ needs.update-schemas.outputs.GRAPHQL_DIFF_FILE }}'))}`; - # github.rest.issues.createComment({ - # issue_number: context.issue.number, - # owner: context.repo.owner, - # repo: context.repo.repo, - # body: commentBody - # }); + compare-graphql-schema: + needs: [update-schemas] + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v3 + with: + name: graphql-diff + - name: Comment schema check result + uses: actions/github-script@v6 + with: + script: | + const diffFmt = s => { + return "```diff\n" + s + "\n```"; + }; + const commentBody = ${{ needs.update-schemas.outputs.GRAPHQL_STATUS }} == '0' + ? `No GraphQL schema changes detected.` + : `GraphQL schema change detected:\n\n${diffFmt(require('fs').readFileSync('${{ needs.update-schemas.outputs.GRAPHQL_DIFF_FILE }}'))}`; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); diff --git a/schema/schema.graphql b/schema/schema.graphql new file mode 100644 index 000000000..2a6b75444 --- /dev/null +++ b/schema/schema.graphql @@ -0,0 +1,295 @@ +type ActiveRecording { + continuous: Boolean! + "Archive the specified Flight Recording" + doArchive: ArchivedRecording + "Delete the specified Flight Recording" + doDelete: ActiveRecording + "Stop the specified Flight Recording" + doStop: ActiveRecording + "URL for GET request to retrieve the JFR binary file content of this recording" + downloadUrl: String + duration: BigInteger! + id: BigInteger + maxAge: BigInteger! + maxSize: BigInteger! + metadata: Metadata! + name: String! + remoteId: BigInteger! + "URL for GET request to retrieve a JSON formatted Automated Analysis Report of this recording" + reportUrl: String + startTime: BigInteger! + state: RecordingState! + target: Target! + toDisk: Boolean! +} + +type ActiveRecordings { + aggregate: AggregateInfo! + data: [ActiveRecording]! +} + +type AggregateInfo { + "The number of elements in this collection" + count: BigInteger! + "The sum of sizes of elements in this collection, or 0 if not applicable" + size: BigInteger! +} + +type Annotations { + cryostat( + "Get entry/entries for a certain key/s" + key: [String] + ): [Entry_String_String] + platform( + "Get entry/entries for a certain key/s" + key: [String] + ): [Entry_String_String] +} + +type ArchivedRecording { + archivedTime: BigInteger! + "URL for GET request to retrieve the JFR binary file content of this recording" + downloadUrl: String + metadata: Metadata + name: String + "URL for GET request to retrieve a JSON formatted Automated Analysis Report of this recording" + reportUrl: String + size: BigInteger! +} + +type ArchivedRecordings { + aggregate: AggregateInfo! + data: [ArchivedRecording]! +} + +type DiscoveryNode { + children: [DiscoveryNode] + "Get target nodes that are descendants of this node. That is, get the set of leaf nodes from anywhere below this node's subtree." + descendantTargets(filter: DiscoveryNodeFilterInput): [DiscoveryNode] + id: BigInteger + labels( + "Get entry/entries for a certain key/s" + key: [String] + ): [Entry_String_String]! + name: String! + nodeType: String! + target: Target +} + +type Entry_String_String { + key: String + value: String +} + +type MBeanMetrics { + jvmId: String + memory: MemoryMetrics + os: OperatingSystemMetrics + runtime: RuntimeMetrics + thread: ThreadMetrics +} + +type MemoryMetrics { + freeHeapMemory: BigInteger! + freeNonHeapMemory: BigInteger! + heapMemoryUsage: MemoryUtilization + heapMemoryUsagePercent: Float! + nonHeapMemoryUsage: MemoryUtilization + objectPendingFinalizationCount: BigInteger! + verbose: Boolean! +} + +type MemoryUtilization { + committed: BigInteger! + init: BigInteger! + max: BigInteger! + used: BigInteger! +} + +type Metadata { + "ISO-8601" + expiry: DateTime + labels( + "Get entry/entries for a certain key/s" + key: [String] + ): [Entry_String_String] +} + +"Mutation root" +type Mutation { + "Archive an existing Flight Recording matching the given filter, on all Targets under the subtrees of the discovery nodes matching the given filter" + archiveRecording(nodes: DiscoveryNodeFilterInput!, recordings: ActiveRecordingsFilterInput): [ArchivedRecording] + "Start a new Flight Recording on all Targets under the subtrees of the discovery nodes matching the given filter" + createRecording(nodes: DiscoveryNodeFilterInput!, recording: RecordingSettingsInput!): [ActiveRecording] + "Create a Flight Recorder Snapshot on all Targets under the subtrees of the discovery nodes matching the given filter" + createSnapshot(nodes: DiscoveryNodeFilterInput!): [ActiveRecording] + "Delete an existing Flight Recording matching the given filter, on all Targets under the subtrees of the discovery nodes matching the given filter" + deleteRecording(nodes: DiscoveryNodeFilterInput!, recordings: ActiveRecordingsFilterInput): [ActiveRecording] + "Stop an existing Flight Recording matching the given filter, on all Targets under the subtrees of the discovery nodes matching the given filter" + stopRecording(nodes: DiscoveryNodeFilterInput!, recordings: ActiveRecordingsFilterInput): [ActiveRecording] +} + +type OperatingSystemMetrics { + arch: String + availableProcessors: Int! + committedVirtualMemorySize: BigInteger! + freePhysicalMemorySize: BigInteger! + freeSwapSpaceSize: BigInteger! + name: String + processCpuLoad: Float! + processCpuTime: BigInteger! + systemCpuLoad: Float! + systemLoadAverage: Float! + totalPhysicalMemorySize: BigInteger! + totalSwapSpaceSize: BigInteger! + version: String +} + +"Query root" +type Query { + archivedRecordings(filter: ArchivedRecordingsFilterInput): ArchivedRecordings + "Get all environment nodes in the discovery tree with optional filtering" + environmentNodes(filter: DiscoveryNodeFilterInput): [DiscoveryNode] + "Get the root target discovery node" + rootNode: DiscoveryNode + "Get the Target discovery nodes, i.e. the leaf nodes of the discovery tree" + targetNodes(filter: DiscoveryNodeFilterInput): [DiscoveryNode] +} + +type Recordings { + active(filter: ActiveRecordingsFilterInput): ActiveRecordings + archived(filter: ArchivedRecordingsFilterInput): ArchivedRecordings +} + +type RuntimeMetrics { + bootClassPath: String + bootClassPathSupported: Boolean! + classPath: String + inputArguments: [String] + libraryPath: String + managementSpecVersion: String + name: String + specName: String + specVendor: String + specVersion: String + startTime: BigInteger! + systemProperties( + "Get entry/entries for a certain key/s" + key: [String] + ): [Entry_String_String] + uptime: BigInteger! + vmName: String + vmVendor: String + vmVersion: String +} + +type Target { + activeRecordings(filter: ActiveRecordingsFilterInput): ActiveRecordings + agent: Boolean! + alias: String! + annotations: Annotations! + archivedRecordings(filter: ArchivedRecordingsFilterInput): ArchivedRecordings + connectUrl: String! + "Create a new Flight Recorder Snapshot on the specified Target" + doSnapshot: ActiveRecording + "Start a new Flight Recording on the specified Target" + doStartRecording(recording: RecordingSettingsInput!): ActiveRecording + id: BigInteger + jvmId: String + labels( + "Get entry/entries for a certain key/s" + key: [String] + ): [Entry_String_String]! + "Get live MBean metrics snapshot from the specified Target" + mbeanMetrics: MBeanMetrics + "Get the active and archived recordings belonging to this target" + recordings: Recordings +} + +type ThreadMetrics { + allThreadIds: [BigInteger] + currentThreadCpuTime: BigInteger! + currentThreadCpuTimeSupported: Boolean! + currentThreadUserTime: BigInteger! + daemonThreadCount: Int! + objectMonitorUsageSupported: Boolean! + peakThreadCount: Int! + synchronizerUsageSupported: Boolean! + threadContentionMonitoringEnabled: Boolean! + threadContentionMonitoringSupported: Boolean! + threadCount: Int! + threadCpuTimeEnabled: Boolean! + threadCpuTimeSupported: Boolean! + totalStartedThreadCount: BigInteger! +} + +"Running state of an active Flight Recording" +enum RecordingState { + "CLOSED" + CLOSED + "DELAYED" + DELAYED + "NEW" + NEW + "RUNNING" + RUNNING + "STOPPED" + STOPPED +} + +input ActiveRecordingsFilterInput { + continuous: Boolean + durationMsGreaterThanEqual: BigInteger + durationMsLessThanEqual: BigInteger + labels: [String] + name: String + names: [String] + startTimeMsAfterEqual: BigInteger + startTimeMsBeforeEqual: BigInteger + state: RecordingState + toDisk: Boolean +} + +input ArchivedRecordingsFilterInput { + archivedTimeAfterEqual: BigInteger + archivedTimeBeforeEqual: BigInteger + labels: [String] + name: String + names: [String] + sizeBytesGreaterThanEqual: BigInteger + sizeBytesLessThanEqual: BigInteger + sourceTarget: String +} + +input DiscoveryNodeFilterInput { + annotations: [String] + id: BigInteger + ids: [BigInteger] + labels: [String] + name: String + names: [String] + nodeTypes: [String] +} + +input Entry_String_StringInput { + key: String + value: String +} + +input RecordingMetadataInput { + labels: [Entry_String_StringInput] +} + +input RecordingSettingsInput { + archiveOnStop: Boolean + continuous: Boolean + duration: BigInteger + maxAge: BigInteger + maxSize: BigInteger + metadata: RecordingMetadataInput + name: String! + replace: String + template: String! + templateType: String! + toDisk: Boolean +} diff --git a/schema/update.bash b/schema/update.bash index 07d109017..6ace30cca 100755 --- a/schema/update.bash +++ b/schema/update.bash @@ -24,4 +24,4 @@ while true; do fi done wget http://localhost:8181/api -O - | yq -P 'sort_keys(..)' > "${DIR}/openapi.yaml" -# wget http://localhost:8181/api/v3/graphql/schema.graphql -O "${DIR}/schema.graphql" +wget http://localhost:8181/api/v3/graphql/schema.graphql -O "${DIR}/schema.graphql"