Skip to content

Commit

Permalink
Merge pull request OSGP#57 from OSGP/feature/FDP-2638-firmware-files-…
Browse files Browse the repository at this point in the history
…inlezen-en-naar-maki

Feature/fdp 2638 firmware files inlezen en naar maki
  • Loading branch information
sanderv authored Oct 24, 2024
2 parents 604e3e8 + 46a23bc commit 0fc1198
Show file tree
Hide file tree
Showing 55 changed files with 1,124 additions and 34 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ To test this flow locally:
Communication between the COAP HTTP Proxy and the Crest device service should be encrypted using mutual TLS.

The repositories contain test certificates that can be used for local testing. (they are not included in the jar or docker image)
They can be also be (re)generated using the [generate_certificates.sh](generate_certificates.sh) script.
They can be also be (re)generated using the [generate_certificates.sh](scripts/generate_certificates.sh) script.
8 changes: 4 additions & 4 deletions application/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.security:spring-security-core")
implementation("org.springframework.kafka:spring-kafka")

implementation(project(":components:avro"))
implementation(project(":components:device"))
implementation(project(":components:firmware"))
implementation(project(":components:psk"))
Expand All @@ -27,8 +29,6 @@ dependencies {

implementation(libs.commonsCodec)

implementation(libs.avro)

runtimeOnly("io.micrometer:micrometer-registry-prometheus")
runtimeOnly("org.postgresql:postgresql")
runtimeOnly("org.flywaydb:flyway-database-postgresql")
Expand Down Expand Up @@ -73,12 +73,12 @@ testing {
useJUnitJupiter()
dependencies {
implementation(project())
implementation(project(":components:avro"))
implementation(project(":components:psk"))
implementation(project(":components:device"))
implementation(project(":components:firmware"))
implementation(project(":components:psk"))
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation(libs.kafkaAvro)
implementation(libs.avro)
implementation("org.springframework.kafka:spring-kafka")
implementation("org.springframework.boot:spring-boot-starter-test")
implementation("org.springframework.kafka:spring-kafka-test")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import org.springframework.kafka.test.context.EmbeddedKafka
import org.springframework.kafka.test.utils.KafkaTestUtils
import org.springframework.test.annotation.DirtiesContext

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@EmbeddedKafka(topics = ["\${kafka.producers.command-feedback.topic}"])
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class CoapMessageHandlingTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import org.springframework.kafka.test.context.EmbeddedKafka
import org.springframework.test.annotation.DirtiesContext

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@EmbeddedKafka(
topics = ["\${kafka.producers.device-message.topic}"],
)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class DeviceCredentialsRetrievalTest {
companion object {
private const val IDENTITY = "1234"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package org.gxf.crestdeviceservice

import com.alliander.sng.CommandFeedback
import com.alliander.sng.Firmwares
import com.gxf.utilities.kafka.avro.AvroDeserializer
import com.gxf.utilities.kafka.avro.AvroSerializer
import org.apache.avro.specific.SpecificRecordBase
Expand All @@ -30,7 +31,9 @@ object IntegrationTestHelper {
DefaultKafkaConsumerFactory(
testProperties,
StringDeserializer(),
AvroDeserializer(listOf(DeviceMessage.getClassSchema(), CommandFeedback.getClassSchema())))
AvroDeserializer(
listOf(
DeviceMessage.getClassSchema(), CommandFeedback.getClassSchema(), Firmwares.getClassSchema())))
val consumer = consumerFactory.createConsumer()
embeddedKafkaBroker.consumeFromAnEmbeddedTopic(consumer, topic)
return consumer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import org.springframework.kafka.test.context.EmbeddedKafka
import org.springframework.kafka.test.utils.KafkaTestUtils
import org.springframework.test.annotation.DirtiesContext

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@EmbeddedKafka(topics = ["\${kafka.consumers.command.topic}", "\${kafka.producers.command-feedback.topic}"])
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class MakiCommandHandlingTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import org.springframework.kafka.test.context.EmbeddedKafka
import org.springframework.test.annotation.DirtiesContext
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@EmbeddedKafka(
topics = ["\${kafka.producers.device-message.topic}"],
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// SPDX-FileCopyrightText: Copyright Contributors to the GXF project
//
// SPDX-License-Identifier: Apache-2.0
package org.gxf.crestdeviceservice

import java.io.File
import java.time.Duration
import java.time.Instant
import org.assertj.core.api.Assertions.assertThat
import org.gxf.crestdeviceservice.IntegrationTestHelper.createKafkaConsumer
import org.gxf.crestdeviceservice.config.KafkaProducerProperties
import org.gxf.crestdeviceservice.firmware.repository.FirmwarePacketRepository
import org.gxf.crestdeviceservice.firmware.repository.FirmwareRepository
import org.gxf.crestdeviceservice.psk.entity.PreSharedKey
import org.gxf.crestdeviceservice.psk.entity.PreSharedKeyStatus
import org.gxf.crestdeviceservice.psk.repository.PskRepository
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.boot.test.web.client.postForEntity
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.FileSystemResource
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.kafka.test.EmbeddedKafkaBroker
import org.springframework.kafka.test.context.EmbeddedKafka
import org.springframework.test.annotation.DirtiesContext
import org.springframework.util.LinkedMultiValueMap

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EmbeddedKafka(topics = ["\${kafka.producers.firmware.topic}"])
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@EnableConfigurationProperties(KafkaProducerProperties::class)
class WebServerTest {
@Autowired private lateinit var restTemplate: TestRestTemplate
@Autowired private lateinit var firmwareRepository: FirmwareRepository
@Autowired private lateinit var firmwarePacketRepository: FirmwarePacketRepository
@Autowired private lateinit var embeddedKafkaBroker: EmbeddedKafkaBroker
@Autowired private lateinit var kafkaProducerProperties: KafkaProducerProperties
@Autowired private lateinit var pskRepository: PskRepository

companion object {
private const val NAME = "RTU#FULL#TO#23.10.txt"
private const val NUMBER_OF_PACKETS = 13
private const val IDENTITY = "1234"
private const val PRE_SHARED_KEY = "1234567890123456"
}

@BeforeEach
fun setup() {
pskRepository.save(PreSharedKey(IDENTITY, 0, Instant.MIN, PRE_SHARED_KEY, PreSharedKeyStatus.ACTIVE))
}

@AfterEach
fun cleanup() {
pskRepository.deleteAll()
}

@Test
fun firmwareFileUploadTest() {
// arrange
val firmwareFile = ClassPathResource(NAME).file
val consumer = createKafkaConsumer(embeddedKafkaBroker, kafkaProducerProperties.firmware.topic)

// act
val response = uploadFile(firmwareFile)

// assert
assertThat(response.statusCode.value()).isEqualTo(302)
assertThat(firmwareRepository.findByName(NAME)).isNotNull
assertThat(firmwarePacketRepository.findAll()).hasSize(NUMBER_OF_PACKETS)

val records = consumer.poll(Duration.ofSeconds(1))
assertThat(records.records(kafkaProducerProperties.firmware.topic)).hasSize(1)
}

fun uploadFile(file: File): ResponseEntity<String> {
val headers: HttpHeaders = HttpHeaders().apply { contentType = MediaType.MULTIPART_FORM_DATA }

val body = LinkedMultiValueMap<String, Any>().apply { add("file", FileSystemResource(file)) }
val requestEntity = HttpEntity(body, headers)

return this.restTemplate.postForEntity<String>("/web/firmware", requestEntity)
}

@Test
fun pskRequestOnWebPortShouldReturn404() {
// create second PSK for identity this one should be returned
pskRepository.save(PreSharedKey(IDENTITY, 1, Instant.MIN, "0000111122223333", PreSharedKeyStatus.ACTIVE))

val headers = HttpHeaders().apply { add("x-device-identity", IDENTITY) }
val result = restTemplate.exchange("/psk", HttpMethod.GET, HttpEntity<Unit>(headers), String::class.java)

assertThat(result.statusCode.is4xxClientError).isTrue()
}
}
Loading

0 comments on commit 0fc1198

Please sign in to comment.