Skip to content

Commit

Permalink
feat(Pool): add operator endpoints for searching and updating Cx memb…
Browse files Browse the repository at this point in the history
…ership of legal entities

- add GET and PUT endpoints for new Cx membership REST resource
- adapt golden record task processing logic to ignore isCatenaXMemberData flag if it is null
- return isCatenaXMemberData for legal entities as in Pool database for golden record tasks
- adapt tests
- adapt documentation
  • Loading branch information
nicoprow committed Oct 15, 2024
1 parent f5b6122 commit 9a41a8c
Show file tree
Hide file tree
Showing 36 changed files with 3,469 additions and 401 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ For changes to the BPDM Helm charts please consult the [changelog](charts/bpdm/C
- BPDM Orchestrator: Endpoint for checking the result state of given tasks
- BPDM Orchestrator: Endpoint for getting event log for finished tasks
- BPDM Pool: Enhanced data model for IdentifierTypes by adding three new fields/attributes: abbreviation, transliteratedName, and transliteratedAbbreviation.([#605](https://github.com/eclipse-tractusx/sig-release/issues/605))
- BPDM Pool: Add CX endpoints for searching and updating the CX membership information of legal entities.([#1069](https://github.com/eclipse-tractusx/bpdm/issues/1069))


### Changed

Expand All @@ -33,6 +35,8 @@ For changes to the BPDM Helm charts please consult the [changelog](charts/bpdm/C
- BPDM Cleaning Service Dummy: Removed assignment of uncategorized states while performing cleaning legal entity process.
- BPDM Gate: Fixed construction logic for states and identifiers by enabling business partner type
- BPDM Gate: Fixed logic for identifiers to retrieve only generic type on output business partner
- BPDM Gate: Fixed construction logic for states and identifiers by enabling business partner type
- BPDM Pool: When processing golden record tasks the Pool now ignores isCatenaXMemberData field if it is set to null. ([#1069](https://github.com/eclipse-tractusx/bpdm/issues/1069))

## [6.1.0] - [2024-07-15]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
import kotlin.reflect.full.findAnnotations


open class BpdmExceptionHandler : ResponseEntityExceptionHandler() {
open class BpdmExceptionHandler: ResponseEntityExceptionHandler() {

private val kotlinLogger = KotlinLogging.logger { }

Expand All @@ -47,11 +47,33 @@ open class BpdmExceptionHandler : ResponseEntityExceptionHandler() {
return handleExceptionInternal(ex, body, headers, status, request)
}

@ExceptionHandler(value = [BpdmMultipleNotFoundException::class])
protected fun handleMultipleObjectsNotFound(
ex: Exception, request: WebRequest
): ResponseEntity<Any>? {
logException(ex)

val body = createProblemDetail(ex, HttpStatusCode.valueOf(404), ex.toString(), null, null, request)
return handleExceptionInternal(ex, body, HttpHeaders(), HttpStatusCode.valueOf(404), request)
}

@ExceptionHandler(value = [BpdmValidationErrorException::class])
protected fun handleValidationErrors(
ex: Exception, request: WebRequest
): ResponseEntity<Any>? {
val typedEx = ex as BpdmValidationErrorException
val errorMessage = typedEx.validationErrors.joinToString(" ") { "Error Code ${it.validationErrorCode}: '${it.errorDetails}' on value '${it.erroneousValue}' at ${it.context.propertyPath.joinToString(".")}." }
val body = createProblemDetail(ex, HttpStatusCode.valueOf(400), errorMessage, null, null, request)
return handleExceptionInternal(ex, body, HttpHeaders(), HttpStatusCode.valueOf(400), request)
}


@ExceptionHandler(value = [Exception::class])
protected fun logException(
protected fun handleGenericException(
ex: Exception, request: WebRequest
): ResponseEntity<Any>? {
logException(ex)

return handleException(ex, request)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import kotlin.reflect.KClass
@ResponseStatus(HttpStatus.NOT_FOUND)
open class BpdmMultipleNotFoundException(
objectType: String,
identifiers: Collection<String>
val identifiers: Collection<String>
) : RuntimeException("$objectType with following identifiers not found: ${identifiers.joinToString()}") {
constructor(objectType: KClass<*>, identifiers: Collection<String>) :
this(objectType.simpleName ?: objectType.toString(), identifiers)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* 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.bpdm.common.exception

import org.eclipse.tractusx.bpdm.common.mapping.ValidationError
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.ResponseStatus


@ResponseStatus(HttpStatus.BAD_REQUEST)
class BpdmValidationErrorException(
val validationErrors: List<ValidationError>
): RuntimeException(validationErrors.joinToString())
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package org.eclipse.tractusx.bpdm.common.mapping

abstract class BpdmFilledLimitedStringMapper<TO_TYPE>(
private val limitedLengthValidation: BpdmValidation<String>
): BpdmStringMapper<TO_TYPE>, BpdmValidateAndMapMapper<String, TO_TYPE> {
): BpdmValidateAndMapStringMapper<TO_TYPE> {

private val isBlankValidation = object: BpdmValidation<String>{
override fun validate(value: String, context: ValidationContext): ValidationError? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.eclipse.tractusx.bpdm.common.mapping

import org.eclipse.tractusx.bpdm.common.mapping.ValidationContext.Companion.onIndex

/**
* Offers base logic to validate and map from one type to another
*/
Expand All @@ -31,13 +33,20 @@ interface BpdmMapper<FROM_TYPE, TO_TYPE> {
*/
fun map(valueToMap: FROM_TYPE, context: ValidationContext = ValidationContext.NoContext): MappingResult<TO_TYPE>

fun map(listToMap: List<FROM_TYPE>, context: ValidationContext = ValidationContext.NoContext): MappingResult<List<TO_TYPE>>{
val entryResults = listToMap.mapIndexed { index, entry -> map(entry, context.onIndex(index)) }
val entryErrors = entryResults.flatMap { it.errors }
return MappingResult.invalidOnError(entryErrors){ entryResults.map { it.successfulResult } }
}

/**
* Check whether a non-null [valueToMap] of the [FROM_TYPE] should be treated as a valid null mapping result
*
*/
fun checkTreatAsNull(valueToMap: FROM_TYPE) = false

fun checkTreatAsNull(listToMap: List<FROM_TYPE>) = false

/**
* Try to map given nullable [valueToMap] within the given [context] whereby null is an acceptable value
*
Expand All @@ -46,7 +55,14 @@ interface BpdmMapper<FROM_TYPE, TO_TYPE> {
fun mapValidNull(valueToMap: FROM_TYPE?, context: ValidationContext = ValidationContext.NoContext): NullableMappingResult<TO_TYPE>{
return valueToMap
?.let { if(checkTreatAsNull(it)) null else it }
?.let { NullableMappingResult.fromResult(map(it)) }
?.let { NullableMappingResult.fromResult(map(it, context)) }
?: NullableMappingResult.ofValidNull()
}

fun mapValidNull(listToMap: List<FROM_TYPE>?, context: ValidationContext = ValidationContext.NoContext): NullableMappingResult<List<TO_TYPE>>{
return listToMap
?.let { if(checkTreatAsNull(it)) null else it }
?.let { NullableMappingResult.fromResult(map(it, context)) }
?: NullableMappingResult.ofValidNull()
}

Expand All @@ -56,7 +72,11 @@ interface BpdmMapper<FROM_TYPE, TO_TYPE> {
* Return a [NullableMappingResult] containing either the result or validation errors
*/
fun mapInvalidNull(valueToMap: FROM_TYPE?, context: ValidationContext = ValidationContext.NoContext): MappingResult<TO_TYPE>{
return valueToMap?.let { map(it) } ?: MappingResult.ofInvalidNull()
return valueToMap?.let { map(it, context) } ?: MappingResult.ofInvalidNull()
}

fun mapInvalidNull(listToMap: List<FROM_TYPE>?, context: ValidationContext = ValidationContext.NoContext): MappingResult<List<TO_TYPE>>{
return listToMap?.let { map(it, context) } ?: MappingResult.ofInvalidNull()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* 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.bpdm.common.mapping

interface BpdmValidateAndMapStringMapper<TO_TYPE>: BpdmStringMapper<TO_TYPE>, BpdmValidateAndMapMapper<String, TO_TYPE>
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

package org.eclipse.tractusx.bpdm.common.mapping

import org.eclipse.tractusx.bpdm.common.exception.BpdmValidationErrorException
import org.eclipse.tractusx.bpdm.common.mapping.ValidationContext.Companion.onIndex

/**
* Offers base logic to validate values
*/
Expand All @@ -39,7 +42,13 @@ interface BpdmValidator<T> {
/**
* Validate given [value] and throw exception if any error is found
*/
fun assert(value: T){
require(validate(value).isEmpty())
fun assert(value: T, context: ValidationContext = ValidationContext.NoContext){
val errors = validate(value, context)
if(errors.isNotEmpty()) throw BpdmValidationErrorException(errors)
}

fun assert(listOfValues: List<T>, context: ValidationContext = ValidationContext.NoContext){
val errors = listOfValues.flatMapIndexed { index, value -> validate(value, context.onIndex(index)) }
if(errors.isNotEmpty()) throw BpdmValidationErrorException(errors)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* 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.bpdm.common.mapping

class BpnValidation(
private val bpnTypeDescriptor: String,
private val errorCode: String,
private val errorDetails: String,
private val bpnPrefix: String = "BPN",
private val codeLength: Int = 10,
private val checksumLength: Int = 2,
private val allowedAlphabet: String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",

): BpdmValidation<String> {

companion object{
val bpnLValidation = BpnValidation(
"L",
CommonValidationErrorCodes.BpnL.name,
CommonValidationErrorCodes.BpnL.description
)
}


private val correctTypePrefix = bpnPrefix + bpnTypeDescriptor
private val correctPrefixLength = correctTypePrefix.length
private val correctLength = correctPrefixLength + codeLength + checksumLength
private val allowedAlphabetSet = allowedAlphabet.toSet()

override fun validate(value: String, context: ValidationContext): ValidationError? {
val wrongLength = value.length != correctLength
val wrongTypePrefix = !value.startsWith(correctTypePrefix)
val wrongAlphabet = value.any { it !in allowedAlphabetSet }
// We could also check the checksum here but won't do for now to be compatible to legacy checksums

return if(wrongLength || wrongTypePrefix || wrongAlphabet)
ValidationError(errorCode, errorDetails, value, context)
else null

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ enum class CommonValidationErrorCodes(val description: String) {
ExceedsHugeLength("Exceeds maximum length of $HUGE_STRING_LENGTH"),
ISO31661("Not ISO 3166-1 conform"),
ISO31662("Not ISO 3166-2 conform"),
ISO6391("Not ISO 639-1 conform");
ISO6391("Not ISO 639-1 conform"),
BpnL("Is not a BPNL");

fun toValidationError(value: String?, context: ValidationContext) =
ValidationError(name, description, value, context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.eclipse.tractusx.bpdm.common.mapping

import org.eclipse.tractusx.bpdm.common.exception.BpdmValidationErrorException

/**
* Holds the non-null result of a mapping to type [T]
*
Expand Down Expand Up @@ -69,7 +71,8 @@ data class MappingResult<T>(
* On a successful mapping return the resulting value otherwise throw an exception
*/
override val successfulResult by lazy {
require(isSuccess)
if(!isSuccess) throw BpdmValidationErrorException(errors)

optionalResult!!
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.eclipse.tractusx.bpdm.common.mapping

import org.eclipse.tractusx.bpdm.common.exception.BpdmValidationErrorException

/**
* Holds the nullable result of a mapping to type [T]
*
Expand Down Expand Up @@ -57,8 +59,8 @@ data class NullableMappingResult<T>(
* On a successful mapping return the resulting value otherwise throw an exception
*/
val successfulResult by lazy {
require(isSuccess)
if(!isSuccess) throw BpdmValidationErrorException(errors)

optionalResult
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,16 @@ import kotlin.reflect.KClass
import kotlin.reflect.KProperty

data class ValidationContext(
val classType: KClass<*>?,
val classType: String,
val objectId: String,
val propertyPath: List<KProperty<*>>,
val propertyPath: List<String>
) {
companion object {
val NoContext = ValidationContext(null, "", emptyList())
val NoContext = ValidationContext("", "", emptyList())

fun fromRoot(classType: KClass<*>?, objectId: String) = ValidationContext(classType, objectId, emptyList())
fun fromRoot(classType: KClass<*>?, objectId: String, vararg path: KProperty<*>) = ValidationContext(classType?.simpleName ?: "", objectId, path.map { it.name })

fun ValidationContext.onProperty(property: KProperty<*>) = copy(propertyPath = propertyPath + property)
fun ValidationContext.onProperty(property: KProperty<*>) = copy(propertyPath = propertyPath + property.name)
fun ValidationContext.onIndex(index: Int) = copy(propertyPath = propertyPath + "Index $index")
}

val prefix = "Class ${classType?.simpleName} with Id $objectId on property ${propertyPath.joinToString()}: "
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* 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.bpdm.common.mapping.types

import org.eclipse.tractusx.bpdm.common.mapping.BpdmValidateAndMapStringMapper
import org.eclipse.tractusx.bpdm.common.mapping.BpnValidation

@JvmInline
value class BpnLString(val value: String) {

init { assert(value) }

companion object: BpdmValidateAndMapStringMapper<BpnLString>{
override fun transform(value: String) = BpnLString(value)

override val validations = listOf(BpnValidation.bpnLValidation)
}
}
Loading

0 comments on commit 9a41a8c

Please sign in to comment.