Skip to content

Commit a5556a1

Browse files
feat(vdr): a vdr proxy with multiple drivers and tests
Signed-off-by: goncalo-frade-iohk <goncalo.frade@iohk.io>
1 parent 72e1263 commit a5556a1

File tree

2 files changed

+272
-0
lines changed

2 files changed

+272
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package proxy
2+
3+
import interfaces.Driver
4+
import interfaces.URLManager
5+
import interfaces.VDR
6+
7+
class VDRProxyMultiDrivers(
8+
val urlManager: URLManager,
9+
var drivers: Array<Driver>,
10+
override val identifier: String,
11+
override val version: String
12+
): VDR {
13+
14+
class NoDriversException: Exception("The VDR does not have any driver associated")
15+
class NoDriverWithThisSpecificationsException(
16+
driverIdentifier: String?,
17+
driverType: String?,
18+
availableDrivers: Array<Pair<String, String>>
19+
) : Exception(
20+
"The VDR does not have any driver with identifier: '${driverIdentifier ?: "N/A"}' " +
21+
"or type: '${driverType ?: "N/A"}'. " +
22+
"Available drivers are: ${
23+
availableDrivers.joinToString("; ") { (id, type) ->
24+
"driverIdentifier: $id, driverType: $type"
25+
}
26+
}."
27+
)
28+
29+
override fun store(data: ByteArray, metadata: Map<String, String>): String {
30+
if (drivers.isEmpty()) {
31+
throw NoDriversException()
32+
}
33+
34+
val storeResult: Driver.StoreResult
35+
val identifier: String
36+
val type: String
37+
val version: String
38+
if (drivers.size == 1) {
39+
val driver = drivers.first()
40+
identifier = driver.identifier
41+
type = driver.type
42+
version = driver.version
43+
storeResult = driver.store(data, null, metadata)
44+
} else {
45+
val driver = processDriver(metadata)
46+
identifier = driver.identifier
47+
type = driver.type
48+
version = driver.version
49+
storeResult = driver.store(data, null, metadata)
50+
}
51+
52+
return urlManager.createNew(
53+
storeResult.paths,
54+
storeResult.queries + mapOf(Pair("dvrId", identifier), Pair("dvrTp", type), Pair("dvrV", version)),
55+
storeResult.fragment,
56+
storeResult.publicKeys
57+
)
58+
}
59+
60+
override fun get(url: String): ByteArray {
61+
val resolvedUrl = urlManager.resolve(url)
62+
if (drivers.isEmpty()) {
63+
throw NoDriversException()
64+
}
65+
if (drivers.size == 1) {
66+
val driver = drivers.first()
67+
return driver.get(
68+
resolvedUrl.paths,
69+
resolvedUrl.queries,
70+
resolvedUrl.fragment,
71+
resolvedUrl.publicKeys
72+
)
73+
} else {
74+
val driver = processDriver(resolvedUrl.queries)
75+
return driver.get(
76+
resolvedUrl.paths,
77+
resolvedUrl.queries,
78+
resolvedUrl.fragment,
79+
resolvedUrl.publicKeys
80+
)
81+
}
82+
}
83+
84+
override fun remove(url: String, metadata: Map<String, String>) {
85+
val resolvedUrl = urlManager.resolve(url)
86+
if (drivers.isEmpty()) {
87+
throw NoDriversException()
88+
}
89+
if (drivers.size == 1) {
90+
val driver = drivers.first()
91+
driver.remove(
92+
resolvedUrl.paths,
93+
resolvedUrl.queries,
94+
resolvedUrl.fragment,
95+
null,
96+
metadata
97+
)
98+
} else {
99+
val driver = processDriver(resolvedUrl.queries)
100+
driver.remove(
101+
resolvedUrl.paths,
102+
resolvedUrl.queries,
103+
resolvedUrl.fragment,
104+
null,
105+
metadata
106+
)
107+
}
108+
}
109+
110+
private fun processDriver(metadata: Map<String, String>): Driver {
111+
val driverIdentifier = metadata["dvrId"]
112+
val driverType = metadata["dvrTp"]
113+
114+
when {
115+
driverIdentifier != null && driverType != null -> {
116+
return drivers.firstOrNull {
117+
it.identifier == driverIdentifier &&
118+
it.type == driverType
119+
} ?: throw NoDriverWithThisSpecificationsException(
120+
driverIdentifier,
121+
driverType,
122+
drivers.map { Pair(it.identifier, it.type) }.toTypedArray()
123+
)
124+
}
125+
driverIdentifier != null -> {
126+
return drivers.firstOrNull {
127+
it.identifier == driverIdentifier
128+
} ?: throw NoDriverWithThisSpecificationsException(
129+
driverIdentifier,
130+
null,
131+
drivers.map { Pair(it.identifier, it.type) }.toTypedArray()
132+
)
133+
}
134+
driverType != null -> {
135+
return drivers.firstOrNull {
136+
it.type == driverType
137+
} ?: throw NoDriverWithThisSpecificationsException(
138+
null,
139+
driverType,
140+
drivers.map { Pair(it.identifier, it.type) }.toTypedArray()
141+
)
142+
}
143+
else -> {
144+
throw NoDriverWithThisSpecificationsException(
145+
driverIdentifier,
146+
driverType,
147+
drivers.map { Pair(it.identifier, it.type) }.toTypedArray()
148+
)
149+
}
150+
}
151+
}
152+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import org.junit.jupiter.api.Assertions.*
2+
import org.junit.jupiter.api.BeforeEach
3+
import org.junit.jupiter.api.Test
4+
import java.security.PublicKey
5+
import java.util.UUID
6+
import proxy.VDRProxyMultiDrivers
7+
import drivers.InMemoryDriver
8+
import org.junit.jupiter.api.assertThrows
9+
import urlManagers.LocalhostUrlManager
10+
11+
class VDRProxyMultiDriversTest {
12+
13+
private lateinit var urlManager: LocalhostUrlManager
14+
private lateinit var driver1: InMemoryDriver
15+
private lateinit var driver2: InMemoryDriver
16+
private lateinit var vdrProxy: VDRProxyMultiDrivers
17+
18+
@BeforeEach
19+
fun setUp() {
20+
urlManager = LocalhostUrlManager()
21+
driver1 = InMemoryDriver(
22+
identifier = "driver1",
23+
type = "typeA",
24+
version = "1.0",
25+
supportedVersions = arrayOf("1.0", "1.1")
26+
)
27+
driver2 = InMemoryDriver(
28+
identifier = "driver2",
29+
type = "typeB",
30+
version = "2.0",
31+
supportedVersions = arrayOf("2.0")
32+
)
33+
vdrProxy = VDRProxyMultiDrivers(
34+
urlManager = urlManager,
35+
drivers = arrayOf(driver1, driver2),
36+
identifier = "vdrProxy",
37+
version = "1.0"
38+
)
39+
}
40+
41+
@Test
42+
fun `store should throw NoDriversException when no drivers are available`() {
43+
vdrProxy.drivers = arrayOf()
44+
45+
val exception = assertThrows<VDRProxyMultiDrivers.NoDriversException> {
46+
vdrProxy.store("test data".toByteArray(), emptyMap())
47+
}
48+
49+
assertEquals("The VDR does not have any driver associated", exception.message)
50+
}
51+
52+
@Test
53+
fun `store should store data using single driver and return correct URL`() {
54+
val driver = InMemoryDriver(
55+
identifier = "driver1",
56+
type = "typeA",
57+
version = "1.0",
58+
supportedVersions = arrayOf("1.0", "1.1")
59+
)
60+
val vdrProxyTest = VDRProxyMultiDrivers(
61+
urlManager = LocalhostUrlManager(),
62+
drivers = arrayOf(driver),
63+
identifier = "vdrProxy",
64+
version = "1.0"
65+
)
66+
67+
val data = "Sample Data".toByteArray()
68+
val resultUrl = vdrProxyTest.store(data, emptyMap())
69+
70+
val storedUuid = resultUrl.split("?")[1].split("&").find { it.startsWith("dvrId=") }?.split("=")?.get(1)
71+
assertNotNull(storedUuid)
72+
assertFalse(driver.storage.isEmpty())
73+
}
74+
75+
@Test
76+
fun `get should throw NoDriversException when no drivers are available`() {
77+
vdrProxy.drivers = arrayOf()
78+
79+
val exception = assertThrows<VDRProxyMultiDrivers.NoDriversException> {
80+
vdrProxy.get("http://localhost/test/path")
81+
}
82+
83+
assertEquals("The VDR does not have any driver associated", exception.message)
84+
}
85+
86+
@Test
87+
fun `get should retrieve stored data using single driver`() {
88+
val data = "Sample Data".toByteArray()
89+
val uuid = UUID.randomUUID().toString()
90+
driver1.storage[uuid] = data
91+
92+
val url = "http://localhost/path?dvrId=driver1#${uuid}"
93+
val result = vdrProxy.get(url)
94+
95+
assertArrayEquals(data, result)
96+
}
97+
98+
@Test
99+
fun `remove should delete stored data when a valid fragment is provided`() {
100+
val data = "Sample Data".toByteArray()
101+
val uuid = UUID.randomUUID().toString()
102+
driver1.storage[uuid] = data
103+
104+
val url = "http://localhost/path?dvrId=driver1#${uuid}"
105+
vdrProxy.remove(url, emptyMap())
106+
107+
assertFalse(driver1.storage.containsKey(uuid))
108+
}
109+
110+
@Test
111+
fun `remove should throw NoDriversException when no drivers are available`() {
112+
vdrProxy.drivers = arrayOf()
113+
114+
val exception = assertThrows<VDRProxyMultiDrivers.NoDriversException> {
115+
vdrProxy.remove("http://localhost/path", emptyMap())
116+
}
117+
118+
assertEquals("The VDR does not have any driver associated", exception.message)
119+
}
120+
}

0 commit comments

Comments
 (0)