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

feat(Pool): Cx Membership Operator Logic #1072

Merged
merged 1 commit into from
Oct 15, 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
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