Skip to content

Commit

Permalink
feat(api): add version endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
paullatzelsperger committed May 17, 2024
1 parent 0ca80ac commit c1ca3dd
Show file tree
Hide file tree
Showing 12 changed files with 489 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,33 @@ jobs:
- name: Run Javadoc
run: ./gradlew javadoc

Verify-Api-Version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Checks to see if any change in any of the management API modules was done. If so, it sets the "mgmt" filter to "true"
- uses: dorny/[email protected]
id: filter
with:
filters: |
mgmt:
- 'extensions/control-plane/api/management-api/**/*.java'
# Use the filter to check if files in any of the management API modules were changed
# in the PR. If they were, check also, if the "api-version.json" file was appropriately modified

- name: Inspect changeset if version file changed
if: ${{ steps.filter.outputs.mgmt == 'true' }}
run: |
# check if changeset contains the `api-version.json` file
changes=$(git diff --name-status main... | grep "api-version.json" | wc -l)
if [ $changes -lt 1 ]; then
echo "::error file=./extensions/common/api/management-api-configuration/src/main/resources/api-version.json,line=1::Bumping the version is required after a change to the Management API"
return 1;
fi

Unit-Tests:
runs-on: ubuntu-latest
env:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"version": "3.0.0",
"date": "2024-05-17T07:12:44Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 Amadeus
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Amadeus - Initial API and Implementation
*
*/


plugins {
`java-library`
id("io.swagger.core.v3.swagger-gradle-plugin")
}

dependencies {
implementation(project(":extensions:common:api:api-core"))
implementation(project(":extensions:common:api:management-api-configuration"))

implementation(libs.jakarta.rsApi)

testImplementation(project(":extensions:common:http"))
testImplementation(project(":core:common:junit"))
testImplementation(testFixtures(project(":extensions:common:http:jersey-core")))
testImplementation(libs.restAssured)
testImplementation(libs.awaitility)
}

edcBuild {
swagger {
apiGroup.set("management-api")
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.connector.api.management.version;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.json.JsonObject;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;
import static org.eclipse.edc.spi.types.domain.secret.Secret.EDC_SECRET_TYPE;
import static org.eclipse.edc.spi.types.domain.secret.Secret.EDC_SECRET_VALUE;

@OpenAPIDefinition(
info = @Info(description = "This contains the version API that provides information about the exact version of the management API", title = "Version API"))
@Tag(name = "Version")
public interface VersionApi {

@Operation(description = "Gets the exact SemVer string of the Management API",
operationId = "getVersion",
responses = {
@ApiResponse(responseCode = "200", description = "The secret",
content = @Content(schema = @Schema(implementation = SecretOutputSchema.class)))
}
)
JsonObject getVersion();


@ArraySchema()
@Schema(name = "SecretOutput", example = SecretOutputSchema.SECRET_OUTPUT_EXAMPLE)
record SecretOutputSchema(
@Schema(name = ID)
String id,
@Schema(name = TYPE, example = EDC_SECRET_TYPE)
String type,
@Schema(name = EDC_SECRET_VALUE, requiredMode = REQUIRED)
String value
) {
public static final String SECRET_OUTPUT_EXAMPLE = """
{
"@context": { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" },
"@id": "secret-id",
"@type": "https://w3id.org/edc/v0.0.1/ns/Secret",
"value": "secret-value"
}
""";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.connector.api.management.version;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.json.JsonBuilderFactory;
import jakarta.json.JsonObject;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import org.eclipse.edc.spi.EdcException;

import java.io.IOException;
import java.util.Map;

import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE;

@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
@Path("/version")
public class VersionApiController implements VersionApi {
public static final String API_VERSION_JSON_FILE = "api-version.json";
public static final String VERSION_PROPERTY = "version";
public static final String DATE_PROPERTY = "date";
private static final TypeReference<Map<String, String>> MAP_TYPE = new TypeReference<>() {
};
private final ClassLoader resourceClassLoader;
private final JsonBuilderFactory jsonBuilderFactory;
private final ObjectMapper objectMapper;
private JsonObject versionObject;

public VersionApiController(ClassLoader resourceClassLoader, JsonBuilderFactory jsonBuilderFactory, ObjectMapper objectMapper) {
this.resourceClassLoader = resourceClassLoader;
this.jsonBuilderFactory = jsonBuilderFactory;
this.objectMapper = objectMapper;
}

@GET
@Path("/")
@Override
public JsonObject getVersion() {
if (versionObject == null) {
try (var versionContent = resourceClassLoader.getResourceAsStream(API_VERSION_JSON_FILE)) {
if (versionContent == null) {
throw new EdcException("Version file not found or not readable.");
}
var content = objectMapper.readValue(versionContent, MAP_TYPE);
versionObject = jsonBuilderFactory.createObjectBuilder()
.add(EDC_NAMESPACE + VERSION_PROPERTY, content.get(VERSION_PROPERTY))
.add(EDC_NAMESPACE + DATE_PROPERTY, content.get(DATE_PROPERTY))
.build();

} catch (IOException e) {
throw new EdcException(e);
}
}
return versionObject;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.connector.api.management.version;

import jakarta.json.Json;
import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.types.TypeManager;
import org.eclipse.edc.web.spi.WebService;

import java.util.Map;

@Extension(value = VersionApiExtension.NAME)
public class VersionApiExtension implements ServiceExtension {

public static final String NAME = "Management API: Version Information";

@Inject
private WebService webService;

@Inject
private ManagementApiConfiguration managementConfig;

@Inject
private TypeManager typeManager;


@Override
public String name() {
return NAME;
}

@Override
public void initialize(ServiceExtensionContext context) {
webService.registerResource(managementConfig.getContextAlias(), new VersionApiController(getClassLoader(), Json.createBuilderFactory(Map.of()), typeManager.getMapper()));
}

public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# Copyright (c) 2024 Amadeus
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
#
# Contributors:
# Amadeus - initial API and implementation
#
#

org.eclipse.edc.connector.api.management.version.VersionApiExtension
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.connector.api.management.version;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.restassured.specification.RequestSpecification;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import org.eclipse.edc.junit.annotations.ApiTest;
import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static io.restassured.RestAssured.given;
import static io.restassured.http.ContentType.JSON;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE;

@ApiTest
class VersionApiControllerTest extends RestControllerTestBase {


@BeforeEach
void setup() {
}

@Test
void getVersion() {
var result = baseRequest()
.get("/version")
.then()
.statusCode(200)
.contentType(JSON)
.extract().body().as(JsonObject.class);

var version = result.get(EDC_NAMESPACE + "version");
assertThat(version).isInstanceOf(JsonString.class);
assertThat(((JsonString) version).getString()).hasToString("3.0.0");
}

@Override
protected Object controller() {
return new VersionApiController(Thread.currentThread().getContextClassLoader(), Json.createBuilderFactory(Map.of()), new ObjectMapper());
}


private RequestSpecification baseRequest() {
return given()
.baseUri("http://localhost:" + port)
.when();
}
}
Loading

0 comments on commit c1ca3dd

Please sign in to comment.