Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions kotlin-wot-binding-http/src/main/kotlin/http/HttpProtocolServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ open class HttpProtocolServer(
private val wait: Boolean = false,
private val bindHost: String = "0.0.0.0",
private val bindPort: Int = 8080,
private var baseUrls: List<String> = listOf("http://localhost:8080"),
private val createServer: (host: String, port: Int, servient: Servient) -> EmbeddedServer<*, *> = ::defaultServer
) : ProtocolServer {
val things: MutableMap<String, ExposedThing> = mutableMapOf()
var started = false
private var server: EmbeddedServer<*, *>? = null
private var actualAddresses: List<String> = listOf("http://$bindHost:$bindPort")

companion object {
private val log = LoggerFactory.getLogger(HttpProtocolServer::class.java)
Expand Down Expand Up @@ -77,27 +77,27 @@ open class HttpProtocolServer(
log.info("Exposing thing '{}' on HttpProtocolServer", thing.id)
things[thing.id] = thing

for (address in actualAddresses) {
for (baseUrl in baseUrls) {
for (contentType in ContentManager.offeredMediaTypes) {
// make reporting of all properties optional?
val href = "$address/${thing.id}/all/properties"
val href = "$baseUrl/${thing.id}/all/properties"
val form = Form(href = href, contentType = contentType, op = listOf( Operation.READ_ALL_PROPERTIES,
Operation.READ_MULTIPLE_PROPERTIES))

thing.forms += form
log.debug("Assign '{}' for reading all properties", href)

exposeProperties(thing, address, contentType)
exposeActions(thing, address, contentType)
exposeEvents(thing, address, contentType)
exposeProperties(thing, baseUrl, contentType)
exposeActions(thing, baseUrl, contentType)
exposeEvents(thing, baseUrl, contentType)
}
}
}

internal fun exposeProperties(thing: ExposedThing, address: String, contentType: String) {
internal fun exposeProperties(thing: ExposedThing, baseUrl: String, contentType: String) {
thing.properties.forEach { (name, property) ->

val href = getHrefWithVariablePattern(address, thing, "properties", name, property)
val href = getHrefWithVariablePattern(baseUrl, thing, "properties", name, property)

// Determine the operations based on readOnly/writeOnly status
val operations = when {
Expand Down Expand Up @@ -138,9 +138,9 @@ open class HttpProtocolServer(
}
}

internal fun exposeActions(thing: ExposedThing, address: String, contentType: String) {
internal fun exposeActions(thing: ExposedThing, baseUrl: String, contentType: String) {
thing.actions.forEach { (name, action) ->
val href: String = getHrefWithVariablePattern(address, thing, "actions", name, action)
val href: String = getHrefWithVariablePattern(baseUrl, thing, "actions", name, action)
// Initialize the form using named parameters
val form = Form(
href = href,
Expand All @@ -154,9 +154,9 @@ open class HttpProtocolServer(
}
}

internal fun exposeEvents(thing: ExposedThing, address: String, contentType: String) {
internal fun exposeEvents(thing: ExposedThing, baseUrl: String, contentType: String) {
thing.events.forEach { (name, event) ->
val href = getHrefWithVariablePattern(address, thing, "events", name, event)
val href = getHrefWithVariablePattern(baseUrl, thing, "events", name, event)

// Create the form using named parameters directly
val form = Form(
Expand All @@ -173,7 +173,7 @@ open class HttpProtocolServer(
}

private fun getHrefWithVariablePattern(
address: String,
baseUrl: String,
thing: ExposedThing,
type: String,
interactionName: String,
Expand All @@ -184,7 +184,7 @@ open class HttpProtocolServer(
if (!uriVariables.isNullOrEmpty()) {
variables = "{?" + java.lang.String.join(",", uriVariables) + "}"
}
return "$address/${thing.id}/$type/$interactionName$variables"
return "$baseUrl/${thing.id}/$type/$interactionName$variables"
}

// Destroy a thing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ class HttpProtocolServerTest {
// Assert
assertTrue(exposedThing.forms.isNotEmpty(), "Expected forms to be added to thing")

val expectedHref = "http://0.0.0.0:8080/${exposedThing.id}/all/properties"
val expectedHref = "http://localhost:8080/${exposedThing.id}/all/properties"
val form = exposedThing.forms.find { it.href == expectedHref }
assertNotNull(form, "Expected form for reading all properties to be added")
assertEquals(CONTENT_TYPE, form.contentType)
Expand All @@ -406,12 +406,12 @@ class HttpProtocolServerTest {
fun `exposeProperties should add forms for read write properties`() {
// Arrange
server.started = true
val address = "http://0.0.0.0:8080"
val baseUrl = "http://localhost:8080"
// Act
server.exposeProperties(exposedThing, address, CONTENT_TYPE)
server.exposeProperties(exposedThing, baseUrl, CONTENT_TYPE)

// Assert
val expectedHref = "$address/${exposedThing.id}/properties/$PROPERTY_NAME"
val expectedHref = "$baseUrl/${exposedThing.id}/properties/$PROPERTY_NAME"
val form = exposedThing.properties[PROPERTY_NAME]?.forms?.find { it.href == expectedHref }
assertNotNull(form, "Expected form for property '$PROPERTY_NAME' to be added")

Expand All @@ -422,12 +422,12 @@ class HttpProtocolServerTest {
fun `exposeActions should add form for action`() {
// Arrange
server.started = true
val address = "http://0.0.0.0:8080"
val baseUrl = "http://localhost:8080"
// Act
server.exposeActions(exposedThing, address, CONTENT_TYPE)
server.exposeActions(exposedThing, baseUrl, CONTENT_TYPE)

// Assert
val expectedHref = "$address/${exposedThing.id}/actions/$ACTION_NAME"
val expectedHref = "$baseUrl/${exposedThing.id}/actions/$ACTION_NAME"
val form = exposedThing.actions[ACTION_NAME]?.forms?.find { it.href == expectedHref }
assertNotNull(form, "Expected form for action 'action1' to be added")
assertEquals(CONTENT_TYPE, form.contentType, "Content type should match")
Expand All @@ -439,12 +439,12 @@ class HttpProtocolServerTest {
fun `exposeEvents should add form for event`() {
// Arrange
server.started = true
val address = "http://0.0.0.0:8080"
val baseUrl = "http://localhost:8080"
// Act
server.exposeEvents(exposedThing, address, CONTENT_TYPE)
server.exposeEvents(exposedThing, baseUrl, CONTENT_TYPE)

// Assert
val expectedHref = "$address/${exposedThing.id}/events/$EVENT_NAME"
val expectedHref = "$baseUrl/${exposedThing.id}/events/$EVENT_NAME"
val form = exposedThing.events[EVENT_NAME]?.forms?.find { it.href == expectedHref }
assertNotNull(form, "Expected form for action 'action1' to be added")
assertEquals(CONTENT_TYPE, form.contentType, "Content type should match")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ class WebSocketProtocolServer(
private val wait: Boolean = false,
private val bindHost: String = "0.0.0.0",
private val bindPort: Int = 8080,
private var baseUrls: List<String> = listOf("ws://localhost:8080"),
private val createServer: (host: String, port: Int, servient: Servient) -> EmbeddedServer<*, *> = ::defaultWebSocketServer
) : ProtocolServer {
private val things: MutableMap<String, ExposedThing> = mutableMapOf()

var started = false
private var server: EmbeddedServer<*, *>? = null
private var actualAddresses: List<String> = listOf("ws://$bindHost:$bindPort")

companion object {
private val log = LoggerFactory.getLogger(WebSocketProtocolServer::class.java)
Expand All @@ -70,10 +70,10 @@ class WebSocketProtocolServer(

log.info("Exposing thing '{}'", thing.id)
things[thing.id] = thing
for (address in actualAddresses) {
exposeProperties(thing, address)
exposeActions(thing, address)
exposeEvents(thing, address)
for (baseUrl in baseUrls) {
exposeProperties(thing, baseUrl)
exposeActions(thing, baseUrl)
exposeEvents(thing, baseUrl)
}
}

Expand All @@ -82,10 +82,10 @@ class WebSocketProtocolServer(
things.remove(thing.id)
}

internal fun exposeProperties(thing: ExposedThing, address: String) {
internal fun exposeProperties(thing: ExposedThing, baseUrl: String) {
thing.properties.forEach { (name, property) ->

val href = "$address/ws"
val href = "$baseUrl/ws"

// Combine all operations (read, write, observe, unobserve) into a single form
val operations = mutableListOf<Operation>()
Expand Down Expand Up @@ -113,10 +113,10 @@ class WebSocketProtocolServer(
}
}

internal fun exposeActions(thing: ExposedThing, address: String) {
internal fun exposeActions(thing: ExposedThing, baseUrl: String) {
thing.actions.forEach { (name, action) ->
// Construct the href for the action
val href = "$address/ws" // WebSocket path for actions
val href = "$baseUrl/ws" // WebSocket path for actions

// Create a form for invoking the action
val form = Form(
Expand All @@ -132,10 +132,10 @@ class WebSocketProtocolServer(
}
}

internal fun exposeEvents(thing: ExposedThing, address: String) {
internal fun exposeEvents(thing: ExposedThing, baseUrl: String) {
thing.events.forEach { (name, event) ->
// Construct the href for the event
val href = "$address/ws" // WebSocket path for events
val href = "$baseUrl/ws" // WebSocket path for events

// Create a form for subscribing to the event
val form = Form(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ wot:
server:
enabled: true
host: localhost
port: 8080
port: 8181
http:
server:
enabled: false
enabled: true
host: localhost
port: 8080
baseUrls:
- http://localhost:8080
- http://not-existing-external-url:8080
mqtt:
server:
enabled: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@ package ai.ancf.lmos.wot.spring
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.validation.annotation.Validated

open class ServerProperties(
var enabled: Boolean = true,
var host: String = "0.0.0.0",
var port: Int = 8080,
var baseUrls: List<String>
)

@ConfigurationProperties(prefix = "wot.servient.http.server", ignoreUnknownFields = true)
@Validated
data class HttpServerProperties(
var enabled: Boolean = true,
var host: String = "localhost",
var port: Int = 8080
class HttpServerProperties : ServerProperties(
baseUrls = listOf("http://localhost:8080")
)

@ConfigurationProperties(prefix = "wot.servient.websocket.server", ignoreUnknownFields = true)
@Validated
class WebsocketProperties : ServerProperties(
baseUrls = listOf("ws://localhost:8080")
)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ import org.springframework.context.annotation.Configuration


@AutoConfiguration
@EnableConfigurationProperties(CredentialsProperties::class, HttpServerProperties::class, MqttServerProperties::class, MqttClientProperties::class)
@EnableConfigurationProperties(
CredentialsProperties::class,
HttpServerProperties::class,
WebsocketProperties::class,
MqttServerProperties::class,
MqttClientProperties::class
)
class ServientAutoConfiguration {

@Bean
Expand Down Expand Up @@ -55,8 +61,12 @@ class ServientAutoConfiguration {
havingValue = "true",
matchIfMissing = true // By default, enable the server
)
fun webSocketProtocolServer(httpServerProperties: HttpServerProperties): WebSocketProtocolServer {
return WebSocketProtocolServer(bindHost = httpServerProperties.host, bindPort = httpServerProperties.port)
fun webSocketProtocolServer(websocketProperties: WebsocketProperties): WebSocketProtocolServer {
return WebSocketProtocolServer(
bindHost = websocketProperties.host,
bindPort = websocketProperties.port,
baseUrls = websocketProperties.baseUrls
)
}

@Bean
Expand All @@ -83,7 +93,11 @@ class ServientAutoConfiguration {
matchIfMissing = true // By default, enable the server
)
fun httpProtocolServer(httpServerProperties: HttpServerProperties): HttpProtocolServer {
return HttpProtocolServer(bindHost = httpServerProperties.host, bindPort = httpServerProperties.port)
return HttpProtocolServer(
bindHost = httpServerProperties.host,
bindPort = httpServerProperties.port,
baseUrls = httpServerProperties.baseUrls
)
}

@Bean
Expand Down
Loading