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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ You can add Xesar-Connect to your project by including it as a dependency in you

## Compatibility

Xesar-Connect is tested with EVVA's Xesar version 3.1 with Mqtt API version 1.2.1 see [EVVA Xesar Mqtt API](https://integrations.api.xesar.evva.com/)
Xesar-Connect is compatible with EVVA's Xesar version 3.3 with Mqtt API version 1.37.0 see [EVVA Xesar Mqtt API](https://integrations.api.xesar.evva.com/)


```kotlin
dependencies {
implementation("com.open200:xesar-connect:1.0.0")
implementation("com.open200:xesar-connect:2.2.0")
}
```

Expand Down
2 changes: 2 additions & 0 deletions xesar-connect/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ val logbackVersion: String = "1.5.17"
val pahoVersion: String = "1.2.5"
val mockkVersion: String = "1.13.17"
val kotestTestcontainersVersion: String = "2.0.2"
val testcontainersVersion: String = "2.0.2"

dependencies {
implementation("org.eclipse.paho:org.eclipse.paho.client.mqttv3:$pahoVersion")
Expand All @@ -52,6 +53,7 @@ dependencies {
testImplementation(
"io.kotest.extensions:kotest-extensions-testcontainers:$kotestTestcontainersVersion"
)
testImplementation("org.testcontainers:testcontainers:$testcontainersVersion")
}

tasks.test { useJUnitPlatform() }
Expand Down
54 changes: 54 additions & 0 deletions xesar-connect/src/main/kotlin/com/open200/xesar/connect/Topics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,44 @@ class Topics(vararg val topics: String) {
/** MQTT topic string for the "SmartphoneAuthorizationsResent" event */
val SMARTPHONE_AUTHORIZATIONS_RESENT = "xs3/1/ces/SmartphoneAuthorizationsResent"

/** MQTT topic string for the "MediumRevoked" event */
val MEDIUM_REVOKED = "xs3/1/ces/MediumRevoked"

/** MQTT topic string for the "MobileRegistrationStateUpdated" event */
val MOBILE_REGISTRATION_STATE_UPDATED = "xs3/1/ces/MobileRegistrationStateUpdated"

/** MQTT topic string for the "AuthorizationProfileMetadataDefinitionsUpdated" event */
val AUTHORIZATION_PROFILE_METADATA_DEFINITIONS_UPDATED =
"xs3/1/ces/AuthorizationProfileMetadataDefinitionsUpdated"

/** MQTT topic string for the "InstallationPointMetadataDefinitionsUpdated" event */
val INSTALLATION_POINT_METADATA_DEFINITIONS_UPDATED =
"xs3/1/ces/InstallationPointMetadataDefinitionsUpdated"

/** MQTT topic string for the "MediumMetadataDefinitionsUpdated" event */
val MEDIUM_METADATA_DEFINITIONS_UPDATED = "xs3/1/ces/MediumMetadataDefinitionsUpdated"

/** MQTT topic string for the "PersonMetadataDefinitionsUpdated" event */
val PERSON_METADATA_DEFINITIONS_UPDATED = "xs3/1/ces/PersonMetadataDefinitionsUpdated"

/** MQTT topic string for the "ZoneMetadataDefinitionsUpdated" event */
val ZONE_METADATA_DEFINITIONS_UPDATED = "xs3/1/ces/ZoneMetadataDefinitionsUpdated"

/** MQTT topic string for the "SmartphoneLocked" event (Self Service Mode) */
val SMARTPHONE_LOCKED = "xs3/1/mss/ces/SmartphoneLocked"

/** MQTT topic string for the "SmartphoneRevokePending" event (Self Service Mode) */
val SMARTPHONE_REVOKE_PENDING = "xs3/1/mss/ces/SmartphoneRevokePending"

/** MQTT topic string for the "SmartphoneRevokeConfirmed" event (Self Service Mode) */
val SMARTPHONE_REVOKE_CONFIRMED = "xs3/1/mss/ces/SmartphoneRevokeConfirmed"

/** MQTT topic string for the "SmartphoneUpdatePending" event (Self Service Mode) */
val SMARTPHONE_UPDATE_PENDING = "xs3/1/mss/ces/SmartphoneUpdatePending"

/** MQTT topic string for the "SmartphoneUpdateConfirmed" event (Self Service Mode) */
val SMARTPHONE_UPDATE_CONFIRMED = "xs3/1/mss/ces/SmartphoneUpdateConfirmed"

/**
* Generates the MQTT topic string which emits errors for previously received queries or
* commands.
Expand Down Expand Up @@ -491,6 +529,22 @@ class Topics(vararg val topics: String) {
/** MQTT topic string for the "ChangeAuthorizationProfileMetadataValueMapi" command. */
val CHANGE_AUTHORIZATION_PROFILE_METADATA_VALUE =
"xs3/1/cmd/ChangeAuthorizationProfileMetadataValueMapi"

/** MQTT topic string for the "RevokeSmartphoneMapi" command. */
val REVOKE_SMARTPHONE = "xs3/1/cmd/RevokeSmartphoneMapi"

/** MQTT topic string for the "UnassignPersonFromMediumMapi" command. */
val UNASSIGN_PERSON_FROM_MEDIUM = "xs3/1/cmd/UnassignPersonFromMediumMapi"

/**
* MQTT topic string for the "ConfirmSmartphoneRevokeMapi" command (Self Service Mode).
*/
val CONFIRM_SMARTPHONE_REVOKE = "xs3/1/mss/cmd/ConfirmSmartphoneRevokeMapi"

/**
* MQTT topic string for the "ConfirmSmartphoneUpdateMapi" command (Self Service Mode).
*/
val CONFIRM_SMARTPHONE_UPDATE = "xs3/1/mss/cmd/ConfirmSmartphoneUpdateMapi"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,22 @@ fun XesarConnect.queryStreamIdentificationMedium(
): Flow<IdentificationMedium> {
return queryStream(IdentificationMedium.QUERY_RESOURCE, params, requestConfig)
}

/**
* Unassigns a person from a medium asynchronously.
*
* @param mediumId The ID of the medium to unassign the person from.
* @param requestConfig The request configuration (optional).
*/
suspend fun XesarConnect.unassignPersonFromMediumAsync(
mediumId: UUID,
requestConfig: XesarConnect.RequestConfig = buildRequestConfig(),
): SingleEventResult<MediumPersonChanged> {
return sendCommandAsync<UnassignPersonFromMediumMapi, MediumPersonChanged>(
Topics.Command.UNASSIGN_PERSON_FROM_MEDIUM,
Topics.Event.MEDIUM_PERSON_CHANGED,
true,
UnassignPersonFromMediumMapi(config.uuidGenerator.generateId(), mediumId, token),
requestConfig,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,74 @@ suspend fun XesarConnect.resendSmartphoneAuthorizationsAsync(
requestConfig,
)
}

/**
* Revokes a smartphone medium asynchronously.
*
* @param id The id of the smartphone medium.
* @param requestConfig The request configuration (optional).
*/
suspend fun XesarConnect.revokeSmartphoneAsync(
id: UUID,
requestConfig: XesarConnect.RequestConfig = buildRequestConfig(),
): SingleEventResult<MediumRevoked> {
return sendCommandAsync<RevokeSmartphoneMapi, MediumRevoked>(
Topics.Command.REVOKE_SMARTPHONE,
Topics.Event.MEDIUM_REVOKED,
true,
RevokeSmartphoneMapi(config.uuidGenerator.generateId(), id, token),
requestConfig,
)
}

/**
* Confirms a smartphone revocation in Self Service Mode asynchronously.
*
* @param mediumId The id of the smartphone medium.
* @param transactionId The id of the transaction.
* @param requestConfig The request configuration (optional).
*/
suspend fun XesarConnect.confirmSmartphoneRevokeAsync(
mediumId: UUID,
transactionId: UUID,
requestConfig: XesarConnect.RequestConfig = buildRequestConfig(),
): SingleEventResult<SmartphoneRevokeConfirmed> {
return sendCommandAsync<ConfirmSmartphoneRevokeMapi, SmartphoneRevokeConfirmed>(
Topics.Command.CONFIRM_SMARTPHONE_REVOKE,
Topics.Event.SMARTPHONE_REVOKE_CONFIRMED,
true,
ConfirmSmartphoneRevokeMapi(
config.uuidGenerator.generateId(),
mediumId,
transactionId,
token,
),
requestConfig,
)
}

/**
* Confirms a smartphone update in Self Service Mode asynchronously.
*
* @param mediumId The id of the smartphone medium.
* @param transactionId The id of the transaction.
* @param requestConfig The request configuration (optional).
*/
suspend fun XesarConnect.confirmSmartphoneUpdateAsync(
mediumId: UUID,
transactionId: UUID,
requestConfig: XesarConnect.RequestConfig = buildRequestConfig(),
): SingleEventResult<SmartphoneUpdateConfirmed> {
return sendCommandAsync<ConfirmSmartphoneUpdateMapi, SmartphoneUpdateConfirmed>(
Topics.Command.CONFIRM_SMARTPHONE_UPDATE,
Topics.Event.SMARTPHONE_UPDATE_CONFIRMED,
true,
ConfirmSmartphoneUpdateMapi(
config.uuidGenerator.generateId(),
mediumId,
transactionId,
token,
),
requestConfig,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.open200.xesar.connect.messages.command

import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents a command POJO to confirm a smartphone revocation in Self Service Mode.
*
* @param commandId The id of the command.
* @param mediumId The id of the smartphone medium.
* @param transactionId The id of the transaction.
* @param token The token of the command.
*/
@Serializable
data class ConfirmSmartphoneRevokeMapi(
override val commandId: @Serializable(with = UUIDSerializer::class) UUID,
val mediumId: @Serializable(with = UUIDSerializer::class) UUID,
val transactionId: @Serializable(with = UUIDSerializer::class) UUID,
val token: String,
) : Command
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.open200.xesar.connect.messages.command

import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents a command POJO to confirm a smartphone update in Self Service Mode.
*
* @param commandId The id of the command.
* @param mediumId The id of the smartphone medium.
* @param transactionId The id of the transaction.
* @param token The token of the command.
*/
@Serializable
data class ConfirmSmartphoneUpdateMapi(
override val commandId: @Serializable(with = UUIDSerializer::class) UUID,
val mediumId: @Serializable(with = UUIDSerializer::class) UUID,
val transactionId: @Serializable(with = UUIDSerializer::class) UUID,
val token: String,
) : Command
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.open200.xesar.connect.messages.command

import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents a command POJO to revoke a smartphone medium.
*
* @param commandId The id of the command.
* @param id The id of the smartphone medium.
* @param token The token of the command.
*/
@Serializable
data class RevokeSmartphoneMapi(
override val commandId: @Serializable(with = UUIDSerializer::class) UUID,
val id: @Serializable(with = UUIDSerializer::class) UUID,
val token: String,
) : Command
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.open200.xesar.connect.messages.command

import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents a command POJO to unassign a person from a medium.
*
* @param commandId The id of the command.
* @param mediumId The id of the medium.
* @param token The token of the command.
*/
@Serializable
data class UnassignPersonFromMediumMapi(
override val commandId: @Serializable(with = UUIDSerializer::class) UUID,
val mediumId: @Serializable(with = UUIDSerializer::class) UUID,
val token: String,
) : Command
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.open200.xesar.connect.messages.event

import com.open200.xesar.connect.messages.EntityMetadata
import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents an event POJO as a response of a command to change of an authorization profile
* metadata definition.
*
* @param entityMetadata Contains the information of the metadata definitions.
* @param id The id of the updated authorization profile.
*/
@Serializable
data class AuthorizationProfileMetadataDefinitionsUpdated(
val entityMetadata: List<EntityMetadata>,
@Serializable(with = UUIDSerializer::class) val id: UUID,
) : Event
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.open200.xesar.connect.messages.event

import com.open200.xesar.connect.messages.EntityMetadata
import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents an event POJO as a response of a command to change of an installation point metadata
* definition.
*
* @param entityMetadata Contains the information of the metadata definitions.
* @param id The id of the updated installation point.
*/
@Serializable
data class InstallationPointMetadataDefinitionsUpdated(
val entityMetadata: List<EntityMetadata>,
@Serializable(with = UUIDSerializer::class) val id: UUID,
) : Event
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.open200.xesar.connect.messages.event

import com.open200.xesar.connect.messages.EntityMetadata
import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents an event POJO as a response of a command to change of a medium metadata definition.
*
* @param entityMetadata Contains the information of the metadata definitions.
* @param id The id of the updated medium.
*/
@Serializable
data class MediumMetadataDefinitionsUpdated(
val entityMetadata: List<EntityMetadata>,
@Serializable(with = UUIDSerializer::class) val id: UUID,
) : Event
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.open200.xesar.connect.messages.event

import com.open200.xesar.connect.utils.LocalDateTimeSerializer
import com.open200.xesar.connect.utils.UUIDSerializer
import java.time.LocalDateTime
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents an event POJO indicating a medium was revoked.
*
* @param aggregateId The id of the medium.
* @param installationPoints The installation points of the medium.
* @param mediumIdentifier The identifier of the medium.
* @param authorizationProfileId The authorization profile id of the medium.
* @param individualAuthorizations The individual authorizations of the medium.
* @param validityEnd The validity end of the medium.
* @param zones The zones of the medium.
* @param hasMasterKeyAccess Whether the medium has master key access.
*/
@Serializable
data class MediumRevoked(
val aggregateId: @Serializable(with = UUIDSerializer::class) UUID,
val installationPoints: List<@Serializable(with = UUIDSerializer::class) UUID> = emptyList(),
val mediumIdentifier: Long,
val authorizationProfileId: @Serializable(with = UUIDSerializer::class) UUID? = null,
val individualAuthorizations: List<@Serializable(with = UUIDSerializer::class) UUID> =
emptyList(),
val validityEnd: @Serializable(with = LocalDateTimeSerializer::class) LocalDateTime? = null,
val zones: List<@Serializable(with = UUIDSerializer::class) UUID> = emptyList(),
val hasMasterKeyAccess: Boolean,
) : Event
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.open200.xesar.connect.messages.event

import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents an event POJO indicating the mobile registration state was updated.
*
* @param id The id of the smartphone medium.
* @param registrationState The new registration state of the smartphone medium.
*/
@Serializable
data class MobileRegistrationStateUpdated(
@Serializable(with = UUIDSerializer::class) val id: UUID,
val registrationState: String? = null,
) : Event
Loading
Loading