All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.huawei.hilink.c2c.integration.helper.api.HiLinkHelper.kt Maven / Gradle / Ivy

Go to download

The helper library streamlines the HiLink C2C integration and exposes a simple API.

There is a newer version: 1.3.2
Show newest version
package com.huawei.hilink.c2c.integration.helper.api

import com.huawei.hilink.c2c.integration.helper.di.Dependencies
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/**
 * The helper streamlines the HiLink C2C's integration and exposes a simple API.
 *
 * In order to use it please instantiate this class in your code, providing all of the
 * required implementations to the constructor. Then, on the instance obtained,
 * you can call its public methods to process incoming requests and send events
 * back to HiLink cloud.
 *
 * Any errors and crashes detected within your implementations of the interfaces,
 * will be described in the json responses produced by the Helper. Please consider
 * logging all requests and responses (including response body) in your communication with HiLink cloud
 * to leverage that.
 * The error descriptions will contain the name of the interface and method where
 * the issue occurred as well as any custom string of description that you've
 * passed to consumer.onError(...) call, if applicable.
 *
 * @param centralAccessTokenCheckOrNull either an implementation of an AT checker or null. If you choose to implement
 * it, then across other interfaces, you will be getting a [UserInfo.authorizedUserIdOrNull], otherwise it will be null.
 * For details see [CentralAccessTokenCheck].
 * @param accountAssociation your implementation of account linking, mostly responsible for saving the association
 * between huaweiId and user id in the partner's system, and sending the user id back to HiLink cloud.
 * For details see [AccountAssociation]
 * @param deviceDiscovery provides information about user's devices and a mapping between device id and the "type" of
 * the device, as understood by HiLink console - that is "prodId".
 * @param supportedDeviceModels a list of [DeviceConversion] objects, representing device models. You can optionally
 * pass just one object within the list, and then process the requests related to all device models in a single
 * implementation. If you choose to do so, please choose an arbitrary prodId string and always pass it in
 * [DeviceDiscovery.getProdIdByDeviceId] implementation.
 * @param configurationInfo several setup parameters contained within a [ConfigurationInfo] object. Including remote
 * api addresses for events sending and Huawei's OAuth as well as partner's appId and appSecret.
 * @param httpRequestMaker an implementation of [HttpRequestMaker] which allows Helper library to make http request.
 * It is used for sending events, like device status change, to HiLink cloud, including OAuth integration.
 */
public class HiLinkHelper(
    centralAccessTokenCheckOrNull: CentralAccessTokenCheck?,
    accountAssociation: AccountAssociation,
    deviceDiscovery: DeviceDiscovery,
    supportedDeviceModels: List,
    configurationInfo: ConfigurationInfo,
    httpRequestMaker: HttpRequestMaker
) {
    private val helperScope = CoroutineScope(Dispatchers.Unconfined)
    private val dependencies = Dependencies(
        centralAccessTokenCheckOrNull,
        accountAssociation,
        configurationInfo,
        httpRequestMaker,
        deviceDiscovery,
        supportedDeviceModels
    )

    /**
     * Handles incoming HiLink cloud requests. When you receive a request, please just pass it to this method, in
     * the raw JSON form it arrived in. The Helper will parse and process it for you. Please also pass the authorization
     * token, in bearer format.
     *
     * Note: for JVM there is also a synchronous version of this method. If you're interested in it, please use
     * HiLinkHelperExtensionsKT class.
     *
     * @param authorizationHeader AT in bearer format, as included in the request to be processed.
     * @param requestBody raw JSON of the request body to be processed.
     * @param resultCallback a callback of [HttpResponseConsumer] type, through which the processing result, that is
     * the response to be returned to HiLink cloud, is returned.
     */
    public fun processRequest(
        authorizationHeader: String,
        requestBody: String,
        resultCallback: HttpResponseConsumer
    ) {
        helperScope.launch {
            val result = processRequest(authorizationHeader, requestBody)
            resultCallback.onResponse(result)
        }
    }

    /**
     * Sends an event to HiLink cloud, notifying that
     * a given device's state has changed. For example if a device is a lamp, the
     * light can be turned on or off on it.
     * On each change please let HiLink know know using this method.
     *
     * This method requires you to provide a [DeviceSnapshot] object, which can be useful for example when
     * dealing with webHooks which only let you know about the changed deviceServices (features) rather than
     * offering a complete snapshot of the device state. If you want the [DeviceSnapshot] to be generated for you,
     * consider using the [notifyDeviceStatusChangeAuto] which leverages your [DeviceConversion.snapshot]
     * implementation.
     *
     * Note: for JVM there is also a synchronous version of this method. If you're interested in it, please use
     * HiLinkHelperExtensionsKT class.
     *
     * @param userId id of the user, whose device's state we're updating.
     * @param huaweiId HuaweiId of the user, whose device's state was changed. Please use mapping saved in
     * [AccountAssociation.associate]
     * @param deviceSnapshot a snapshot describing the state of the device after the change. Inside the [DeviceSnapshot]
     * object there is a list of deviceServices (features) where you can either place all the deviceServices for the
     * device in question, or just the ones that have been changed.
     */
    public fun notifyDeviceStatusChange(
        userId: String,
        huaweiId: String,
        deviceSnapshot: DeviceSnapshot,
        callback: EventResponseConsumer
    ) {
        helperScope.launch {
            val result = notifyDeviceStatusChange(userId, huaweiId, deviceSnapshot)
            callback.onResponse(result)
        }
    }

    /**
     * Sends an event to HiLink cloud, notifying that
     * a given device's state has changed. For example if a device is a lamp, the
     * light can be turned on or off on it.
     * On each change please let HiLink know know using this method.
     *
     * Uses your [DeviceConversion.snapshot] implementation to prepare a device snapshot to be included in the
     * event. Alternatively, you can use [notifyDeviceStatusChange] where you can pass a ready [DeviceSnapshot]
     * directly. That can be used for example to only include the changed deviceServices (features) of a device,
     * instead of sending all of them (both the changed and the unchanged ones).
     *
     * Note: for JVM there is also a synchronous version of this method. If you're interested in it, please use
     * HiLinkHelperExtensionsKT class.
     *
     * @param accessToken an access token that will be presented in your [DeviceConversion.snapshot] implementation.
     * You can pass a null here, if you don't need authorization in order to run the [DeviceConversion.snapshot]
     * function, if this is the case, please consider implementing [CentralAccessTokenCheck].
     * When a null is passed here, the access token will be a blank string "".
     * @param userId id of the user, whose device's state we're updating.
     * @param huaweiId HuaweiId of the user, whose device's state was changed. Please use mapping saved in
     * [AccountAssociation.associate]
     * @param deviceId id of the device being updated.
     */
    public fun notifyDeviceStatusChangeAuto(
        accessToken: String?,
        userId: String,
        huaweiId: String,
        deviceId: String,
        callback: EventResponseConsumer
    ) {
        helperScope.launch {
            val result = notifyDeviceStatusChangeAuto(accessToken, userId, huaweiId, deviceId)
            callback.onResponse(result)
        }
    }

    /**
     * Sends an event to HiLink cloud, notifying that
     * a given device was added by user, using partner's IOT app.
     *
     * Note: for JVM there is also a synchronous version of this method. If you're interested in it, please use
     * HiLinkHelperExtensionsKT class.
     *
     * @param userId id of the user, who owns the newly added device.
     * @param huaweiId huaweiId of the user who owns the newly added device. Please use mapping saved in
     * [AccountAssociation.associate]
     * @param deviceInfo information about the device and the deviceServices (features) that are available on it,
     * for example a lamp might have a "switch" service for turning the light on and off.
     * Please check the documentation of [DeviceInformation] for more details on what is required and where to get it
     * from.
     */
    public fun notifyDeviceAddition(
        userId: String,
        huaweiId: String,
        deviceInfo: DeviceInformation,
        callback: EventResponseConsumer
    ) {
        helperScope.launch {
            val result = notifyDeviceAddition(userId, huaweiId, deviceInfo)
            callback.onResponse(result)
        }
    }

    /**
     * Sends an event to HiLink cloud, notifying that
     * a given device was added by user, using partner's IOT app.
     *
     * Uses your [DeviceConversion.discover] implementation to prepare a device info block which will be be included
     * in the event. You can also use an overload of this method, where you can pass the [DeviceInformation]
     * object directly.
     *
     * Note: for JVM there is also a synchronous version of this method. If you're interested in it, please use
     * HiLinkHelperExtensionsKT class.
     *
     * @param accessToken an access token that will be presented in your [DeviceConversion.discover] implementation.
     * You can pass a null here, if you don't need authorization in order to run the [DeviceConversion.discover]
     * function, if this is the case, please consider implementing [CentralAccessTokenCheck].
     * When a null is passed here, the access token will be a blank string "".
     * @param userId id of the user, who owns the newly added device.
     * @param huaweiId huaweiId of the user who owns the newly added device. Please use mapping saved in
     * [AccountAssociation.associate]
     * @param deviceId id of the device being added.
     */
    public fun notifyDeviceAdditionAuto(
        accessToken: String?,
        userId: String,
        huaweiId: String,
        deviceId: String,
        callback: EventResponseConsumer
    ) {
        helperScope.launch {
            val result = notifyDeviceAdditionAuto(accessToken, userId, huaweiId, deviceId)
            callback.onResponse(result)
        }
    }

    /**
     * Sends an event to HiLink cloud, notifying that
     * a given device was removed by user, using your IOT app.
     *
     * Note: for JVM there is also a synchronous version of this method. If you're interested in it, please use
     * HiLinkHelperExtensionsKT class.
     *
     * @param userId id of the user, who owns the removed device.
     * @param huaweiId huaweiId of the user who owns the removed device. Please use mapping saved in
     * [AccountAssociation.associate]
     * @param deviceId id of the device that was removed.
     */
    public fun notifyDeviceRemoval(
        userId: String,
        huaweiId: String,
        deviceId: String,
        callback: EventResponseConsumer
    ) {
        helperScope.launch {
            val result = notifyDeviceRemoval(userId, huaweiId, deviceId)
            callback.onResponse(result)
        }
    }

    internal suspend fun processRequest(
        authorizationHeader: String,
        requestBody: String
    ): HttpResponse =
        dependencies.requestProcessor.process(authorizationHeader, requestBody)

    internal suspend fun notifyDeviceStatusChange(
        userId: String,
        huaweiId: String,
        deviceSnapshot: DeviceSnapshot
    ): EventResponse =
        dependencies.eventsWrapper.notifyDeviceChange(userId, huaweiId, deviceSnapshot)

    internal suspend fun notifyDeviceStatusChangeAuto(
        accessToken: String?,
        userId: String,
        huaweiId: String,
        deviceId: String
    ): EventResponse =
        dependencies.eventsWrapper.notifyDeviceChange(accessToken, userId, huaweiId, deviceId)

    internal suspend fun notifyDeviceAddition(
        userId: String,
        huaweiId: String,
        deviceInfo: DeviceInformation
    ): EventResponse =
        dependencies.eventsWrapper.notifyDeviceAddition(userId, huaweiId, deviceInfo)

    internal suspend fun notifyDeviceAdditionAuto(
        accessToken: String?,
        userId: String,
        huaweiId: String,
        deviceId: String
    ): EventResponse =
        dependencies.eventsWrapper.notifyDeviceAddition(accessToken, userId, huaweiId, deviceId)

    internal suspend fun notifyDeviceRemoval(
        userId: String,
        huaweiId: String,
        deviceId: String
    ): EventResponse =
        dependencies.eventsWrapper.notifyDeviceRemoval(userId, huaweiId, deviceId)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy