Skip to content

Commit

Permalink
Finish migrating logbook message flat and consolidated methods in Bac…
Browse files Browse the repository at this point in the history
…kend
  • Loading branch information
ivangabriele committed Apr 8, 2024
1 parent de7e839 commit 49882f8
Show file tree
Hide file tree
Showing 9 changed files with 913 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,81 +40,105 @@ data class LogbookMessage(
val tripSegments: List<LogbookTripSegment>? = listOf(),
) {
fun <T : LogbookMessageValue> toConsolidatedLogbookMessage(
children: List<LogbookMessage>,
relatedLogbookMessages: List<LogbookMessage>,
clazz: Class<T>,
): ConsolidatedLogbookMessage<T> {
if (reportId == null) {
throw EntityConversionException(
"Logbook report $id has no `reportId`. You can only consolidate a DAT operation with a `reportId`.",
"Logbook report $id has no `reportId`. You can only consolidate a DAT or an orphan COR operation with a `reportId`.",
)
}
if (operationType != LogbookOperationType.DAT) {
if (operationType !in listOf(LogbookOperationType.DAT, LogbookOperationType.COR)) {
throw EntityConversionException(
"Logbook report $id has operationType '$operationType'. You can only consolidate a DAT operation.",
"Logbook report $id has operationType '$operationType'. You can only consolidate a DAT or an orphan COR operation.",
)
}

val historicallyOrderedChildren = children.sortedBy { it.reportDateTime }
val maybeLastLogbookMessageAcknowledgement = historicallyOrderedChildren.lastOrNull {
it.operationType == LogbookOperationType.RET
}
val maybeLastLogbookMessageCorrection = historicallyOrderedChildren.lastOrNull {
it.operationType == LogbookOperationType.COR
}
val historicallyOrderedRelatedLogbookMessages = relatedLogbookMessages.sortedBy { it.reportDateTime }
val maybeLastLogbookMessageCorrection = historicallyOrderedRelatedLogbookMessages
.lastOrNull { it.operationType == LogbookOperationType.COR }

val logbookMessageBase = maybeLastLogbookMessageCorrection ?: this
logbookMessageBase.consolidateAcknowledge(relatedLogbookMessages)
val finalLogbookMessage = logbookMessageBase.copy(
// We need to restore the `reportId` and `referencedReportId` to the original values
// in case it has been consolidated from a COR operation rather than a DAT one
reportId = reportId,
referencedReportId = null,
// /!\ `logbookMessageBase` might be a COR, which happens when there is no DAT at all.
isCorrected = logbookMessageBase.operationType == LogbookOperationType.COR,
deleted = historicallyOrderedRelatedLogbookMessages.any { it.operationType == LogbookOperationType.DEL },
)

return ConsolidatedLogbookMessage(
reportId = reportId,
logbookMessage = finalLogbookMessage,
clazz = clazz,
)
}

logbookMessageBase.let { logbookMessageWithConsolidatedProps ->
if (maybeLastLogbookMessageAcknowledgement != null) {
val lastLogbookMessageAcknowledgementMessage =
maybeLastLogbookMessageAcknowledgement.message as Acknowledge
private fun consolidateAcknowledge(relatedLogbookMessages: List<LogbookMessage>) {
if (this.transmissionFormat == LogbookTransmissionFormat.FLUX ||
software !== null && software.contains(LogbookSoftware.VISIOCAPTURE.software)
) {
this.setAcknowledgeAsSuccessful()

logbookMessageWithConsolidatedProps.apply {
val isSuccess =
lastLogbookMessageAcknowledgementMessage.returnStatus == RETReturnErrorCode.SUCCESS.number
return
}

this.acknowledge = Acknowledge(
dateTime = maybeLastLogbookMessageAcknowledgement.reportDateTime,
isSuccess = isSuccess,
)
}
}
if (logbookMessageWithConsolidatedProps.transmissionFormat == LogbookTransmissionFormat.FLUX) {
logbookMessageWithConsolidatedProps.apply {
this.acknowledge = Acknowledge(isSuccess = true)
}
}
val historycallyOrderedRetLogbookMessages = relatedLogbookMessages
.filter { it.operationType == LogbookOperationType.RET && it.referencedReportId == reportId }
.sortedBy { it.reportDateTime }

if (maybeLastLogbookMessageCorrection != null) {
logbookMessageWithConsolidatedProps.apply {
logbookMessageWithConsolidatedProps.isCorrected = true
}
}
val maybeLastSuccessfulRetLogbookMessage = historycallyOrderedRetLogbookMessages.lastOrNull {
val message = it.message as Acknowledge

if (historicallyOrderedChildren.any { it.operationType == LogbookOperationType.DEL }) {
logbookMessageWithConsolidatedProps.apply {
logbookMessageWithConsolidatedProps.deleted = true
}
message.returnStatus == RETReturnErrorCode.SUCCESS.number
}
if (maybeLastSuccessfulRetLogbookMessage != null) {
val lastSucessfulRetMessage = maybeLastSuccessfulRetLogbookMessage.message as Acknowledge
this.acknowledge = lastSucessfulRetMessage.also {
it.dateTime = maybeLastSuccessfulRetLogbookMessage.reportDateTime
it.isSuccess = true
}

return ConsolidatedLogbookMessage(
reportId = reportId,
logbookMessage = logbookMessageWithConsolidatedProps,
clazz = clazz,
)
return
}
}

fun setAcknowledge(acknowledgeLogbookMessage: LogbookMessage) {
val acknowledgeDateTime = this.acknowledge?.dateTime
if (acknowledgeDateTime != null && acknowledgeDateTime > acknowledgeLogbookMessage.reportDateTime) {
return
val maybeLastRetLogbookMessage = historycallyOrderedRetLogbookMessages.lastOrNull()
if (maybeLastRetLogbookMessage != null) {
val lastRetMessage = maybeLastRetLogbookMessage.message as Acknowledge
this.acknowledge = lastRetMessage.also {
it.dateTime = maybeLastRetLogbookMessage.reportDateTime
it.isSuccess = lastRetMessage.returnStatus == RETReturnErrorCode.SUCCESS.number
}
}
}

fun setAcknowledge(newLogbookMessageAcknowledgement: LogbookMessage) {
val currentAcknowledgement = this.acknowledge
val newAcknowledgement = newLogbookMessageAcknowledgement.message as Acknowledge

val isCurrentAcknowledgementSuccessful = currentAcknowledgement?.isSuccess ?: false
val isNewAcknowledgementSuccessful = newAcknowledgement.returnStatus == RETReturnErrorCode.SUCCESS.number

this.acknowledge = acknowledgeLogbookMessage.message as Acknowledge
this.acknowledge?.let {
it.isSuccess = it.returnStatus == RETReturnErrorCode.SUCCESS.number
it.dateTime = acknowledgeLogbookMessage.reportDateTime
val shouldUpdate = when {
// If there is no currently calculated acknowledgement yet, create it
currentAcknowledgement?.dateTime == null || currentAcknowledgement.isSuccess == null -> true
// If the new acknowledgement message is successful while the currently calculated one is not, replace it
isNewAcknowledgementSuccessful && currentAcknowledgement.isSuccess != true -> true
// TODO How to handle that? Check time rules with Vincent.
newLogbookMessageAcknowledgement.reportDateTime == null -> false
// If the new acknowledgement message is more recent than the currently calculated one, replace it
newLogbookMessageAcknowledgement.reportDateTime > currentAcknowledgement.dateTime -> true

else -> false
}
if (shouldUpdate) {
this.acknowledge = newAcknowledgement.also {
it.isSuccess = isCurrentAcknowledgementSuccessful || isNewAcknowledgementSuccessful
it.dateTime = newLogbookMessageAcknowledgement.reportDateTime
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class GetPriorNotification(
val priorNotificationWithoutReportingsCount = logbookReportRepository
.findPriorNotificationByReportId(logbookMessageReportId)
.let { priorNotification ->
logger.info("Prior notification found: $priorNotification")
logger.info("Prior notification found: ${priorNotification.consolidatedLogbookMessage.logbookMessage}")

priorNotification.consolidatedLogbookMessage.logbookMessage
.generateGearPortAndSpecyNames(allGears, allPorts, allSpecies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,22 @@ class GetLogbookMessages(

private fun flagCorrectedAcknowledgedAndDeletedMessages(messages: List<LogbookMessage>) {
messages.forEach { logbookMessage ->
val referencedLogbookMessage = if (!logbookMessage.referencedReportId.isNullOrEmpty()) {
val referenceLogbookMessage = if (!logbookMessage.referencedReportId.isNullOrEmpty()) {
messages.find { it.reportId == logbookMessage.referencedReportId }
} else {
null
}

if (logbookMessage.operationType == LogbookOperationType.COR && !logbookMessage.referencedReportId.isNullOrEmpty()) {
if (referencedLogbookMessage == null) {
if (referenceLogbookMessage == null) {
logger.warn(
"Original message ${logbookMessage.referencedReportId} corrected by message COR ${logbookMessage.operationNumber} is not found.",
)
}

referencedLogbookMessage?.isCorrected = true
referenceLogbookMessage?.isCorrected = true
} else if (logbookMessage.operationType == LogbookOperationType.RET && !logbookMessage.referencedReportId.isNullOrEmpty()) {
referencedLogbookMessage?.setAcknowledge(logbookMessage)
referenceLogbookMessage?.setAcknowledge(logbookMessage)
} else if (logbookMessage.transmissionFormat == LogbookTransmissionFormat.FLUX) {
logbookMessage.setAcknowledgeAsSuccessful()
} else if (
Expand All @@ -87,7 +87,7 @@ class GetLogbookMessages(
) {
logbookMessage.setAcknowledgeAsSuccessful()
} else if (logbookMessage.operationType == LogbookOperationType.DEL && !logbookMessage.referencedReportId.isNullOrEmpty()) {
referencedLogbookMessage?.deleted = true
referenceLogbookMessage?.deleted = true
}

if (logbookMessage.software !== null && logbookMessage.software.contains(LogbookSoftware.E_SACAPT.software)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ data class LogbookReportEntity(
@Column(name = "software")
val software: String? = null,
@Column(name = "enriched")
val isEnriched: Boolean,
val isEnriched: Boolean = false,
@Type(JsonBinaryType::class)
@Column(name = "trip_gears", nullable = true, columnDefinition = "jsonb")
val tripGears: String? = null,
Expand Down Expand Up @@ -144,11 +144,12 @@ data class LogbookReportEntity(
)
}

fun toPriorNotification(mapper: ObjectMapper, childrenModels: List<LogbookReportEntity>): PriorNotification {
val logbookMessage = toLogbookMessage(mapper)
val logbookMessageChildren = childrenModels.map { it.toLogbookMessage(mapper) }
val consolidatedLogbookMessage = logbookMessage
.toConsolidatedLogbookMessage(logbookMessageChildren, PNO::class.java)
fun toPriorNotification(mapper: ObjectMapper, relatedModels: List<LogbookReportEntity>): PriorNotification {
val referenceLogbookMessage = toLogbookMessage(mapper)
val relatedLogbookMessages = relatedModels.map { it.toLogbookMessage(mapper) }
println("relatedLogbookMessages: $relatedLogbookMessages")
val consolidatedLogbookMessage = referenceLogbookMessage
.toConsolidatedLogbookMessage(relatedLogbookMessages, PNO::class.java)
// Default to UNKNOWN vessel when null or not found
val vessel = vessel?.toVessel() ?: Vessel(id = -1, flagState = CountryCode.UNDEFINED)

Expand Down
Loading

0 comments on commit 49882f8

Please sign in to comment.