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

org.somda.sdc.glue.consumer.SdcRemoteDeviceImpl.kt Maven / Gradle / Ivy

Go to download

SDCri is a set of Java libraries that implements a network communication framework conforming with the IEEE 11073 SDC specifications. This project implements the 11073-20702 SDC glue binding.

The newest version!
package org.somda.sdc.glue.consumer

import com.google.common.util.concurrent.AbstractIdleService
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import com.google.inject.assistedinject.Assisted
import com.google.inject.assistedinject.AssistedInject
import com.google.inject.name.Named
import org.apache.commons.lang3.tuple.Pair
import org.apache.logging.log4j.kotlin.Logging
import org.somda.sdc.biceps.common.access.MdibAccessObservable
import org.somda.sdc.biceps.consumer.access.RemoteMdibAccess
import org.somda.sdc.biceps.model.message.AbstractGet
import org.somda.sdc.biceps.model.message.AbstractSet
import org.somda.sdc.biceps.model.message.AbstractSetResponse
import org.somda.sdc.biceps.model.message.GetLocalizedText
import org.somda.sdc.biceps.model.message.GetLocalizedTextResponse
import org.somda.sdc.biceps.model.message.GetSupportedLanguages
import org.somda.sdc.biceps.model.message.GetSupportedLanguagesResponse
import org.somda.sdc.biceps.model.message.OperationInvokedReport
import org.somda.sdc.biceps.model.participant.MdibVersion
import org.somda.sdc.common.CommonConfig
import org.somda.sdc.dpws.DpwsConfig
import org.somda.sdc.dpws.service.HostingServiceProxy
import org.somda.sdc.glue.consumer.helper.HostingServiceLogger
import org.somda.sdc.glue.consumer.localization.LocalizationServiceAccess
import org.somda.sdc.glue.consumer.localization.LocalizationServiceProxy
import org.somda.sdc.glue.consumer.report.ReportProcessor
import org.somda.sdc.glue.consumer.sco.ScoController
import org.somda.sdc.glue.consumer.sco.ScoTransaction
import java.time.Duration
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
import java.util.function.Consumer

/**
 * Default implementation of [SdcRemoteDevice].
 */
@Suppress("LongParameterList") // parameters are injected
class SdcRemoteDeviceImpl @AssistedInject internal constructor(
    @param:Assisted private val hostingServiceProxy: HostingServiceProxy,
    @param:Assisted private val remoteMdibAccess: RemoteMdibAccess,
    @param:Assisted private val reportProcessor: ReportProcessor,
    @param:Assisted private val scoController: ScoController?,
    @param:Assisted private val localizationServiceProxy: LocalizationServiceProxy?,
    @param:Assisted private val watchdog: SdcRemoteDeviceWatchdog,
    @param:Named(DpwsConfig.MAX_WAIT_FOR_FUTURES) private val maxWait: Duration,
    @Named(CommonConfig.INSTANCE_IDENTIFIER) frameworkIdentifier: String
) : AbstractIdleService(), SdcRemoteDevice {

    private val instanceLogger = HostingServiceLogger.getLogger(logger, hostingServiceProxy, frameworkIdentifier)

    override fun getHostingServiceProxy(): HostingServiceProxy {
        checkRunning()
        return hostingServiceProxy
    }

    override fun getMdibAccess(): RemoteMdibAccess {
        checkRunning()
        return remoteMdibAccess
    }

    override fun getMdibAccessObservable(): MdibAccessObservable {
        return remoteMdibAccess
    }

    override fun getSetServiceAccess(): SetServiceAccess {
        checkRunning()
        if (scoController == null) {
            return object : SetServiceAccess {
                override fun  invoke(
                    setRequest: T,
                    responseClass: Class
                ): ListenableFuture> = invoke(setRequest, null, responseClass)

                override fun  invoke(
                    setRequest: T,
                    reportListener: Consumer>?,
                    responseClass: Class
                ): ListenableFuture> {
                    instanceLogger.warn {
                        "Remote device does not provide a set service. ${setRequest.javaClass.simpleName} refused."
                    }
                    return Futures.immediateCancelledFuture()
                }
            }
        }

        return scoController
    }

    override fun registerWatchdogObserver(watchdogObserver: WatchdogObserver) {
        checkRunning()
        watchdog.registerObserver(watchdogObserver)
    }

    override fun unregisterWatchdogObserver(watchdogObserver: WatchdogObserver) {
        checkRunning()
        watchdog.unregisterObserver(watchdogObserver)
    }

    override fun getLocalizationServiceAccess(): LocalizationServiceAccess {
        checkRunning()
        if (localizationServiceProxy == null) {
            fun message(request: AbstractGet) =
                "Remote device does not provide a localization service. ${request.javaClass.simpleName} refused."
            return object : LocalizationServiceAccess {
                override fun getLocalizedText(
                    getLocalizedTextRequest: GetLocalizedText
                ): ListenableFuture {
                    instanceLogger.warn { message(getLocalizedTextRequest) }
                    return Futures.immediateCancelledFuture()
                }

                override fun getSupportedLanguages(
                    getSupportedLanguagesRequest: GetSupportedLanguages
                ): ListenableFuture {
                    instanceLogger.warn { message(getSupportedLanguagesRequest) }
                    return Futures.immediateCancelledFuture()
                }
            }
        }

        return localizationServiceProxy
    }

    @Throws(TimeoutException::class)
    override fun startUp() {
        watchdog.startAsync().awaitRunning(maxWait.seconds, TimeUnit.SECONDS)
    }

    override fun shutDown() {
        try {
            watchdog.stopAsync().awaitTerminated(maxWait.seconds, TimeUnit.SECONDS)
        } catch (e: TimeoutException) {
            instanceLogger.error(e) { "Could not stop the remote device watchdog" }
        }

        try {
            reportProcessor.stopAsync().awaitTerminated(maxWait.seconds, TimeUnit.SECONDS)
        } catch (e: TimeoutException) {
            instanceLogger.error(e) { "Could not stop the report processor" }
        }

        // iterate over copy
        val hostedServices = hostingServiceProxy.hostedServices.values.toList()
        for (hostedService in hostedServices) {
            hostedService.eventSinkAccess.unsubscribeAll()
        }

        remoteMdibAccess.unregisterAllObservers()
    }

    private fun checkRunning() {
        check(isRunning) {
            "Tried to access a disconnected SDC remote device instance " +
                "with EPR address ${hostingServiceProxy.endpointReferenceAddress}"
        }
    }

    companion object : Logging
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy