UpnpService as bean

This commit is contained in:
xis 2023-10-19 17:53:36 +02:00
parent ba2cb2b578
commit f5a8a6e982
14 changed files with 110 additions and 52 deletions

View file

@ -45,6 +45,7 @@ dependencies {
implementation 'org.jupnp:org.jupnp:2.7.1' implementation 'org.jupnp:org.jupnp:2.7.1'
implementation 'org.jupnp:org.jupnp.support:2.7.1' implementation 'org.jupnp:org.jupnp.support:2.7.1'
implementation 'org.osgi:org.osgi.service.http:1.2.2'
implementation 'org.apache.httpcomponents:httpclient:4.5.14' implementation 'org.apache.httpcomponents:httpclient:4.5.14'
// to avoid snakeyaml-1.3 vulnerability CVE-2022-1471 // to avoid snakeyaml-1.3 vulnerability CVE-2022-1471
implementation 'org.yaml:snakeyaml:2.2' implementation 'org.yaml:snakeyaml:2.2'

View file

@ -6,15 +6,18 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootContextLoader import org.springframework.boot.test.context.SpringBootContextLoader
import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.web.client.TestRestTemplate import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.context.annotation.Import
import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification import spock.lang.Specification
import support.beans.TestConfig
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT
@ContextConfiguration(loader = SpringBootContextLoader, classes = NextcloudDLNAApp.class) @ContextConfiguration(loader = SpringBootContextLoader, classes = NextcloudDLNAApp.class)
@SpringBootTest(webEnvironment = DEFINED_PORT) @SpringBootTest(webEnvironment = DEFINED_PORT)
@ActiveProfiles("integration") @ActiveProfiles("integration")
@Import(TestConfig.class)
class IntegrationSpecification extends Specification { class IntegrationSpecification extends Specification {
@Autowired @Autowired
private TestRestTemplate restTemplate private TestRestTemplate restTemplate

View file

@ -0,0 +1,7 @@
package support.beans
import org.springframework.context.annotation.ComponentScan
@ComponentScan(["support", "net.schowek.nextclouddlna"])
class TestConfig {
}

View file

@ -0,0 +1,29 @@
package support.beans.dlna.upnp
import org.jupnp.DefaultUpnpServiceConfiguration
import org.jupnp.transport.spi.DatagramIO
import org.jupnp.transport.spi.NetworkAddressFactory
import org.jupnp.transport.spi.StreamClient
import org.jupnp.transport.spi.StreamServer
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Component
@Component
@Profile("integration")
class UpnpServiceConfigurationInt extends DefaultUpnpServiceConfiguration {
@Override
public StreamClient createStreamClient() {
return null
}
@Override
public StreamServer createStreamServer(NetworkAddressFactory networkAddressFactory) {
return null
}
// @Override
// public DatagramIO createDatagramIO(NetworkAddressFactory networkAddressFactory) {
//
// }
}

View file

@ -1,6 +1,6 @@
package net.schowek.nextclouddlna.nextcloud.config package support.beans.nextcloud.config
import net.schowek.nextclouddlna.nextcloud.config.NextcloudAppPathProvider
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Component import org.springframework.stereotype.Component

View file

@ -1,5 +1,6 @@
package net.schowek.nextclouddlna.util package support.beans.util
import net.schowek.nextclouddlna.util.ServerInfoProvider
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Profile import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Component import org.springframework.stereotype.Component

View file

@ -1,4 +1,4 @@
package net.schowek.nextclouddlna.util package support.beans.util
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.web.server.ConfigurableWebServerFactory import org.springframework.boot.web.server.ConfigurableWebServerFactory

View file

@ -3,36 +3,20 @@ package net.schowek.nextclouddlna
import jakarta.annotation.PreDestroy import jakarta.annotation.PreDestroy
import mu.KLogging import mu.KLogging
import net.schowek.nextclouddlna.dlna.media.MediaServer import net.schowek.nextclouddlna.dlna.media.MediaServer
import net.schowek.nextclouddlna.dlna.transport.ApacheStreamClient import org.jupnp.UpnpService
import net.schowek.nextclouddlna.dlna.transport.ApacheStreamClientConfiguration
import net.schowek.nextclouddlna.dlna.transport.MyStreamServerConfiguration
import net.schowek.nextclouddlna.dlna.transport.MyStreamServerImpl
import net.schowek.nextclouddlna.util.ServerInfoProvider
import org.jupnp.DefaultUpnpServiceConfiguration
import org.jupnp.UpnpServiceConfiguration
import org.jupnp.UpnpServiceImpl
import org.jupnp.model.message.StreamRequestMessage import org.jupnp.model.message.StreamRequestMessage
import org.jupnp.model.message.StreamResponseMessage import org.jupnp.model.message.StreamResponseMessage
import org.jupnp.model.message.UpnpResponse import org.jupnp.model.message.UpnpResponse
import org.jupnp.protocol.ProtocolFactory
import org.jupnp.registry.RegistryImpl
import org.jupnp.transport.impl.NetworkAddressFactoryImpl
import org.jupnp.transport.spi.NetworkAddressFactory
import org.springframework.context.event.ContextRefreshedEvent import org.springframework.context.event.ContextRefreshedEvent
import org.springframework.context.event.EventListener import org.springframework.context.event.EventListener
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
import java.net.InetAddress
import java.net.NetworkInterface
@Component @Component
class DlnaService( class DlnaService(
private val mediaServer: MediaServer, private val upnpService: UpnpService,
private val serverInfoProvider: ServerInfoProvider, private val mediaServer: MediaServer
) { ) {
private val addressesToBind: List<String> = listOf(serverInfoProvider.host)
var upnpService = MyUpnpService(MyUpnpServiceConfiguration())
fun start() { fun start() {
upnpService.startup() upnpService.startup()
upnpService.registry.addDevice(mediaServer.device) upnpService.registry.addDevice(mediaServer.device)
@ -61,30 +45,5 @@ class DlnaService(
} }
} }
inner class MyUpnpService(
configuration: UpnpServiceConfiguration
) : UpnpServiceImpl(configuration) {
override fun createRegistry(pf: ProtocolFactory) = RegistryImpl(this)
}
private inner class MyUpnpServiceConfiguration : DefaultUpnpServiceConfiguration(serverInfoProvider.port) {
override fun createStreamClient() =
ApacheStreamClient(ApacheStreamClientConfiguration(syncProtocolExecutorService))
override fun createStreamServer(networkAddressFactory: NetworkAddressFactory) =
MyStreamServerImpl(MyStreamServerConfiguration(networkAddressFactory.streamListenPort))
override fun createNetworkAddressFactory(streamListenPort: Int, multicastResponsePort: Int) =
MyNetworkAddressFactory(streamListenPort, multicastResponsePort)
}
inner class MyNetworkAddressFactory(
streamListenPort: Int,
multicastResponsePort: Int
) : NetworkAddressFactoryImpl(streamListenPort, multicastResponsePort) {
override fun isUsableAddress(iface: NetworkInterface, address: InetAddress) =
addressesToBind.contains(address.hostAddress)
}
companion object : KLogging() companion object : KLogging()
} }

View file

@ -0,0 +1,14 @@
package net.schowek.nextclouddlna.dlna.upnp
import org.jupnp.UpnpServiceConfiguration
import org.jupnp.UpnpServiceImpl
import org.jupnp.protocol.ProtocolFactory
import org.jupnp.registry.RegistryImpl
import org.springframework.stereotype.Component
@Component
class MyUpnpService(
upnpServiceConfiguration: UpnpServiceConfiguration
) : UpnpServiceImpl(upnpServiceConfiguration) {
override fun createRegistry(pf: ProtocolFactory) = RegistryImpl(this)
}

View file

@ -0,0 +1,44 @@
package net.schowek.nextclouddlna.dlna.upnp
import net.schowek.nextclouddlna.dlna.upnp.transport.ApacheStreamClient
import net.schowek.nextclouddlna.dlna.upnp.transport.ApacheStreamClientConfiguration
import net.schowek.nextclouddlna.dlna.upnp.transport.MyStreamServerConfiguration
import net.schowek.nextclouddlna.dlna.upnp.transport.MyStreamServerImpl
import net.schowek.nextclouddlna.util.ServerInfoProvider
import org.jupnp.DefaultUpnpServiceConfiguration
import org.jupnp.transport.impl.NetworkAddressFactoryImpl
import org.jupnp.transport.spi.DatagramIO
import org.jupnp.transport.spi.NetworkAddressFactory
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Component
import java.net.InetAddress
import java.net.NetworkInterface
@Component
@Profile("!integration")
class MyUpnpServiceConfiguration(
private val serverInfoProvider: ServerInfoProvider
) : DefaultUpnpServiceConfiguration(serverInfoProvider.port) {
val addressesToBind = listOf(serverInfoProvider.host)
override fun createStreamClient() =
ApacheStreamClient(ApacheStreamClientConfiguration(syncProtocolExecutorService))
override fun createStreamServer(networkAddressFactory: NetworkAddressFactory) =
MyStreamServerImpl(MyStreamServerConfiguration(networkAddressFactory.streamListenPort))
override fun createDatagramIO(networkAddressFactory: NetworkAddressFactory): DatagramIO<*> {
return super.createDatagramIO(networkAddressFactory)
}
override fun createNetworkAddressFactory(streamListenPort: Int, multicastResponsePort: Int) =
MyNetworkAddressFactory(serverInfoProvider, multicastResponsePort)
inner class MyNetworkAddressFactory(
private val serverInfoProvider: ServerInfoProvider,
multicastResponsePort: Int
) : NetworkAddressFactoryImpl(serverInfoProvider.port, multicastResponsePort) {
override fun isUsableAddress(iface: NetworkInterface, address: InetAddress) =
addressesToBind.contains(address.hostAddress)
}
}

View file

@ -1,4 +1,4 @@
package net.schowek.nextclouddlna.dlna.transport package net.schowek.nextclouddlna.dlna.upnp.transport
import mu.KLogging import mu.KLogging
import org.apache.http.HttpMessage import org.apache.http.HttpMessage

View file

@ -1,4 +1,4 @@
package net.schowek.nextclouddlna.dlna.transport package net.schowek.nextclouddlna.dlna.upnp.transport
import org.jupnp.transport.spi.AbstractStreamClientConfiguration import org.jupnp.transport.spi.AbstractStreamClientConfiguration
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService

View file

@ -1,4 +1,4 @@
package net.schowek.nextclouddlna.dlna.transport package net.schowek.nextclouddlna.dlna.upnp.transport
import org.jupnp.transport.spi.StreamServerConfiguration import org.jupnp.transport.spi.StreamServerConfiguration

View file

@ -1,4 +1,4 @@
package net.schowek.nextclouddlna.dlna.transport package net.schowek.nextclouddlna.dlna.upnp.transport
import mu.KLogging import mu.KLogging
import org.jupnp.transport.Router import org.jupnp.transport.Router