diff --git a/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapResourceStub.kt b/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapResourceStub.kt index 909657c..bf183ad 100644 --- a/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapResourceStub.kt +++ b/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapResourceStub.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator import org.eclipse.californium.core.CoapResource diff --git a/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapServerHelpers.kt b/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapServerHelpers.kt index 57663f0..30c4ac1 100644 --- a/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapServerHelpers.kt +++ b/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/CoapServerHelpers.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator import org.eclipse.californium.core.network.CoapEndpoint diff --git a/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/SimulatorIntegrationTest.kt b/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/SimulatorIntegrationTest.kt index df9b61d..24e75cf 100644 --- a/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/SimulatorIntegrationTest.kt +++ b/application/src/integrationTest/kotlin/org/gxf/crestdevicesimulator/SimulatorIntegrationTest.kt @@ -1,11 +1,12 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper +import java.net.URI +import java.time.Duration import org.assertj.core.api.Assertions.assertThat import org.awaitility.Awaitility import org.eclipse.californium.core.CoapServer @@ -15,14 +16,11 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Value import org.springframework.boot.test.context.SpringBootTest import org.springframework.core.io.ClassPathResource -import java.net.URI -import java.time.Duration @SpringBootTest class SimulatorIntegrationTest { - @Value("\${simulator.config.uri}") - private lateinit var uri: URI + @Value("\${simulator.config.uri}") private lateinit var uri: URI private val mapper = ObjectMapper() private lateinit var coapServer: CoapServer @@ -33,7 +31,8 @@ class SimulatorIntegrationTest { @BeforeEach fun setup() { coapServer = CoapServer(Configuration.getStandard()) - coapServer.addEndpoint(CoapServerHelpers.createEndpoint(Configuration.getStandard(), uri.port)) + coapServer.addEndpoint( + CoapServerHelpers.createEndpoint(Configuration.getStandard(), uri.port)) coapServer.add(coapResourceStub) coapServer.start() } diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/Application.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/Application.kt index 07501b8..5abd698 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/Application.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/Application.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator import org.gxf.crestdevicesimulator.configuration.SimulatorProperties @@ -10,7 +9,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.runApplication import org.springframework.scheduling.annotation.EnableScheduling - @EnableConfigurationProperties(SimulatorProperties::class) @EnableScheduling @SpringBootApplication diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/AdvancedSingleIdentityPskStore.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/AdvancedSingleIdentityPskStore.kt index dd63637..180fc76 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/AdvancedSingleIdentityPskStore.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/AdvancedSingleIdentityPskStore.kt @@ -1,9 +1,10 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.configuration +import java.net.InetSocketAddress +import javax.crypto.SecretKey import org.eclipse.californium.scandium.dtls.ConnectionId import org.eclipse.californium.scandium.dtls.HandshakeResultHandler import org.eclipse.californium.scandium.dtls.PskPublicInformation @@ -12,8 +13,6 @@ import org.eclipse.californium.scandium.dtls.pskstore.AdvancedPskStore import org.eclipse.californium.scandium.util.SecretUtil import org.eclipse.californium.scandium.util.ServerNames import org.springframework.beans.factory.annotation.Value -import java.net.InetSocketAddress -import javax.crypto.SecretKey class AdvancedSingleIdentityPskStore(private val identity: String) : AdvancedPskStore { @@ -21,23 +20,30 @@ class AdvancedSingleIdentityPskStore(private val identity: String) : AdvancedPsk private const val ALGORITHM = "PSK" } - @Value("\${simulator.config.psk-key}") - lateinit var defaultKey: String + @Value("\${simulator.config.psk-key}") lateinit var defaultKey: String var key: String = "" override fun hasEcdhePskSupported() = true - - override fun requestPskSecretResult(cid: ConnectionId?, serverName: ServerNames?, identity: PskPublicInformation, hmacAlgorithm: String?, otherSecret: SecretKey?, seed: ByteArray?, useExtendedMasterSecret: Boolean): PskSecretResult { + override fun requestPskSecretResult( + cid: ConnectionId?, + serverName: ServerNames?, + identity: PskPublicInformation, + hmacAlgorithm: String?, + otherSecret: SecretKey?, + seed: ByteArray?, + useExtendedMasterSecret: Boolean + ): PskSecretResult { if (key.isEmpty()) { - return PskSecretResult(cid, identity, SecretUtil.create(defaultKey.toByteArray(), ALGORITHM)) + return PskSecretResult( + cid, identity, SecretUtil.create(defaultKey.toByteArray(), ALGORITHM)) } return PskSecretResult(cid, identity, SecretUtil.create(key.toByteArray(), ALGORITHM)) } - override fun getIdentity(peerAddress: InetSocketAddress?, virtualHost: ServerNames?) = PskPublicInformation(identity) - + override fun getIdentity(peerAddress: InetSocketAddress?, virtualHost: ServerNames?) = + PskPublicInformation(identity) override fun setResultHandler(resultHandler: HandshakeResultHandler?) { // No async handler is used, so no implementation needed diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CaliforniumConfiguration.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CaliforniumConfiguration.kt index 2870c69..8db4572 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CaliforniumConfiguration.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CaliforniumConfiguration.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.configuration import org.eclipse.californium.core.config.CoapConfig @@ -25,10 +24,10 @@ class CaliforniumConfiguration(private val simulatorProperties: SimulatorPropert @Bean fun configure(): Configuration { return Configuration.getStandard() - .set(CoapConfig.COAP_PORT, simulatorProperties.uri.port) - .set(CoapConfig.COAP_SECURE_PORT, simulatorProperties.uri.port) - .set(DtlsConfig.DTLS_ROLE, DtlsRole.CLIENT_ONLY) - .set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, false) - .set(DtlsConfig.DTLS_CIPHER_SUITES, simulatorProperties.cipherSuites) + .set(CoapConfig.COAP_PORT, simulatorProperties.uri.port) + .set(CoapConfig.COAP_SECURE_PORT, simulatorProperties.uri.port) + .set(DtlsConfig.DTLS_ROLE, DtlsRole.CLIENT_ONLY) + .set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, false) + .set(DtlsConfig.DTLS_CIPHER_SUITES, simulatorProperties.cipherSuites) } } diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CoapClientConfiguration.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CoapClientConfiguration.kt index a03ce19..4c33a9d 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CoapClientConfiguration.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/CoapClientConfiguration.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.configuration import org.gxf.crestdevicesimulator.simulator.data.entity.PreSharedKey @@ -10,25 +9,26 @@ import org.gxf.crestdevicesimulator.simulator.data.repository.PskRepository import org.springframework.context.annotation.Bean @org.springframework.context.annotation.Configuration -class CoapClientConfiguration(private val simulatorProperties: SimulatorProperties, - private val pskRepository: PskRepository) { +class CoapClientConfiguration( + private val simulatorProperties: SimulatorProperties, + private val pskRepository: PskRepository +) { @Bean fun pskStore(): AdvancedSingleIdentityPskStore { val store = AdvancedSingleIdentityPskStore(simulatorProperties.pskIdentity) - val savedKey = pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( - simulatorProperties.pskIdentity, - PreSharedKeyStatus.ACTIVE - ) + val savedKey = + pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( + simulatorProperties.pskIdentity, PreSharedKeyStatus.ACTIVE) if (savedKey == null) { - val initialPreSharedKey = PreSharedKey( - simulatorProperties.pskIdentity, - 0, - simulatorProperties.pskKey, - simulatorProperties.pskSecret, - PreSharedKeyStatus.ACTIVE - ) + val initialPreSharedKey = + PreSharedKey( + simulatorProperties.pskIdentity, + 0, + simulatorProperties.pskKey, + simulatorProperties.pskSecret, + PreSharedKeyStatus.ACTIVE) pskRepository.save(initialPreSharedKey) store.key = simulatorProperties.pskKey } else { diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/SimulatorProperties.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/SimulatorProperties.kt index 3b32e09..5e06f1b 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/SimulatorProperties.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/configuration/SimulatorProperties.kt @@ -1,26 +1,25 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.configuration +import java.net.URI +import java.time.Duration import org.eclipse.californium.scandium.dtls.cipher.CipherSuite import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.core.io.Resource -import java.net.URI -import java.time.Duration @ConfigurationProperties(prefix = "simulator.config") class SimulatorProperties( - val uri: URI, - val pskIdentity: String, - val pskKey: String, - val pskSecret: String, - val sleepDuration: Duration, - val scheduledMessage: Resource, - val successMessage: Resource, - val failureMessage: Resource, - val rebootSuccessMessage: Resource, - val produceValidCbor: Boolean, - val cipherSuites: List + val uri: URI, + val pskIdentity: String, + val pskKey: String, + val pskSecret: String, + val sleepDuration: Duration, + val scheduledMessage: Resource, + val successMessage: Resource, + val failureMessage: Resource, + val rebootSuccessMessage: Resource, + val produceValidCbor: Boolean, + val cipherSuites: List ) diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/observability/ObservabilityConfiguration.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/observability/ObservabilityConfiguration.kt index 906d1b5..f6bae2d 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/observability/ObservabilityConfiguration.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/observability/ObservabilityConfiguration.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.observability import io.micrometer.observation.ObservationRegistry diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/CborFactory.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/CborFactory.kt index a3ae2ac..07e4d41 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/CborFactory.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/CborFactory.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator import com.fasterxml.jackson.databind.JsonNode diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/Simulator.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/Simulator.kt index 8c92d33..50fc5be 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/Simulator.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/Simulator.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator import com.fasterxml.jackson.databind.JsonNode @@ -39,6 +38,5 @@ class Simulator( } } - fun createMessage(resource: Resource): JsonNode = - mapper.readTree(resource.inputStream) + fun createMessage(resource: Resource): JsonNode = mapper.readTree(resource.inputStream) } diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/coap/CoapClientService.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/coap/CoapClientService.kt index 2e8c4d4..a434562 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/coap/CoapClientService.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/coap/CoapClientService.kt @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 package org.gxf.crestdevicesimulator.simulator.coap +import java.net.InetSocketAddress import org.eclipse.californium.core.CoapClient import org.eclipse.californium.core.coap.CoAP import org.eclipse.californium.core.network.CoapEndpoint @@ -14,13 +15,13 @@ 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) { + private val simulatorProperties: SimulatorProperties, + private val advancedSingleIdentityPskStore: AdvancedSingleIdentityPskStore, + private val configuration: Configuration +) { fun shutdownCoapClient(coapClient: CoapClient) { coapClient.endpoint.stop() @@ -32,7 +33,8 @@ class CoapClientService( val uri = simulatorProperties.uri val coapClient = CoapClient(uri) if (uri.scheme == CoAP.COAP_SECURE_URI_SCHEME) { - val endpoint = CoapEndpoint.Builder() + val endpoint = + CoapEndpoint.Builder() .setConfiguration(configuration) .setConnector(createDtlsConnector(advancedSingleIdentityPskStore)) .build() @@ -41,9 +43,12 @@ class CoapClientService( return coapClient } - private fun createDtlsConnector(advancedSingleIdentityPskStore: AdvancedSingleIdentityPskStore): DTLSConnector { + private fun createDtlsConnector( + advancedSingleIdentityPskStore: AdvancedSingleIdentityPskStore + ): DTLSConnector { val address = InetSocketAddress(0) - val dtlsBuilder = DtlsConnectorConfig.builder(configuration) + val dtlsBuilder = + DtlsConnectorConfig.builder(configuration) .setAddress(address) .setAdvancedPskStore(advancedSingleIdentityPskStore) .setConnectionListener(MdcConnectionListener()) diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/entity/PreSharedKey.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/entity/PreSharedKey.kt index ab35785..440bc0a 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/entity/PreSharedKey.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/entity/PreSharedKey.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.data.entity import jakarta.persistence.Entity diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PreSharedKeyCompositeKey.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PreSharedKeyCompositeKey.kt index 400cc4e..731d095 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PreSharedKeyCompositeKey.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PreSharedKeyCompositeKey.kt @@ -1,14 +1,10 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.data.repository import java.io.Serializable -class PreSharedKeyCompositeKey( - val identity: String?, - val revision: Int? -) : Serializable { +class PreSharedKeyCompositeKey(val identity: String?, val revision: Int?) : Serializable { constructor() : this(null, null) } diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PskRepository.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PskRepository.kt index 53d3a0b..8695223 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PskRepository.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/data/repository/PskRepository.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.data.repository import org.gxf.crestdevicesimulator.simulator.data.entity.PreSharedKey diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandler.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandler.kt index 0c9b43f..1ab0a57 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandler.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandler.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.message import com.fasterxml.jackson.databind.JsonNode @@ -49,7 +48,9 @@ class MessageHandler( try { coapClient = coapClientService.createCoapClient() val response = coapClient.advanced(request) - logger.info { "Received Response: ${response.payload.decodeToString()} with status ${response.code}" } + logger.info { + "Received Response: ${response.payload.decodeToString()} with status ${response.code}" + } handleResponse(response) } catch (e: Exception) { e.printStackTrace() @@ -58,15 +59,14 @@ class MessageHandler( } } - fun createRequest(jsonNode: JsonNode): Request{ + fun createRequest(jsonNode: JsonNode): Request { val payload = if (simulatorProperties.produceValidCbor) CborFactory.createValidCbor(jsonNode) else CborFactory.createInvalidCbor() return Request.newPost() - .apply { - options.setContentFormat(MediaTypeRegistry.APPLICATION_CBOR) - }.setPayload(payload) + .apply { options.setContentFormat(MediaTypeRegistry.APPLICATION_CBOR) } + .setPayload(payload) } private fun handleResponse(response: CoapResponse) { @@ -98,7 +98,9 @@ class MessageHandler( pskService.preparePendingKey(payload) sendPskSetSuccessMessage(payload) } catch (e: Exception) { - logger.error(e) { "PSK change error, send failure message and set pending key status to invalid" } + logger.error(e) { + "PSK change error, send failure message and set pending key status to invalid" + } sendPskSetFailureMessage(payload) pskService.setPendingKeyAsInvalid() } @@ -106,24 +108,21 @@ class MessageHandler( private fun sendPskSetSuccessMessage(pskCommand: String) { logger.info { "Sending success message for command $pskCommand" } - val messageJsonNode = - mapper.readTree(simulatorProperties.successMessage.inputStream) + val messageJsonNode = mapper.readTree(simulatorProperties.successMessage.inputStream) val message = updatePskCommandInMessage(messageJsonNode, URC_PSK_SUCCESS, pskCommand) sendMessage(message) } private fun sendPskSetFailureMessage(pskCommand: String) { logger.warn { "Sending failure message for command $pskCommand" } - val messageJsonNode = - mapper.readTree(simulatorProperties.failureMessage.inputStream) + val messageJsonNode = mapper.readTree(simulatorProperties.failureMessage.inputStream) val message = updatePskCommandInMessage(messageJsonNode, URC_PSK_ERROR, pskCommand) sendMessage(message) } private fun sendRebootSuccesMessage(command: String) { logger.info { "Sending success message for command $command" } - val message = - mapper.readTree(simulatorProperties.rebootSuccessMessage.inputStream) + val message = mapper.readTree(simulatorProperties.rebootSuccessMessage.inputStream) sendMessage(message) } @@ -133,10 +132,10 @@ class MessageHandler( receivedCommand: String ): JsonNode { val newMessage = message as ObjectNode - val urcList = listOf( - TextNode(urc), - ObjectNode(JsonNodeFactory.instance, mapOf(DL_FIELD to TextNode(receivedCommand))) - ) + val urcList = + listOf( + TextNode(urc), + ObjectNode(JsonNodeFactory.instance, mapOf(DL_FIELD to TextNode(receivedCommand)))) val urcArray = mapper.valueToTree(urcList) newMessage.replace(URC_FIELD, urcArray) logger.debug { "Sending message with URC $urcArray" } diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/CommandService.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/CommandService.kt index 328d393..0137d1e 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/CommandService.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/CommandService.kt @@ -1,13 +1,11 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.response import org.springframework.stereotype.Service @Service class CommandService { - fun hasRebootCommand(command: String) = - command.contains("CMD:REBOOT") + fun hasRebootCommand(command: String) = command.contains("CMD:REBOOT") } diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractor.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractor.kt index d1c733a..c22893c 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractor.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractor.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.response import org.gxf.crestdevicesimulator.simulator.response.command.exception.InvalidPskException @@ -9,25 +8,23 @@ import org.gxf.crestdevicesimulator.simulator.response.command.exception.Invalid object PskExtractor { /** - * Regex to split a valid PSK set command in 3 groups - * Group 0 containing everything - * Group 1 containing the next 16 chars after PSK: this is only the key - * Group 2 containing the next 64 chars after the key this is only the hash + * Regex to split a valid PSK set command in 3 groups: Group 0 containing everything; Group 1 + * containing the next 16 chars after PSK: this is only the key; Group 2 containing the next 64 + * chars after the key this is only the hash. */ private val pskKeyHashSplitterRegex = "!PSK:([a-zA-Z0-9]{16}):([a-zA-Z0-9]{64});PSK:[a-zA-Z0-9]{16}:[a-zA-Z0-9]{64}:SET".toRegex() fun hasPskSetCommand(command: String) = pskKeyHashSplitterRegex.matches(command) - fun extractKeyFromCommand(command: String) = - extractGroups(command)[1]!!.value + fun extractKeyFromCommand(command: String) = extractGroups(command)[1]!!.value - fun extractHashFromCommand(command: String)= - extractGroups(command)[2]!!.value + fun extractHashFromCommand(command: String) = extractGroups(command)[2]!!.value private fun extractGroups(command: String): MatchGroupCollection { val matchingGroups = pskKeyHashSplitterRegex.findAll(command) - if (matchingGroups.none()) throw InvalidPskException("Command did not match psk set command") + if (matchingGroups.none()) + throw InvalidPskException("Command did not match psk set command") val groups = matchingGroups.first().groups if (groups.size != 3) throw InvalidPskException("Command did not contain psk and hash") diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskService.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskService.kt index 3656798..0164102 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskService.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskService.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.response.command import io.github.oshai.kotlinlogging.KotlinLogging @@ -30,11 +29,11 @@ class PskService( val newPsk = PskExtractor.extractKeyFromCommand(body) val hash = PskExtractor.extractHashFromCommand(body) - val activePreSharedKey = pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( - simulatorProperties.pskIdentity, - PreSharedKeyStatus.ACTIVE - ) - ?: throw NoSuchElementException("No active psk for identity: ${simulatorProperties.pskIdentity}") + val activePreSharedKey = + pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( + simulatorProperties.pskIdentity, PreSharedKeyStatus.ACTIVE) + ?: throw NoSuchElementException( + "No active psk for identity: ${simulatorProperties.pskIdentity}") logger.info { "Validating hash for identity: ${simulatorProperties.pskIdentity}" } @@ -42,7 +41,8 @@ class PskService( val expectedHash = DigestUtils.sha256Hex("$secret$newPsk") if (expectedHash != hash) { - throw InvalidPskHashException("PSK set Hash for Identity ${simulatorProperties.pskIdentity} did not match") + throw InvalidPskHashException( + "PSK set Hash for Identity ${simulatorProperties.pskIdentity} did not match") } return setNewKeyForIdentity(activePreSharedKey, newPsk) @@ -50,37 +50,34 @@ class PskService( private fun setNewKeyForIdentity(previousPSK: PreSharedKey, newKey: String): PreSharedKey { val newVersion = previousPSK.revision + 1 - logger.debug { "Save new key for identity ${simulatorProperties.pskIdentity} with revision $newVersion and status PENDING" } + logger.debug { + "Save new key for identity ${simulatorProperties.pskIdentity} with revision $newVersion and status PENDING" + } return pskRepository.save( PreSharedKey( previousPSK.identity, newVersion, newKey, previousPSK.secret, - PreSharedKeyStatus.PENDING - ) - ) + PreSharedKeyStatus.PENDING)) } - fun isPendingKeyPresent() = pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( - simulatorProperties.pskIdentity, - PreSharedKeyStatus.PENDING - ) != null + fun isPendingKeyPresent() = + pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( + simulatorProperties.pskIdentity, PreSharedKeyStatus.PENDING) != null fun changeActiveKey() { val identity = simulatorProperties.pskIdentity val currentPsk = pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( - identity, - PreSharedKeyStatus.ACTIVE - ) + identity, PreSharedKeyStatus.ACTIVE) val newPsk = pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( - identity, - PreSharedKeyStatus.PENDING - ) + identity, PreSharedKeyStatus.PENDING) - check(currentPsk != null && newPsk != null) { "No current or new psk, impossible to change active key" } + check(currentPsk != null && newPsk != null) { + "No current or new psk, impossible to change active key" + } currentPsk.status = PreSharedKeyStatus.INACTIVE newPsk.status = PreSharedKeyStatus.ACTIVE @@ -93,9 +90,7 @@ class PskService( val identity = simulatorProperties.pskIdentity val psk = pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( - identity, - PreSharedKeyStatus.PENDING - ) + identity, PreSharedKeyStatus.PENDING) if (psk != null) { psk.status = PreSharedKeyStatus.INVALID diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskException.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskException.kt index e43f983..d01f946 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskException.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskException.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.response.command.exception class InvalidPskException(message: String) : Exception(message) diff --git a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskHashException.kt b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskHashException.kt index 6663db9..4bf9708 100644 --- a/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskHashException.kt +++ b/application/src/main/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/exception/InvalidPskHashException.kt @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Contributors to the GXF project // // SPDX-License-Identifier: Apache-2.0 - package org.gxf.crestdevicesimulator.simulator.response.command.exception class InvalidPskHashException(message: String) : Exception(message) diff --git a/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandlerTests.kt b/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandlerTests.kt index a4cae83..eb65adc 100644 --- a/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandlerTests.kt +++ b/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/message/MessageHandlerTests.kt @@ -23,26 +23,19 @@ import org.springframework.util.ResourceUtils @ExtendWith(MockitoExtension::class) class MessageHandlerTests { - @Spy - private val mapper = ObjectMapper() + @Spy private val mapper = ObjectMapper() - @Mock - private lateinit var simulatorProperties: SimulatorProperties + @Mock private lateinit var simulatorProperties: SimulatorProperties - @Mock - private lateinit var coapClient: CoapClient + @Mock private lateinit var coapClient: CoapClient - @Mock - private lateinit var coapClientService: CoapClientService + @Mock private lateinit var coapClientService: CoapClientService - @Mock - private lateinit var pskService: PskService + @Mock private lateinit var pskService: PskService - @Mock - private lateinit var commandService: CommandService + @Mock private lateinit var commandService: CommandService - @InjectMocks - private lateinit var messageHandler: MessageHandler + @InjectMocks private lateinit var messageHandler: MessageHandler @Test fun shouldSendInvalidCborWhenTheMessageTypeIsInvalidCbor() { @@ -64,6 +57,5 @@ class MessageHandlerTests { assertThat(request.payload).containsExactly(expected.toTypedArray()) } - private fun testFile() = - ResourceUtils.getFile("classpath:test-file.json") + private fun testFile() = ResourceUtils.getFile("classpath:test-file.json") } diff --git a/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractorTest.kt b/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractorTest.kt index 255d748..d33f46a 100644 --- a/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractorTest.kt +++ b/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/PskExtractorTest.kt @@ -7,26 +7,27 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.CsvSource - class PskExtractorTest { companion object { - private const val testHash = "1234567890123456123456789012345612345678901234561234567890123456" - - private const val validPskCommand = "!PSK:1234567891234567:${testHash};PSK:1234567891234567:${testHash}:SET" - private const val validPskCommandWithKeyWordsInKey = "!PSK:PSKaSET1PSKd2SET:${testHash};PSK:PSKaSET1PSKd2SET:${testHash}:SET" - private const val invalidKeySizePskCommand = "!PSK:1234:${testHash};PSK:1234:${testHash}:SET" + private const val testHash = + "1234567890123456123456789012345612345678901234561234567890123456" + + private const val validPskCommand = + "!PSK:1234567891234567:${testHash};PSK:1234567891234567:${testHash}:SET" + private const val validPskCommandWithKeyWordsInKey = + "!PSK:PSKaSET1PSKd2SET:${testHash};PSK:PSKaSET1PSKd2SET:${testHash}:SET" + private const val invalidKeySizePskCommand = + "!PSK:1234:${testHash};PSK:1234:${testHash}:SET" private const val notPskCommand = "NoPskCommandInThisString" } - @ParameterizedTest @CsvSource( - "$validPskCommand, true", - "$validPskCommandWithKeyWordsInKey, true", - "$invalidKeySizePskCommand, false", - "$notPskCommand, false" - ) + "$validPskCommand, true", + "$validPskCommandWithKeyWordsInKey, true", + "$invalidKeySizePskCommand, false", + "$notPskCommand, false") fun shouldReturnTrueWhenThereIsAPskCommandInString(pskCommand: String, isValid: Boolean) { val result = PskExtractor.hasPskSetCommand(pskCommand) assertThat(result).isEqualTo(isValid) @@ -34,9 +35,7 @@ class PskExtractorTest { @ParameterizedTest @CsvSource( - "$validPskCommand, 1234567891234567", - "$validPskCommandWithKeyWordsInKey, PSKaSET1PSKd2SET" - ) + "$validPskCommand, 1234567891234567", "$validPskCommandWithKeyWordsInKey, PSKaSET1PSKd2SET") fun shouldReturnPskKeyFromValidPskCommand(pskCommand: String, expectedKey: String) { val result = PskExtractor.extractKeyFromCommand(pskCommand) @@ -44,10 +43,7 @@ class PskExtractorTest { } @ParameterizedTest - @CsvSource( - "$validPskCommand, $testHash", - "$validPskCommandWithKeyWordsInKey, $testHash" - ) + @CsvSource("$validPskCommand, $testHash", "$validPskCommandWithKeyWordsInKey, $testHash") fun shouldReturnHashFromValidPskCommand(pskCommand: String, expectedHash: String) { val result = PskExtractor.extractHashFromCommand(pskCommand) diff --git a/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskServiceTest.kt b/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskServiceTest.kt index d897f21..721edde 100644 --- a/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskServiceTest.kt +++ b/application/src/test/kotlin/org/gxf/crestdevicesimulator/simulator/response/command/PskServiceTest.kt @@ -29,17 +29,14 @@ import org.mockito.kotlin.whenever @ExtendWith(MockitoExtension::class) class PskServiceTest { - @Mock - private lateinit var pskRepository: PskRepository + @Mock private lateinit var pskRepository: PskRepository - @Mock - private lateinit var simulatorProperties: SimulatorProperties + @Mock private lateinit var simulatorProperties: SimulatorProperties @Mock(answer = Answers.CALLS_REAL_METHODS) private lateinit var pskStore: AdvancedSingleIdentityPskStore - @InjectMocks - private lateinit var pskService: PskService + @InjectMocks private lateinit var pskService: PskService private val newKey = "7654321987654321" @@ -58,14 +55,11 @@ class PskServiceTest { whenever(simulatorProperties.pskIdentity).thenReturn(identity) val psk = PreSharedKey(identity, oldRevision, oldKey, secret, PreSharedKeyStatus.ACTIVE) lenient().whenever(simulatorProperties.pskIdentity).thenReturn(identity) - lenient().whenever( - pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( - identity, - PreSharedKeyStatus.ACTIVE - ) - ).thenReturn( - psk - ) + lenient() + .whenever( + pskRepository.findFirstByIdentityAndStatusOrderByRevisionDesc( + identity, PreSharedKeyStatus.ACTIVE)) + .thenReturn(psk) pskStore.key = oldKey } @@ -73,13 +67,7 @@ class PskServiceTest { fun shouldSetNewPskInStoreWhenTheKeyIsValid() { val expectedHash = DigestUtils.sha256Hex("$secret$newKey") val pskCommand = "!PSK:$newKey:${expectedHash};PSK:$newKey:${expectedHash}:SET" - val psk = PreSharedKey( - identity, - newRevision, - newKey, - secret, - PreSharedKeyStatus.PENDING - ) + val psk = PreSharedKey(identity, newRevision, newKey, secret, PreSharedKeyStatus.PENDING) whenever(pskRepository.save(any())).thenReturn(psk) val result = pskService.preparePendingKey(pskCommand) @@ -92,10 +80,8 @@ class PskServiceTest { val invalidHash = DigestUtils.sha256Hex("invalid") val pskCommand = "!PSK:$oldKey;PSK:$oldKey:${invalidHash}:SET" - val thrownException = catchException { - pskService.preparePendingKey(pskCommand) - } - + val thrownException = catchException { pskService.preparePendingKey(pskCommand) } + assertThat(thrownException).isInstanceOf(InvalidPskException::class.java) verify(pskRepository, never()).save(any()) assertThat(pskStore.key).isEqualTo(oldKey) @@ -106,9 +92,7 @@ class PskServiceTest { val invalidHash = DigestUtils.sha256Hex("invalid") val pskCommand = "!PSK:$oldKey:$invalidHash;PSK:$oldKey:${invalidHash}:SET" - val thrownException = catchException { - pskService.preparePendingKey(pskCommand) - } + val thrownException = catchException { pskService.preparePendingKey(pskCommand) } assertThat(thrownException).isInstanceOf(InvalidPskHashException::class.java) verify(pskRepository, never()).save(any()) diff --git a/build.gradle.kts b/build.gradle.kts index 708dc9e..f92be74 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 +import com.diffplug.gradle.spotless.SpotlessExtension import com.github.davidmc24.gradle.plugin.avro.GenerateAvroJavaTask import io.spring.gradle.dependencymanagement.internal.dsl.StandardDependencyManagementExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension @@ -15,6 +16,7 @@ plugins { kotlin("plugin.spring") version "2.0.20" apply false kotlin("plugin.jpa") version "2.0.20" apply false id("com.github.davidmc24.gradle.plugin.avro") version "1.9.1" apply false + id("com.diffplug.spotless") version "6.25.0" id("org.sonarqube") version "5.1.0.4882" id("eclipse") } @@ -34,6 +36,7 @@ subprojects { apply(plugin = "org.jetbrains.kotlin.jvm") apply(plugin = "org.jetbrains.kotlin.plugin.spring") apply(plugin = "io.spring.dependency-management") + apply(plugin = "com.diffplug.spotless") apply(plugin = "eclipse") apply(plugin = "org.jetbrains.kotlin.plugin.jpa") apply(plugin = "jacoco") @@ -46,6 +49,17 @@ subprojects { mavenCentral() } + extensions.configure { + kotlin { + // by default the target is every '.kt' and '.kts' file in the java source sets + ktfmt().dropboxStyle() + licenseHeaderFile( + "${project.rootDir}/license-template.kt", + "package") + .updateYearWithLatest(false) + } + } + extensions.configure { imports { mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) } } @@ -59,8 +73,18 @@ subprojects { } } + tasks.register("updateGitHooks") { + description = "Copies the pre-commit Git Hook to the .git/hooks folder." + group = "verification" + from("${project.rootDir}/scripts/pre-commit") + into("${project.rootDir}/.git/hooks") + } + tasks.withType { - dependsOn(tasks.withType()) + dependsOn( + tasks.withType(), + tasks.named("updateGitHooks") + ) } tasks.withType { diff --git a/license-template.kt b/license-template.kt new file mode 100644 index 0000000..878d7ea --- /dev/null +++ b/license-template.kt @@ -0,0 +1,3 @@ +// SPDX-FileCopyrightText: Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 diff --git a/scripts/pre-commit b/scripts/pre-commit new file mode 100755 index 0000000..7c2770c --- /dev/null +++ b/scripts/pre-commit @@ -0,0 +1,33 @@ +#!/bin/bash +echo "*********************************************************" +echo "Running git pre-commit hook. Running Spotless Apply... " +echo "*********************************************************" + +# Gather the staged files - to make sure changes are saved only for these files. +stagedFiles=$(git diff --staged --name-only) + +# run spotless apply +./gradlew spotlessApply + +status=$? + +if [ "$status" = 0 ] ; then + echo "Static analysis found no problems." + # Add staged file changes to git + for file in $stagedFiles; do + if test -f "$file"; then + git add $file + fi + done + #Exit + exit 0 +else + echo "*********************************************************" + echo " ******************************************** " + echo 1>&2 "Spotless Apply found violations it could not fix." + echo "Run spotless apply in your terminal and fix the issues before trying to commit again." + echo " ******************************************** " + echo "*********************************************************" + #Exit + exit 1 +fi