Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: makes IdentityHub API Swagger-UI compliant #285

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .github/workflows/apidoc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ jobs:
# Disable temporarily, because we can only have 3 APIs in the SwaggerHub free tier
if: github.repository == 'eclipse-edc/IdentityHub' && false
runs-on: ubuntu-latest
strategy:
matrix:
apiGroup: [ 'ih-resolution-api', 'ih-management-api' ]
env:
rootDir: resources/openapi/yaml
rootDir: resources/openapi/yaml/${{ matrix.apiGroup }}
SWAGGERHUB_API_KEY: ${{ secrets.SWAGGERHUB_TOKEN }}
SWAGGERHUB_USER: ${{ secrets.SWAGGERHUB_USER }}
VERSION: ${{ github.event.inputs.version || inputs.version }}
API_NAME: 'ih-api'
OUTPUT_FILE_NAME: 'ihapi.yaml'
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-build
Expand All @@ -49,7 +50,7 @@ jobs:
cmd="-Pversion=$VERSION"
fi
./gradlew resolve
./gradlew ${cmd} -PapiTitle="IdentityHub REST API" -PapiDescription="REST API documentation for the IdentityHub" :mergeApiSpec --input=${{ env.rootDir }} --output=${{ env.OUTPUT_FILE_NAME }}
./gradlew ${cmd} -PapiTitle="${{ matrix.apiGroup }}" -PapiDescription="REST API documentation for the ${{ matrix.apiGroup }}" :mergeApiSpec --input=${{ env.rootDir }} --output=${{ matrix.apiGroup }}.yaml

# install swaggerhub CLI
- name: Install SwaggerHub CLI
Expand All @@ -59,7 +60,7 @@ jobs:
- name: Create API
continue-on-error: true
run: |
swaggerhub api:create ${{ env.SWAGGERHUB_USER }}/${{ env.API_NAME }} -f ${{ env.OUTPUT_FILE_NAME }} --visibility=public --published=unpublish
swaggerhub api:create ${{ env.SWAGGERHUB_USER }}/${{ matrix.apiGroup }} -f ${{ matrix.apiGroup }}.yaml --visibility=public --published=unpublish

# Post snapshots of the API to SwaggerHub as "unpublished", because published APIs cannot be overwritten
- name: Publish API Specs to SwaggerHub
Expand All @@ -69,9 +70,9 @@ jobs:

if [[ $vers != *-SNAPSHOT ]]; then
echo "no snapshot, will set the API to 'published'";
swaggerhub api:update ${{ env.SWAGGERHUB_USER }}/${{ env.API_NAME }} -f ${{ env.OUTPUT_FILE_NAME }} --visibility=public --published=publish
swaggerhub api:setdefault ${{ env.SWAGGERHUB_USER }}/${{ env.API_NAME }}/$vers
swaggerhub api:update ${{ env.SWAGGERHUB_USER }}/${{ matrix.apiGroup }} -f ${{ matrix.apiGroup }}.yaml --visibility=public --published=publish
swaggerhub api:setdefault ${{ env.SWAGGERHUB_USER }}/${{ matrix.apiGroup }}/$vers
else
echo "snapshot, will set the API to 'unpublished'";
swaggerhub api:update ${{ env.SWAGGERHUB_USER }}/${{ env.API_NAME }} -f ${{ env.OUTPUT_FILE_NAME }} --visibility=public --published=unpublish
swaggerhub api:update ${{ env.SWAGGERHUB_USER }}/${{ matrix.apiGroup }} -f ${{ matrix.apiGroup }}.yaml --visibility=public --published=unpublish
fi
6 changes: 6 additions & 0 deletions core/identity-hub-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ dependencies {
testImplementation(testFixtures(project(":spi:identity-hub-spi")))
testImplementation(libs.nimbus.jwt)
}

edcBuild {
swagger {
apiGroup.set("ih-resolution-api")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ record PresentationQuerySchema(
"@type": "PresentationQueryMessage",
"presentationDefinition": null,
"scope": [
"org.eclipse.edc.vc.type:SomeCredential_0.3.5:write,
"org.eclipse.edc.vc.type:SomeOtherCredential:read,
"org.eclipse.edc.vc.type:ThirdCredential:*,
"org.eclipse.edc.vc.type:SomeCredential_0.3.5:write",
"org.eclipse.edc.vc.type:SomeOtherCredential:read",
"org.eclipse.edc.vc.type:ThirdCredential:*"
]
}
""";
Expand All @@ -75,7 +75,7 @@ record PresentationQuerySchema(
record PresentationResponseSchema(
@Schema(name = CONTEXT, requiredMode = REQUIRED)
Object context,
@Schema(name = "presentation", requiredMode = REQUIRED, anyOf = { String.class, JsonObject.class })
@Schema(name = "presentation", requiredMode = REQUIRED, anyOf = {String.class, JsonObject.class})
List<Object> presentation
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,19 @@ public interface PresentationApi {

@Tag(name = "Resolution API")
@Operation(description = "Issues a new presentation query, that contains either a DIF presentation definition, or a list of scopes",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ApiSchema.PresentationQuerySchema.class), mediaType = "application/ld+json")),
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ApiSchema.PresentationQuerySchema.class))),
responses = {
@ApiResponse(responseCode = "200", description = "The query was successfully processed, the response contains the VerifiablePresentation",
content = @Content(schema = @Schema(implementation = ApiSchema.PresentationResponseSchema.class), mediaType = "application/ld+json")),
content = @Content(schema = @Schema(implementation = ApiSchema.PresentationResponseSchema.class))),
@ApiResponse(responseCode = "400", description = "Request body was malformed, for example when both scope and presentationDefinition are given",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class)), mediaType = "application/json")),
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class)))),
@ApiResponse(responseCode = "401", description = "No Authorization header was given.",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class)), mediaType = "application/json")),
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class)))),
@ApiResponse(responseCode = "403", description = "The given authentication token could not be validated. This can happen, when the request body " +
"calls for a broader query scope than the granted scope in the auth token",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class)), mediaType = "application/json")),
"calls for a broader query scope than the granted scope in the auth token",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class)))),
@ApiResponse(responseCode = "501", description = "When the request contained a presentationDefinition object, but the implementation does not support it.",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class)), mediaType = "application/json"))
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiSchema.ApiErrorDetailSchema.class))))
}
)
Response queryPresentation(String participantContextId, JsonObject query, String authHeader);
Expand Down
6 changes: 6 additions & 0 deletions extensions/api/did-mgmt-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,9 @@ dependencies {
testImplementation(libs.nimbus.jwt)
testImplementation(libs.restAssured)
}

edcBuild {
swagger {
apiGroup.set("ih-management-api")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -39,6 +40,7 @@ public interface DidManagementApi {

@Tag(name = "DID Management API")
@Operation(description = "Publish an (existing) DID document. The DID is expected to exist in the database.",
parameters = {@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)},
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = DidRequestPayload.class), mediaType = "application/json")),
responses = {
@ApiResponse(responseCode = "200", description = "The DID document was successfully published."),
Expand All @@ -52,6 +54,7 @@ public interface DidManagementApi {

@Tag(name = "DID Management API")
@Operation(description = "Un-Publish an (existing) DID document. The DID is expected to exist in the database.",
parameters = {@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)},
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = DidRequestPayload.class), mediaType = "application/json")),
responses = {
@ApiResponse(responseCode = "200", description = "The DID document was successfully un-published."),
Expand All @@ -67,6 +70,7 @@ public interface DidManagementApi {

@Tag(name = "DID Management API")
@Operation(description = "Query for DID documents..",
parameters = {@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)},
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = QuerySpec.class), mediaType = "application/json")),
responses = {
@ApiResponse(responseCode = "200", description = "The list of DID Documents.",
Expand All @@ -81,6 +85,7 @@ public interface DidManagementApi {

@Tag(name = "DID Management API")
@Operation(description = "Get state of a DID document",
parameters = {@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)},
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = DidRequestPayload.class), mediaType = "application/json")),
responses = {
@ApiResponse(responseCode = "200", description = "The DID state was successfully obtained"),
Expand All @@ -95,7 +100,10 @@ public interface DidManagementApi {
@Tag(name = "DID Management API")
@Operation(description = "Adds a service endpoint to a particular DID document.",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = Service.class), mediaType = "application/json")),
parameters = {@Parameter(name = "autoPublish", description = "Whether the DID should get republished after the removal. Defaults to false.")},
parameters = {
@Parameter(name = "autoPublish", description = "Whether the DID should get republished after the removal. Defaults to false."),
@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)
},
responses = {
@ApiResponse(responseCode = "200", description = "The DID document was successfully updated."),
@ApiResponse(responseCode = "401", description = "The request could not be completed, because either the authentication was missing or was not valid.",
Expand All @@ -111,7 +119,10 @@ public interface DidManagementApi {
@Tag(name = "DID Management API")
@Operation(description = "Replaces a service endpoint of a particular DID document.",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = Service.class), mediaType = "application/json")),
parameters = {@Parameter(name = "autoPublish", description = "Whether the DID should get republished after the removal. Defaults to false.")},
parameters = {
@Parameter(name = "autoPublish", description = "Whether the DID should get republished after the removal. Defaults to false."),
@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)
},
responses = {
@ApiResponse(responseCode = "200", description = "The DID document was successfully updated."),
@ApiResponse(responseCode = "401", description = "The request could not be completed, because either the authentication was missing or was not valid.",
Expand All @@ -126,9 +137,11 @@ public interface DidManagementApi {

@Tag(name = "DID Management API")
@Operation(description = "Removes a service endpoint from a particular DID document.",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = Service.class), mediaType = "application/json")),
parameters = {@Parameter(name = "serviceId", description = "The ID of the service that should get removed"), @Parameter(name = "autoPublish", description = "Whether the DID should " +
"get republished after the removal. Defaults to false.")},
parameters = {
@Parameter(name = "serviceId", description = "The ID of the service that should get removed"),
@Parameter(name = "autoPublish", description = "Whether the DID should " + "get republished after the removal. Defaults to false."),
@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)
},
responses = {
@ApiResponse(responseCode = "200", description = "The DID document was successfully updated."),
@ApiResponse(responseCode = "401", description = "The request could not be completed, because either the authentication was missing or was not valid.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
plugins {
`java-library`
`maven-publish`
id("io.swagger.core.v3.swagger-gradle-plugin")
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
plugins {
`java-library`
`maven-publish`
id("io.swagger.core.v3.swagger-gradle-plugin")
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
plugins {
`java-library`
`maven-publish`
id("io.swagger.core.v3.swagger-gradle-plugin")
}

dependencies {
Expand Down
6 changes: 6 additions & 0 deletions extensions/api/keypair-mgmt-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ dependencies {
testImplementation(libs.restAssured)
testImplementation(testFixtures(libs.edc.core.jersey))
}

edcBuild {
swagger {
apiGroup.set("ih-management-api")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -37,6 +38,9 @@ public interface KeyPairResourceApi {

@Tag(name = "KeyPairResources Management API")
@Operation(description = "Finds a KeyPairResource by ID.",
parameters = {
@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)
},
responses = {
@ApiResponse(responseCode = "200", description = "The KeyPairResource.",
content = @Content(schema = @Schema(implementation = ParticipantContext.class))),
Expand Down Expand Up @@ -85,6 +89,9 @@ public interface KeyPairResourceApi {

@Tag(name = "KeyPairResources Management API")
@Operation(description = "Sets a KeyPairResource to the ACTIVE state. Will fail if the current state is anything other than ACTIVE or CREATED.",
parameters = {
@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)
},
responses = {
@ApiResponse(responseCode = "200", description = "The KeyPairResource.",
content = @Content(schema = @Schema(implementation = ParticipantContext.class))),
Expand All @@ -101,7 +108,10 @@ public interface KeyPairResourceApi {
@Tag(name = "KeyPairResources Management API")
@Operation(description = "Rotates (=retires) a particular key pair, identified by their ID and optionally create a new successor key.",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = KeyDescriptor.class), mediaType = "application/json")),
parameters = @Parameter(name = "duration", description = "Indicates for how long the public key of the rotated/retired key pair should still be available "),
parameters = {
@Parameter(name = "duration", description = "Indicates for how long the public key of the rotated/retired key pair should still be available "),
@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)
},
responses = {
@ApiResponse(responseCode = "200", description = "The KeyPairResource was successfully rotated and linked to the participant.",
content = @Content(schema = @Schema(implementation = ParticipantContext.class))),
Expand All @@ -117,6 +127,9 @@ public interface KeyPairResourceApi {

@Tag(name = "KeyPairResources Management API")
@Operation(description = "Revokes (=removes) a particular key pair, identified by their ID and create a new successor key.",
parameters = {
@Parameter(name = "participantId", description = "Base64-Url encode Participant Context ID", required = true, in = ParameterIn.PATH)
},
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = KeyDescriptor.class), mediaType = "application/json")),
responses = {
@ApiResponse(responseCode = "200", description = "The KeyPairResource was successfully rotated and linked to the participant.",
Expand Down
6 changes: 6 additions & 0 deletions extensions/api/participant-context-mgmt-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,9 @@ dependencies {
testImplementation(libs.nimbus.jwt)
testImplementation(libs.restAssured)
}

edcBuild {
swagger {
apiGroup.set("ih-management-api")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public interface ParticipantContextApi {

@Tag(name = "ParticipantContext Management API")
@Operation(description = "Gets ParticipantContexts by ID.",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ParticipantManifest.class), mediaType = "application/json")),
responses = {
@ApiResponse(responseCode = "200", description = "The list of ParticipantContexts.",
content = @Content(schema = @Schema(implementation = ParticipantContext.class))),
Expand Down Expand Up @@ -100,7 +99,6 @@ public interface ParticipantContextApi {

@Tag(name = "ParticipantContext Management API")
@Operation(description = "Delete a ParticipantContext.",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ParticipantManifest.class), mediaType = "application/json")),
responses = {
@ApiResponse(responseCode = "200", description = "The ParticipantContext was deleted successfully", content = {@Content(schema = @Schema(implementation = String.class))}),
@ApiResponse(responseCode = "400", description = "Request body was malformed, or the request could not be processed",
Expand Down
Loading
Loading