Skip to content

Commit 92263f1

Browse files
committed
improve logging: input api fail + exceptions
- log detailed information when a measure is rejected by the input api - make AppException herit from RuntimeException (vs Throwable), so that logs from ExceptionHandlerExceptionResolver are not throwing IllegalStateException, but actually showing the kind of error instead
1 parent 9d324b5 commit 92263f1

5 files changed

Lines changed: 31 additions & 5 deletions

File tree

src/main/kotlin/ch/derlin/bbdata/common/Beans.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@ object Beans {
2929
val description: String? = null
3030
}
3131

32+
}
3233

33-
}
34+
35+
fun String?.truncate(maxLength: Int = 30, ellipsis: String = "[${Typography.ellipsis}]"): String? =
36+
if (this != null && this.length > maxLength) this.take(maxLength).plus(ellipsis) else this

src/main/kotlin/ch/derlin/bbdata/common/exceptions/Exceptions.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package ch.derlin.bbdata.common.exceptions
22

3+
import java.lang.RuntimeException
4+
35
/**
46
* date: 15.12.19
57
* @author Lucy Linder <lucy.derlin@gmail.com>
68
*/
79

8-
open class AppException(val details: Any) : Throwable() {
10+
open class AppException(val details: Any) : RuntimeException("$details") {
911
val name: String get() = this.javaClass.name.split('.').last()
1012
}
1113

src/main/kotlin/ch/derlin/bbdata/input/InputController.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
1111
import io.swagger.v3.oas.annotations.Operation
1212
import io.swagger.v3.oas.annotations.tags.Tag
1313
import org.joda.time.DateTime
14+
import org.slf4j.LoggerFactory
1415
import org.springframework.beans.factory.annotation.Value
1516
import org.springframework.kafka.core.KafkaTemplate
1617
import org.springframework.web.bind.annotation.PostMapping
@@ -35,6 +36,8 @@ class InputController(
3536
private val kafkaTemplate: KafkaTemplate<String, String> // note: ignore jetbrains [false] warning
3637
) {
3738

39+
private final val log = LoggerFactory.getLogger(InputController::class.java)
40+
3841
// Just for tests, if you don't want to have kafka running, do:
3942
// export BB_NO_KAFKA=true
4043
@Value("\${${HiddenEnvironmentVariables.NO_KAFKA}:false}")
@@ -84,6 +87,7 @@ class InputController(
8487
val measure = if (rawMeasure.timestamp != null) {
8588
// check that date is in the past
8689
if (rawMeasure.timestamp.millis > now.millis + MAX_LAG) {
90+
log.info("REJECTED: wrong timestamp: ${rawMeasure}")
8791
throw WrongParamsException("objectId ${rawMeasure.objectId}: date should be in the past. input='${rawMeasure.timestamp}', now='$now'")
8892
}
8993
rawMeasure
@@ -94,17 +98,21 @@ class InputController(
9498

9599
// get metadata
96100
val meta = inputRepository.getMeasureMeta(measure.objectId!!, measure.token!!).orElseThrow {
101+
log.info("REJECTED: wrong token: $measure")
97102
ItemNotFoundException(msg = "objectId ${measure.objectId}: the pair <objectId, token> does not exist")
98103
}
99104
// ensure the object is enabled. This is just a double check, as tokens cannot be created on disabled objects
100105
if (meta.disabled) {
106+
log.info("REJECTED: object is disabled: $rawMeasure")
101107
throw ForbiddenException("objectId ${rawMeasure.objectId} is disabled.")
102108
}
103109
// ensure the measure matches the type declared, and parse it
104110
val parsedValue = BaseType.parseType(measure.value!!, meta.type)
105-
parsedValue
106-
?: throw WrongParamsException("objectId ${rawMeasure.objectId}: the value '${measure.value}' does not match " +
107-
"the unit ${meta.unitSymbol} (${meta.type}) declared in the object definition.")
111+
if(parsedValue == null) {
112+
log.info("REJECTED: wrong value given the unit: $measure, $meta")
113+
throw WrongParamsException("objectId ${rawMeasure.objectId}: the value '${measure.value}' does not match " +
114+
"the unit ${meta.unitSymbol} (${meta.type}) declared in the object definition.")
115+
}
108116

109117
measure.value = parsedValue.toString()
110118

@@ -114,12 +122,14 @@ class InputController(
114122

115123
// ensure no duplicate objectId/timestamp in the data sent
116124
if (valueKeys.contains(key)) {
125+
log.info("REJECTED: duplicate in body: $measure")
117126
throw WrongParamsException("objectId ${measure.objectId}: two or more values with the same timestamp")
118127
}
119128
valueKeys.add(key)
120129

121130
// ensure it doesn't already exist in cassandra TODO: find a better way ?
122131
if (rawValueRepository.existsById(rawValue.key)) {
132+
log.info("REJECTED: duplicate in cassandra: $measure")
123133
throw WrongParamsException("objectId ${rawMeasure.objectId}: " +
124134
"a value with the same timestamp (${measure.timestamp}) already exists for this object.")
125135
}

src/main/kotlin/ch/derlin/bbdata/input/InputRepository.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class InputRepository(private val em: EntityManager) {
3030
WHERE o.id = :objectId AND t.token = :token
3131
""".trimIndent()
3232
}
33+
34+
override fun toString(): String {
35+
return "MeasureMeta(unitName='$unitName', unitSymbol='$unitSymbol', type='$type', owner=$owner, disabled=$disabled)"
36+
}
3337
}
3438

3539
@Cacheable(Constants.META_CACHE, key = "#objectId.toString().concat(':').concat(#token)", unless = "#result == null")

src/main/kotlin/ch/derlin/bbdata/input/NewValue.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ch.derlin.bbdata.input
22

33
import ch.derlin.bbdata.common.cassandra.RawValue
44
import ch.derlin.bbdata.common.cassandra.RawValuePK
5+
import ch.derlin.bbdata.common.truncate
56
import org.joda.time.DateTime
67
import org.joda.time.YearMonth
78
import javax.validation.constraints.Min
@@ -35,6 +36,7 @@ data class NewValue(
3536
val comment: String? = null
3637
) {
3738

39+
3840
fun toRawValue(): RawValue = RawValue(
3941
key = RawValuePK(
4042
objectId = objectId!!.toInt(),
@@ -43,4 +45,9 @@ data class NewValue(
4345
value = value!!,
4446
comment = comment
4547
)
48+
49+
override fun toString(): String {
50+
return "NewValue(objectId=$objectId, token=$token, timestamp=$timestamp, " +
51+
"value=${value.truncate()}, comment=${comment?.truncate(10)})"
52+
}
4653
}

0 commit comments

Comments
 (0)