Skip to content

Commit

Permalink
Merge pull request #10 from OSGP/feature/FDP-1619-simulator-reconnect…
Browse files Browse the repository at this point in the history
…-on-failure

FDP-1619: fix proxy reboot issue
  • Loading branch information
LucianoFavoroso authored Jan 10, 2024
2 parents 7fcb7c9 + b0062c9 commit 69e61ff
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,15 @@

package org.gxf.crestdevicesimulator.configuration

import org.eclipse.californium.core.CoapClient
import org.eclipse.californium.core.coap.CoAP
import org.eclipse.californium.core.network.CoapEndpoint
import org.eclipse.californium.elements.config.Configuration
import org.eclipse.californium.scandium.DTLSConnector
import org.eclipse.californium.scandium.MdcConnectionListener
import org.eclipse.californium.scandium.config.DtlsConnectorConfig
import org.eclipse.californium.scandium.dtls.ProtocolVersion
import org.gxf.crestdevicesimulator.simulator.data.entity.PreSharedKey
import org.gxf.crestdevicesimulator.simulator.data.repository.PskRepository
import org.springframework.context.annotation.Bean
import java.net.InetSocketAddress

@org.springframework.context.annotation.Configuration
class CoapClientConfiguration(private val configuration: Configuration,
private val simulatorProperties: SimulatorProperties,
class CoapClientConfiguration(private val simulatorProperties: SimulatorProperties,
private val pskRepository: PskRepository) {

@Bean
fun coapClient(dtlsConnector: DTLSConnector): CoapClient {
val uri = simulatorProperties.uri
val coapClient = CoapClient(uri)
if (uri.scheme == CoAP.COAP_SECURE_URI_SCHEME) {
val endpoint = CoapEndpoint.Builder()
.setConfiguration(configuration)
.setConnector(dtlsConnector)
.build()
coapClient.setEndpoint(endpoint)
}
return coapClient
}

@Bean
fun dtlsConnector(advancedSingleIdentityPskStore: AdvancedSingleIdentityPskStore): DTLSConnector {
val address = InetSocketAddress(0)
val dtlsBuilder = DtlsConnectorConfig.builder(configuration)
.setAddress(address)
.setAdvancedPskStore(advancedSingleIdentityPskStore)
.setConnectionListener(MdcConnectionListener())
.setProtocolVersionForHelloVerifyRequests(ProtocolVersion.VERSION_DTLS_1_2)
.build()
return DTLSConnector(dtlsBuilder)
}

@Bean
fun pskStore(): AdvancedSingleIdentityPskStore {
val store = AdvancedSingleIdentityPskStore(simulatorProperties.pskIdentity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ package org.gxf.crestdevicesimulator.simulator

import com.fasterxml.jackson.databind.ObjectMapper
import io.github.oshai.kotlinlogging.KotlinLogging
import org.eclipse.californium.core.CoapClient
import org.eclipse.californium.core.coap.MediaTypeRegistry
import org.eclipse.californium.core.coap.Request
import org.eclipse.californium.elements.exception.ConnectorException
import org.gxf.crestdevicesimulator.configuration.SimulatorProperties
import org.gxf.crestdevicesimulator.simulator.coap.CoapClientService
import org.gxf.crestdevicesimulator.simulator.response.ResponseHandler
import org.springframework.core.io.ClassPathResource
import org.springframework.scheduling.annotation.Scheduled
Expand All @@ -20,7 +20,7 @@ import java.io.IOException
@Service
class Simulator(
private val simulatorProperties: SimulatorProperties,
private val coapClient: CoapClient,
private val coapClientService: CoapClientService,
private val responseHandler: ResponseHandler) {

private val logger = KotlinLogging.logger {}
Expand All @@ -46,8 +46,10 @@ class Simulator(

private fun request(request: Request) {
try {
val coapClient = coapClientService.createCoapClient()
val response = coapClient.advanced(request)
responseHandler.handleResponse(response)
coapClientService.shutdownCoapClient(coapClient)
logger.info { "RESPONSE $response" }
} catch (e: ConnectorException) {
e.printStackTrace()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.gxf.crestdevicesimulator.simulator.coap

import org.eclipse.californium.core.CoapClient
import org.eclipse.californium.core.coap.CoAP
import org.eclipse.californium.core.network.CoapEndpoint
import org.eclipse.californium.elements.config.Configuration
import org.eclipse.californium.scandium.DTLSConnector
import org.eclipse.californium.scandium.MdcConnectionListener
import org.eclipse.californium.scandium.config.DtlsConnectorConfig
import org.eclipse.californium.scandium.dtls.ProtocolVersion
import org.gxf.crestdevicesimulator.configuration.AdvancedSingleIdentityPskStore
import org.gxf.crestdevicesimulator.configuration.SimulatorProperties
import org.springframework.stereotype.Service
import java.net.InetSocketAddress

@Service
class CoapClientService(
private val simulatorProperties: SimulatorProperties,
private val advancedSingleIdentityPskStore: AdvancedSingleIdentityPskStore,
private val configuration: Configuration) {

fun shutdownCoapClient(coapClient: CoapClient) {
coapClient.endpoint.stop()
coapClient.endpoint.destroy()
coapClient.shutdown()
}

fun createCoapClient(): CoapClient {
val uri = simulatorProperties.uri
val coapClient = CoapClient(uri)
if (uri.scheme == CoAP.COAP_SECURE_URI_SCHEME) {
val endpoint = CoapEndpoint.Builder()
.setConfiguration(configuration)
.setConnector(createDtlsConnector(advancedSingleIdentityPskStore))
.build()
coapClient.setEndpoint(endpoint)
}
return coapClient
}

private fun createDtlsConnector(advancedSingleIdentityPskStore: AdvancedSingleIdentityPskStore): DTLSConnector {
val address = InetSocketAddress(0)
val dtlsBuilder = DtlsConnectorConfig.builder(configuration)
.setAddress(address)
.setAdvancedPskStore(advancedSingleIdentityPskStore)
.setConnectionListener(MdcConnectionListener())
.setProtocolVersionForHelloVerifyRequests(ProtocolVersion.VERSION_DTLS_1_2)
.build()
return DTLSConnector(dtlsBuilder)
}
}
26 changes: 16 additions & 10 deletions application/src/test/kotlin/SimulatorTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import org.eclipse.californium.core.coap.Request
import org.gxf.crestdevicesimulator.configuration.SimulatorProperties
import org.gxf.crestdevicesimulator.simulator.CborFactory
import org.gxf.crestdevicesimulator.simulator.Simulator
import org.gxf.crestdevicesimulator.simulator.coap.CoapClientService
import org.gxf.crestdevicesimulator.simulator.response.ResponseHandler
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Assertions.assertArrayEquals
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.ArgumentCaptor
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.*
import org.mockito.junit.jupiter.MockitoExtension
import org.springframework.util.ResourceUtils

Expand All @@ -27,6 +29,9 @@ class SimulatorTests {
@Mock
private lateinit var coapClient: CoapClient

@Mock
private lateinit var coapClientService: CoapClientService

@Mock
private lateinit var responseHandler: ResponseHandler

Expand All @@ -35,33 +40,34 @@ class SimulatorTests {

@BeforeEach
fun setup() {
Mockito.`when`(coapClient.advanced(Mockito.any())).thenReturn(Mockito.mock(CoapResponse::class.java))
Mockito.`when`(simulatorProperties.messagePath).thenReturn("test-file.json")
`when`(coapClient.advanced(any())).thenReturn(mock(CoapResponse::class.java))
`when`(simulatorProperties.messagePath).thenReturn("test-file.json")
`when`(coapClientService.createCoapClient()).thenReturn(coapClient)
}


@Test
fun shouldSendInvalidCborWhenTheMessageTypeIsInvalidCbor() {
Mockito.`when`(simulatorProperties.produceValidCbor).thenReturn(false)
`when`(simulatorProperties.produceValidCbor).thenReturn(false)
val argument = ArgumentCaptor.forClass(Request::class.java)

simulator.sendPostMessage()

Mockito.verify(coapClient).advanced(argument.capture())
Assertions.assertEquals(CborFactory.INVALID_CBOR_MESSAGE, argument.value.payloadString)
verify(coapClient).advanced(argument.capture())
assertEquals(CborFactory.INVALID_CBOR_MESSAGE, argument.value.payloadString)
}

@Test
fun shouldSendCborFromConfiguredJsonFileWhenTheMessageTypeIsCbor() {
Mockito.`when`(simulatorProperties.produceValidCbor).thenReturn(true)
`when`(simulatorProperties.produceValidCbor).thenReturn(true)

val fileToUse = ResourceUtils.getFile("classpath:test-file.json")
val argument = ArgumentCaptor.forClass(Request::class.java)

simulator.sendPostMessage()
Mockito.verify(coapClient).advanced(argument.capture())
verify(coapClient).advanced(argument.capture())

val expected = CBORMapper().writeValueAsBytes(ObjectMapper().readTree(fileToUse))
Assertions.assertArrayEquals(expected, argument.value.payload)
assertArrayEquals(expected, argument.value.payload)
}
}

0 comments on commit 69e61ff

Please sign in to comment.