Skip to content

Commit

Permalink
feat: add airthings
Browse files Browse the repository at this point in the history
  • Loading branch information
oyvindis committed Aug 25, 2023
1 parent 501b0ab commit 4c10962
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 15 deletions.
19 changes: 19 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
<kotlin.version>1.6.21</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
Expand Down Expand Up @@ -55,6 +63,17 @@
<version>1.2.6</version>
</dependency>

<!-- Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package no.oyvindis.kafkaproducerclimate

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.boot.runApplication
import org.springframework.scheduling.annotation.EnableScheduling

@SpringBootApplication
@ConfigurationPropertiesScan
@EnableScheduling
class KafkaProducerClimateApplication

fun main(args: Array<String>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package no.oyvindis.kafkaproducerclimate.config

import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager
import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction
import org.springframework.web.reactive.function.client.WebClient


private val logger: Logger = LoggerFactory.getLogger(AirthingsWebClientConfig::class.java)

@Configuration
open class AirthingsWebClientConfig {
@Bean
open fun webClient(clientRegistrationRepository: ClientRegistrationRepository): WebClient? {
val registrationRepository =
InMemoryReactiveClientRegistrationRepository(clientRegistrationRepository.findByRegistrationId("airthings"))
val clientService = InMemoryReactiveOAuth2AuthorizedClientService(registrationRepository)
val clientManager =
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(registrationRepository, clientService)
return WebClient.builder()
.filter(ServerOAuth2AuthorizedClientExchangeFilterFunction(clientManager))
.build()
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package no.oyvindis.kafkaproducerclimate.entities

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
data class Sensor(
@JsonProperty("temperature")
val temperature: String,
@JsonProperty("humidity")
val humidity: String?
)
var location: String?,
val battery: String? = null,
val co2: String? = null,
val humidity: String? = null,
val pm1: String? = null,
val pm25: String? = null,
val pressure: String? = null,
val temp: String? = null,
val voc: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package no.oyvindis.kafkaproducerclimate.service

import no.oyvindis.kafkaproducerclimate.entities.Sensor
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.kafka.core.KafkaTemplate
import org.springframework.kafka.support.KafkaHeaders
import org.springframework.messaging.Message
import org.springframework.messaging.support.MessageBuilder
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction
import org.springframework.stereotype.Service
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.reactive.function.client.bodyToMono

private val logger: Logger = LoggerFactory.getLogger(ClimateService::class.java)

class AirthingsResponse {
val data: Sensor? = null
}

@Service
class ClimateService(
private val webClient: WebClient,
@Autowired
val kafkaTemplate: KafkaTemplate<String, Any>,
@Value("\${kafka.topics.sensor}")
val topic: String,
) {
@Scheduled(fixedDelay = 900000)
fun postReadingFromAirthings() {
try {
logger.debug("postReadingFromAirthings")
val data = webClient
.get()
.uri("https://ext-api.airthings.com/v1/devices/2960009475/latest-samples")
.attributes(
ServerOAuth2AuthorizedClientExchangeFilterFunction
.clientRegistrationId("airthings")
)
.retrieve()
.bodyToMono<AirthingsResponse>()
val responseStr = data.block()

val sensorReading: Sensor? = responseStr?.data
sensorReading?.location = "2960009475"
sensorReading?.let {
val message: Message<Sensor?> = MessageBuilder
.withPayload(sensorReading)
.setHeader(KafkaHeaders.TOPIC, topic)
.build()
kafkaTemplate.send(message)
logger.info("Message sent with success")
}
} catch (e: Exception) {
logger.error("Exception: {}", e)
}
}
}
35 changes: 34 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,41 @@ logging:

server:
port: 8080

kafka:
bootstrapAddress: ${KAFKA_BOOTSTRAP_HOST:10.0.0.22}:${KAFKA_BOOTSTRAP_PORT:31172}
topics:
sensor: sensor
spring:
security:
oauth2:
client:
registration:
airthings:
clientId: ${CLIENT_ID}
clientSecret: ${CLIENT_SECRET}
clientAuthenticationMethod: client_secret_post
authorizationGrantType: client_credentials
scopes: read:device:current_values
clientName: ois-airthings
provider:
airthings:
authorizationUri: https://accounts.airthings.com/authorize
tokenUri: https://accounts-api.airthings.com/v1/token
---
spring:
security:
oauth2:
client:
registration:
airthings:
clientId: ${CLIENT_ID}
clientSecret: ${CLIENT_SECRET}
clientAuthenticationMethod: client_secret_post
authorizationGrantType: client_credentials
scopes: read:device:current_values
clientName: ois-airthings
provider:
airthings:
authorizationUri: https://accounts.airthings.com/authorize
tokenUri: https://accounts-api.airthings.com/v1/token
config.activate.on-profile: develop
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
package no.oyvindis.kafkaproducerclimate

import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
class KafkaProducerClimateApplicationTests {

@Test
fun contextLoads() {
}

}
class KafkaProducerClimateApplicationTests {}

0 comments on commit 4c10962

Please sign in to comment.