-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add API for the BPN validation extension (#688)
* feat: add BPN group API * renamed store * javadoc * cleanup * add api and controller * update license headers * add test tag * DEPENDENCIES
- Loading branch information
1 parent
d8b54dd
commit 8670f2c
Showing
30 changed files
with
663 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
edc-extensions/bpn-validation/bpn-validation-api/build.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright (c) 2023 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 | ||
* | ||
*/ | ||
|
||
plugins { | ||
`java-library` | ||
`maven-publish` | ||
id("io.swagger.core.v3.swagger-gradle-plugin") | ||
} | ||
|
||
dependencies { | ||
implementation(project(":edc-extensions:bpn-validation:bpn-validation-spi")) | ||
implementation(project(":spi:core-spi")) | ||
implementation(libs.edc.api.management) | ||
implementation(libs.edc.spi.aggregateservices) | ||
implementation(libs.jakarta.rsApi) | ||
|
||
testImplementation(testFixtures(libs.edc.core.jersey)) | ||
testImplementation(libs.restAssured) | ||
testImplementation(libs.edc.junit) | ||
} |
102 changes: 102 additions & 0 deletions
102
...alidation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/BusinessPartnerGroupApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* 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 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.api.bpn; | ||
|
||
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.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.parameters.RequestBody; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.json.JsonObject; | ||
import org.eclipse.edc.web.spi.ApiErrorDetail; | ||
|
||
import java.util.Set; | ||
|
||
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; | ||
|
||
@OpenAPIDefinition(info = @Info(description = "With this API clients can create, read, update and delete BusinessPartnerNumber groups. It allows the assigning of BPNs to groups.", title = "Business Partner Group API")) | ||
@Tag(name = "BusinessPartnerGroup") | ||
public interface BusinessPartnerGroupApi { | ||
|
||
|
||
@Operation(description = "Resolves all groups for a particular BPN", | ||
responses = { | ||
@ApiResponse(responseCode = "200", description = "An object containing an array with the assigned groups"), | ||
@ApiResponse(responseCode = "404", description = "No entry for the given BPN was found"), | ||
@ApiResponse(responseCode = "400", description = "Request body was malformed", | ||
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) | ||
}) | ||
JsonObject resolve(@Parameter(name = "bpn", description = "The business partner number") String bpn); | ||
|
||
@Operation(description = "Deletes the entry for a particular BPN", | ||
responses = { | ||
@ApiResponse(responseCode = "204", description = "The object was successfully deleted"), | ||
@ApiResponse(responseCode = "404", description = "No entry for the given BPN was found"), | ||
@ApiResponse(responseCode = "400", description = "Request body was malformed", | ||
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) | ||
}) | ||
void deleteEntry(@Parameter(name = "bpn", description = "The business partner number") String bpn); | ||
|
||
@Operation(description = "Updates the entry for a particular BPN", | ||
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ListSchema.class))), | ||
|
||
responses = { | ||
@ApiResponse(responseCode = "204", description = "The object was successfully updated"), | ||
@ApiResponse(responseCode = "404", description = "No entry for the given BPN was found"), | ||
@ApiResponse(responseCode = "400", description = "Request body was malformed", | ||
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) | ||
}) | ||
void updateEntry(JsonObject object); | ||
|
||
@Operation(description = "Creates an entry for a particular BPN", | ||
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ListSchema.class))), | ||
|
||
responses = { | ||
@ApiResponse(responseCode = "204", description = "The object was successfully created"), | ||
@ApiResponse(responseCode = "409", description = "An entry already exists for that BPN"), | ||
@ApiResponse(responseCode = "400", description = "Request body was malformed", | ||
content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) | ||
}) | ||
void createEntry(JsonObject entry); | ||
|
||
|
||
@Schema(name = "List", example = ListSchema.EXAMPLE) | ||
record ListSchema( | ||
@Schema(name = ID) String id, | ||
Set<String> groups | ||
) { | ||
public static final String EXAMPLE = """ | ||
{ | ||
"@context": { | ||
"tx": "https://w3id.org/tractusx/v0.0.1/ns/" | ||
}, | ||
"@id": "tx:BPN000001234", | ||
"tx:groups": ["group1", "group2", "group3"] | ||
} | ||
"""; | ||
} | ||
} |
126 changes: 126 additions & 0 deletions
126
...api/src/main/java/org/eclipse/tractusx/edc/api/bpn/BusinessPartnerGroupApiController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/* | ||
* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* 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 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.api.bpn; | ||
|
||
import io.swagger.v3.oas.annotations.parameters.RequestBody; | ||
import jakarta.json.Json; | ||
import jakarta.json.JsonObject; | ||
import jakarta.json.JsonString; | ||
import jakarta.ws.rs.Consumes; | ||
import jakarta.ws.rs.DELETE; | ||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.POST; | ||
import jakarta.ws.rs.PUT; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.PathParam; | ||
import jakarta.ws.rs.Produces; | ||
import jakarta.ws.rs.core.MediaType; | ||
import org.eclipse.edc.web.spi.exception.InvalidRequestException; | ||
import org.eclipse.edc.web.spi.exception.ObjectConflictException; | ||
import org.eclipse.edc.web.spi.exception.ObjectNotFoundException; | ||
import org.eclipse.tractusx.edc.validation.businesspartner.spi.BusinessPartnerStore; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.List; | ||
|
||
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; | ||
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE; | ||
|
||
|
||
@Consumes({MediaType.APPLICATION_JSON}) | ||
@Produces({MediaType.APPLICATION_JSON}) | ||
@Path("/business-partner-groups") | ||
public class BusinessPartnerGroupApiController implements BusinessPartnerGroupApi { | ||
|
||
private final BusinessPartnerStore businessPartnerService; | ||
|
||
|
||
public BusinessPartnerGroupApiController(BusinessPartnerStore businessPartnerService) { | ||
this.businessPartnerService = businessPartnerService; | ||
} | ||
|
||
@GET | ||
@Path("/{bpn}") | ||
@Override | ||
public JsonObject resolve(@PathParam("bpn") String bpn) { | ||
|
||
// StoreResult does not support the .map() operator, because it does not override newInstance() | ||
var result = businessPartnerService.resolveForBpn(bpn); | ||
if (result.succeeded()) { | ||
return createObject(bpn, result.getContent()); | ||
} | ||
|
||
throw new ObjectNotFoundException(List.class, result.getFailureDetail()); | ||
} | ||
|
||
@DELETE | ||
@Path("/{bpn}") | ||
@Override | ||
public void deleteEntry(@PathParam("bpn") String bpn) { | ||
businessPartnerService.delete(bpn) | ||
.orElseThrow(f -> new ObjectNotFoundException(List.class, f.getFailureDetail())); | ||
} | ||
|
||
@PUT | ||
@Override | ||
public void updateEntry(@RequestBody JsonObject object) { | ||
var bpn = getBpn(object); | ||
var groups = getGroups(object); | ||
businessPartnerService.update(bpn, groups) | ||
.orElseThrow(f -> new ObjectNotFoundException(List.class, f.getFailureDetail())); | ||
} | ||
|
||
@POST | ||
@Override | ||
public void createEntry(@RequestBody JsonObject object) { | ||
var bpn = getBpn(object); | ||
var groups = getGroups(object); | ||
businessPartnerService.save(bpn, groups) | ||
.orElseThrow(f -> new ObjectConflictException(f.getFailureDetail())); | ||
} | ||
|
||
private JsonObject createObject(String bpn, List<String> list) { | ||
return Json.createObjectBuilder() | ||
.add(ID, bpn) | ||
.add(TX_NAMESPACE + "groups", Json.createArrayBuilder(list)) | ||
.build(); | ||
} | ||
|
||
|
||
private String getBpn(JsonObject object) { | ||
try { | ||
return object.getString(ID); | ||
} catch (Exception ex) { | ||
throw new InvalidRequestException(ex.getMessage()); | ||
} | ||
} | ||
|
||
@NotNull | ||
private List<String> getGroups(JsonObject object) { | ||
try { | ||
return object.getJsonArray(TX_NAMESPACE + "groups").stream().map(jv -> ((JsonString) jv).getString()).toList(); | ||
} catch (Exception ex) { | ||
throw new InvalidRequestException(ex.getMessage()); | ||
} | ||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
...-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/BusinessPartnerGroupApiExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* 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 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.api.bpn; | ||
|
||
import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration; | ||
import org.eclipse.edc.connector.api.management.configuration.transform.ManagementApiTypeTransformerRegistry; | ||
import org.eclipse.edc.jsonld.spi.JsonLd; | ||
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.web.spi.WebService; | ||
import org.eclipse.tractusx.edc.validation.businesspartner.spi.BusinessPartnerStore; | ||
|
||
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE; | ||
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_PREFIX; | ||
|
||
@Extension(value = "Registers the Business Partner Group API") | ||
public class BusinessPartnerGroupApiExtension implements ServiceExtension { | ||
|
||
@Inject | ||
private WebService webService; | ||
@Inject | ||
private ManagementApiConfiguration apiConfiguration; | ||
@Inject | ||
private ManagementApiTypeTransformerRegistry transformerRegistry; | ||
@Inject | ||
private JsonLd jsonLdService; | ||
@Inject | ||
private BusinessPartnerStore businessPartnerStore; | ||
|
||
@Override | ||
public void initialize(ServiceExtensionContext context) { | ||
jsonLdService.registerNamespace(TX_PREFIX, TX_NAMESPACE); | ||
|
||
webService.registerResource(apiConfiguration.getContextAlias(), new BusinessPartnerGroupApiController(businessPartnerStore)); | ||
|
||
} | ||
} |
Oops, something went wrong.