Skip to content

Commit

Permalink
Add support for calling annotated methods with proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
rubengees committed Jul 22, 2021
1 parent d7a5500 commit 4dec658
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 21 deletions.
30 changes: 19 additions & 11 deletions src/main/kotlin/de/smartsquare/starter/mqtt/AnnotationCollector.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package de.smartsquare.starter.mqtt
import com.hivemq.client.mqtt.datatypes.MqttTopic
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.config.BeanPostProcessor
import org.springframework.core.annotation.AnnotationUtils
import org.springframework.util.LinkedMultiValueMap
import org.springframework.util.MultiValueMap
import java.lang.reflect.Method

/**
Expand All @@ -13,21 +16,24 @@ class AnnotationCollector : BeanPostProcessor {
private val logger = LoggerFactory.getLogger(javaClass)

/**
* Map of beans to it's methods annotated with [MqttSubscribe].
* MultiMap of beans to its methods annotated with [MqttSubscribe] and the annotation itself.
*/
val subscribers: Map<Any, List<Method>> get() = _subscribers
private val _subscribers = mutableMapOf<Any, List<Method>>()
val subscribers: MultiValueMap<Any, ResolvedMqttSubscriber> = LinkedMultiValueMap()

override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any {
override fun postProcessAfterInitialization(bean: Any, beanName: String): Any {
val collectedSubscribers = bean.javaClass.methods
.filter { it.isAnnotationPresent(MqttSubscribe::class.java) }
.sortedBy { it.name }
.mapNotNull { method ->
val annotation = AnnotationUtils.findAnnotation(method, MqttSubscribe::class.java)

val erroneousSubscriberDefinitions = collectedSubscribers.filter { it.isInvalidSignature() }
annotation?.let { ResolvedMqttSubscriber(method, annotation) }
}
.sortedBy { (method) -> method.name }

val erroneousSubscriberDefinitions = collectedSubscribers.filter { (method) -> method.isInvalidSignature() }

if (erroneousSubscriberDefinitions.isNotEmpty()) {
val joinedSubscribers = erroneousSubscriberDefinitions.joinToString(separator = ", ") {
"$beanName#${it.name}"
val joinedSubscribers = erroneousSubscriberDefinitions.joinToString(separator = ", ") { (method) ->
"$beanName#${method.name}"
}

throw MqttConfigurationException(
Expand All @@ -41,9 +47,9 @@ class AnnotationCollector : BeanPostProcessor {
}

for (subscriber in collectedSubscribers) {
logger.debug("Found subscriber ${subscriber.name} of ${bean.javaClass.simpleName}.")
logger.debug("Found subscriber ${subscriber.method.name} of ${bean.javaClass.simpleName}.")

_subscribers[bean] = subscribers.getOrDefault(bean, emptyList()) + listOf(subscriber)
subscribers.add(bean, subscriber)
}

return bean
Expand All @@ -58,4 +64,6 @@ class AnnotationCollector : BeanPostProcessor {

return topicParamCount > 1 || payloadParamCount > 1
}

data class ResolvedMqttSubscriber(val method: Method, val config: MqttSubscribe)
}
14 changes: 6 additions & 8 deletions src/main/kotlin/de/smartsquare/starter/mqtt/MqttRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@ abstract class MqttRouter(

override fun afterPropertiesSet() {
for ((bean, subscribers) in collector.subscribers) {
for (subscriber in subscribers) {
val annotation = subscriber.getAnnotation(MqttSubscribe::class.java)

val subscribeTopic = if (annotation.shared && config.group != null) {
"\$share/${config.group}/${annotation.topic}"
for ((subscriberMethod, subscriberAnnotation) in subscribers) {
val subscribeTopic = if (subscriberAnnotation.shared && config.group != null) {
"\$share/${config.group}/${subscriberAnnotation.topic}"
} else {
annotation.topic
subscriberAnnotation.topic
}

subscribe(subscribeTopic, annotation.qos) { topic, payload ->
deliver(subscriber, bean, topic, payload)
subscribe(subscribeTopic, subscriberAnnotation.qos) { topic, payload ->
deliver(subscriberMethod, bean, topic, payload)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class AnnotationCollectorTests {
fun onMessage(a: String, b: String) = Unit
}

invoking { annotationCollector.postProcessBeforeInitialization(bean, "testBean") }
invoking { annotationCollector.postProcessAfterInitialization(bean, "testBean") }
.shouldThrow(MqttConfigurationException::class)
.exceptionMessage
.shouldStartWith("Following subscribers are invalid [testBean#onMessage]")
Expand All @@ -86,7 +86,7 @@ class AnnotationCollectorTests {
fun second(a: String, b: String) = Unit
}

invoking { annotationCollector.postProcessBeforeInitialization(bean, "testBean") }
invoking { annotationCollector.postProcessAfterInitialization(bean, "testBean") }
.shouldThrow(MqttConfigurationException::class)
.exceptionMessage
.shouldStartWith("Following subscribers are invalid [testBean#first, testBean#second].")
Expand Down

0 comments on commit 4dec658

Please sign in to comment.