API Reference
Common API Use Cases
- When the facts are infrequently updated, or they are sporadic in nature you can use the Facts API to submit them when they change (event based). This can help reduce the amount of calls that soundcheck is making to fetch certain facts.
- When check rules are hard to set up, or you already have a system that calculates them you can submit the result straight to the Check Results API.
- When you want to prevent releasing a component that is not meeting your standards. You can set up your CI/CD pipeline to rerun checks and get entity certification level before allowing release.
Checks API
Use the Checks API to:
- List all checks
- Get a check by id
- Execute a check against one more entities.
Each API call is discussed in detail below.
NOTE: Your environment may not have checks specified in the app-config.yaml file. Here is a sample configuration with two checks defined. The first is checking a fact collected by the SCM plugin for the existence of a README.md file at the root level of a repository. The second analyzes the metadata returned by the catalog fact collector for the existence of either an internal or external metadata tag.
soundcheck:
checks:
- id: has_required_tags
rule:
any:
- factRef: catalog:default/entity_descriptor
path: $.metadata.tags
operator: contains
value: internal
- factRef: catalog:default/entity_descriptor
path: $.metadata.tags
operator: contains
value: external
passedMessage: |
Tag found, check passed.
failedMessage: |
No `internal` or `external` tag found, check failed.
- id: has_readme
rule:
factRef: scm:default/readme
path: $.exists
operator: equal
value: true
passedMessage: |
README.md was found at repository root, check passed.
failedMessage: |
README.md was not found at repository root, check failed.
The existence of these checks is assumed when executing API calls in the rest of this Checks API section.
Get a List of Checks
The endpoint to get a list of checks is at /api/soundcheck/checks. For a local deployment, the call would look like this:
GET localhost:7007/api/soundcheck/checks
With the above check defined, hitting the /checks endpoint will yield the following output:
{
"checks": [
{
"id": "has_required_tags",
"rule": {
"any": [
{
"factRef": "catalog:default/entity_descriptor",
"operator": "contains",
"value": "internal",
"path": "$.metadata.tags"
},
{
"factRef": "catalog:default/entity_descriptor",
"operator": "contains",
"value": "external",
"path": "$.metadata.tags"
}
]
},
"passedMessage": "Tag found, check passed.\n",
"failedMessage": "No `internal` or `external` tag found, check failed.\n"
},
{
"id": "has_readme",
"rule": {
"factRef": "scm:default/readme",
"operator": "equal",
"value": true,
"path": "$.exists"
},
"passedMessage": "README.md was found at repository root, check passed.\n",
"failedMessage": "README.md was not found at repository root, check failed.\n"
}
]
}
Get a Check by ID
The endpoint to get a single check by ID is at /api/soundcheck/checks/:checkId. For a local deployment, the call would look like this:
GET localhost:7007/api/soundcheck/checks/has_readme
where 'has_readme' above is the check id, which was defined at the beginning of this section.
Executing the call above results in the following output:
{
"check": {
"id": "has_readme",
"rule": {
"factRef": "scm:default/readme",
"operator": "equal",
"value": true,
"path": "$.exists"
},
"passedMessage": "README.md was found at repository root, check passed.\n",
"failedMessage": "README.md was not found at repository root, check failed.\n"
}
}
Trigger a Set of Checks to Execute
This endpoint allows for a set of checks to be executed in soundcheck. To execute a set of checks, POST to:
POST localhost:7007/api/soundcheck/checks/execute
The POST request takes a json request body composed of one of four sets of parameters as follows:
1.) An array of checkIds
and an array of entityRefs
:
{
"entityRefs": ["component:default/queue-proxy", "component:default/searcher"],
"checkIds": ["has_required_tags", "has_readme"]
}
POSTing the above request results in output like the following:
{
"results": [
{
"entityRef": "component:default/queue-proxy",
"timestamp": "2023-02-15T19:33:15.945Z",
"checkId": "has_required_tags",
"state": "failed",
"details": {
"notes": {
"type": "notes",
"data": "No `internal` or `external` tag found, check failed.\n"
}
}
},
{
"entityRef": "component:default/searcher",
"timestamp": "2023-02-15T19:33:15.945Z",
"checkId": "has_required_tags",
"state": "failed",
"details": {
"notes": {
"type": "notes",
"data": "No `internal` or `external` tag found, check failed.\n"
}
}
}
]
}
Note that the response above has no results for the 'has_readme' check, this is because that check does not apply to the given components and thus is not executed.
2.) An array of checkIds
and a filter
:
{
"checkIds": ["has_required_tags", "has_readme"],
"filter": { "metadata.tags": "java" }
}
This will execute the given list of checks against all entities that match the filter, and return an output similar to the following, which has been truncated for brevity:
{
"results": [
{
"entityRef": "component:default/artist-lookup",
"timestamp": "2023-02-15T20:24:40.473Z",
"checkId": "has_required_tags",
"state": "failed",
"details": {
"notes": {
"type": "notes",
"data": "No `internal` or `external` tag found, check failed.\n"
}
}
},
...
]
}
3.) A single check
which is a FactCheckerSchema
and an array of entityRefs
:
{
"check": {
"id": "has_required_tags",
"rule": {
"factRef": "catalog:default/entity_descriptor",
"path": "$.metadata.tags",
"operator": "contains",
"value": "internal"
}
},
"entityRefs": ["component:default/queue-proxy", "component:default/searcher"]
}
This will execute the supplied check against the given list of entities, and return a results output like the following, where each entry describes the entity and the result of the check:
{
"results": [
{
"entityRef": "component:default/queue-proxy",
"timestamp": "2023-02-15T20:43:44.990Z",
"checkId": "has_required_tags",
"state": "failed"
},
{
"entityRef": "component:default/searcher",
"timestamp": "2023-02-15T20:43:44.990Z",
"checkId": "has_required_tags",
"state": "failed"
}
]
}
4.) A single check
which is a FactCheckerSchema
and filter
:
{
"check": {
"id": "has_required_tags",
"rule": {
"factRef": "catalog:default/entity_descriptor",
"path": "$.metadata.tags",
"operator": "contains",
"value": "internal"
}
},
"filter": { "metadata.tags": "java" }
}
This will execute the given check against all entities matching the filter, and return an array of results describing the result of the check against all entities which passed the filter:
{
"results": [
{
"entityRef": "component:default/artist-lookup",
"timestamp": "2023-02-15T20:49:11.601Z",
"checkId": "has_required_tags",
"state": "failed"
},
{
"entityRef": "component:default/playback-order",
"timestamp": "2023-02-15T20:49:11.601Z",
"checkId": "has_required_tags",
"state": "failed"
},
{
"entityRef": "component:default/podcast-api",
"timestamp": "2023-02-15T20:49:11.601Z",
"checkId": "has_required_tags",
"state": "failed"
},
{
"entityRef": "template:default/springboot-template",
"timestamp": "2023-02-15T20:49:11.601Z",
"checkId": "has_required_tags",
"state": "failed"
}
]
}
Finally, this request also allows an optional dry-run query parameter which can be set to empty,
true
, or false
.
true
(or empty, ie: '?dryRun' with no value set) indicates that the request is indeed a dry-run, and will execute the checks but will not persist the results.false
indicates a standard request to perform the checks and record the results. This is also the default behavior if thedryRun
parameter is not specified.
Check Results API
Use the Check Results API to submit and retrieve check results to/from Soundcheck.
Submitting Results
Submit check results to Soundcheck.
POST localhost:7007/api/soundcheck/results
Request Body
See Check Results Schema.
Example Request Body
Passed
{
"results": [
{
"entityRef": "component:default/petstore",
"checkId": "tests-run",
"state": "passed"
}
]
}
Failed
{
"results": [
{
"entityRef": "component:default/petstore",
"checkId": "tests-run",
"state": "failed",
"details": {
"notes": {
"data": "Tests were not executed."
}
}
}
]
}
Example Requests
BACKSTAGE_BACKEND=localhost:7007 && \
curl \
-H 'Content-Type: application/json' \
"${BACKSTAGE_BACKEND}/api/soundcheck/results" \
--data @- << EOF
{
"results": [
{
"entityRef": "component:default/petstore",
"checkId": "tests-run",
"state": "passed"
}
]
}
EOF
POST /api/soundcheck/results HTTP/1.1
Host: localhost:7007
Content-Type: application/json
Content-Length: 129
{
"results": [
{
"entityRef": "component:default/petstore",
"checkId": "tests-run",
"state": "passed"
}
]
}
Responses
200 Response
Returns the check results which are either new or resulted in a change of state.
See Check Results Schema.
Example Response Body
{
"results": [
{
"entityRef": "string",
"checkId": "string",
"scope": "string",
"state": "passed",
"details": {
"notes": {
"type": "notes",
"version": 1,
"data": "string"
}
}
}
]
}
400 Response
Body did not match expected schema.
See Error Schema.
Example Response Body
{
"error": {
"name": "string",
"message": "string",
"stack": "string"
},
"request": {
"method": "string",
"url": "string"
},
"response": {
"statusCode": 0
}
}
500 Response
Soundcheck encountered an unexpected condition that prevented it from fulfilling the request.
See Error Schema.
Example Response Body
{
"error": {
"name": "string",
"message": "string",
"stack": "string"
},
"request": {
"method": "string",
"url": "string"
},
"response": {
"statusCode": 0
}
}
Retrieving Results
GET localhost:7007/api/soundcheck/results
Returns check results for a given entity.
Query Parameters
entityRef
Required. A reference to the entity to retrieve check results for.checks
Optional. Filters check results to only those with the provided check ID(s). Accepts multiple values:checks=A,checks=B
Example Requests
BACKSTAGE_BACKEND=localhost:7007 && \
curl \
-H 'Accept: application/json' \
"${BACKSTAGE_BACKEND}/api/soundcheck/results?entityRef=component:default/petstore&checks=tests-run"
GET /api/soundcheck/results?entityRef=component:default/petstore&checks=tests-run HTTP/1.1
Host: localhost:7007
Accept: application/json
Responses
200 Response
See Check Results Schema.
Example Response Body
{
"results": [
{
"entityRef": "component:default/petstore",
"checkId": "tests-run",
"scope": "default",
"state": "failed",
"details": {
"notes": {
"type": "notes",
"version": 1,
"data": "Tests were not executed."
}
}
}
]
}
400 Response
Invalid or missing query parameter(s).
500 Response
Soundcheck encountered an unexpected condition that prevented it from fulfilling the request.