Skip to content

Commit c0656a7

Browse files
author
Oleksandr Dzhychko
authored
Merge pull request #795 from modelix/fix-merging-versions-in-v1
fix(model-server): fix merging versions through V1-API
2 parents 8338ec8 + fd53d64 commit c0656a7

File tree

2 files changed

+58
-23
lines changed

2 files changed

+58
-23
lines changed

model-server/src/main/kotlin/org/modelix/model/server/handlers/RepositoriesManager.kt

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -277,27 +277,28 @@ class RepositoriesManager(val client: LocalModelClient) : IRepositoriesManager {
277277
* Same as [mergeChanges] but blocking.
278278
* Caller is expected to execute it outside the request thread.
279279
*/
280-
override fun mergeChangesBlocking(branch: BranchReference, newVersionHash: String): String {
281-
return store.runTransaction {
282-
val headHash = getVersionHashBlocking(branch)
283-
val mergedHash = if (headHash == null) {
284-
newVersionHash
285-
} else {
286-
val headVersion = CLVersion(headHash, client.storeCache)
287-
val newVersion = CLVersion(newVersionHash, client.storeCache)
288-
require(headVersion.getTree().getId() == newVersion.getTree().getId()) {
289-
"Attempt to merge a model with ID '${newVersion.getTree().getId()}'" +
290-
" into one with ID '${headVersion.getTree().getId()}'"
280+
override fun mergeChangesBlocking(branch: BranchReference, newVersionHash: String): String =
281+
runWithRepositoryBlocking(branch.repositoryId) {
282+
store.runTransaction {
283+
val headHash = getVersionHashBlocking(branch)
284+
val mergedHash = if (headHash == null) {
285+
newVersionHash
286+
} else {
287+
val headVersion = CLVersion(headHash, client.storeCache)
288+
val newVersion = CLVersion(newVersionHash, client.storeCache)
289+
require(headVersion.getTree().getId() == newVersion.getTree().getId()) {
290+
"Attempt to merge a model with ID '${newVersion.getTree().getId()}'" +
291+
" into one with ID '${headVersion.getTree().getId()}'"
292+
}
293+
val mergedVersion = VersionMerger(client.storeCache, client.idGenerator)
294+
.mergeChange(headVersion, newVersion)
295+
mergedVersion.getContentHash()
291296
}
292-
val mergedVersion = VersionMerger(client.storeCache, client.idGenerator)
293-
.mergeChange(headVersion, newVersion)
294-
mergedVersion.getContentHash()
297+
ensureBranchInList(branch)
298+
putVersionHash(branch, mergedHash)
299+
mergedHash
295300
}
296-
ensureBranchInList(branch)
297-
putVersionHash(branch, mergedHash)
298-
mergedHash
299301
}
300-
}
301302

302303
override suspend fun getVersion(branch: BranchReference): CLVersion? {
303304
return getVersionHash(branch)?.let { getVersion(branch.repositoryId, it) }
@@ -440,6 +441,10 @@ class RepositoriesManager(val client: LocalModelClient) : IRepositoriesManager {
440441
return store.withRepositoryInCoroutine(repository.takeIf { isIsolated(repository) == true }, body)
441442
}
442443

444+
private fun <R> runWithRepositoryBlocking(repository: RepositoryId, body: () -> R): R {
445+
return store.withRepository(repository.takeIf { isIsolated(repository) == true }, body)
446+
}
447+
443448
companion object {
444449
private val LOG = LoggerFactory.getLogger(RepositoriesManager::class.java)
445450
const val KEY_PREFIX = ":v2"

model-server/src/test/kotlin/org/modelix/model/server/handlers/KeyValueLikeModelServerTest.kt

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,33 @@ import kotlinx.serialization.json.Json
2727
import kotlinx.serialization.json.JsonElement
2828
import org.modelix.authorization.installAuthentication
2929
import org.modelix.model.InMemoryModels
30+
import org.modelix.model.client.RestWebModelClient
31+
import org.modelix.model.client2.runWrite
32+
import org.modelix.model.lazy.CLVersion
33+
import org.modelix.model.lazy.RepositoryId
34+
import org.modelix.model.server.createModelClient
3035
import org.modelix.model.server.installDefaultServerPlugins
3136
import org.modelix.model.server.store.InMemoryStoreClient
3237
import org.modelix.model.server.store.LocalModelClient
38+
import org.modelix.model.server.store.forContextRepository
3339
import org.modelix.model.server.store.forGlobalRepository
3440
import kotlin.test.Test
3541
import kotlin.test.assertEquals
42+
import kotlin.test.assertTrue
3643

3744
class KeyValueLikeModelServerTest {
3845

3946
private fun runTest(block: suspend ApplicationTestBuilder.() -> Unit) = testApplication {
40-
val storeClient = InMemoryStoreClient()
41-
val modelClient = LocalModelClient(storeClient.forGlobalRepository())
42-
val repositoriesManager = RepositoriesManager(modelClient)
43-
val handler = KeyValueLikeModelServer(repositoriesManager, modelClient.store, InMemoryModels())
47+
val inMemoryModels = InMemoryModels()
48+
val store = InMemoryStoreClient()
49+
val localModelClient = LocalModelClient(store.forContextRepository())
50+
val repositoriesManager = RepositoriesManager(localModelClient)
4451

4552
application {
4653
installAuthentication(unitTestMode = true)
4754
installDefaultServerPlugins()
48-
handler.init(this)
55+
KeyValueLikeModelServer(repositoriesManager, store.forGlobalRepository(), InMemoryModels()).init(this)
56+
ModelReplicationServer(repositoriesManager, localModelClient, inMemoryModels).init(this)
4957
}
5058

5159
block()
@@ -85,4 +93,26 @@ class KeyValueLikeModelServerTest {
8593
)
8694
assertEquals(expected, actual)
8795
}
96+
97+
@Test
98+
fun `model client V1 can merge versions`() = runTest {
99+
val clientV1 = RestWebModelClient(baseUrl = "http://localhost/", providedClient = client)
100+
val clientV2 = createModelClient()
101+
val repositoryId = RepositoryId("repo1")
102+
val branchA = repositoryId.getBranchReference("branchA")
103+
val branchB = repositoryId.getBranchReference("branchB")
104+
clientV2.initRepositoryWithLegacyStorage(repositoryId)
105+
clientV2.runWrite(branchA) { rootNode ->
106+
rootNode.setPropertyValue("propertyA", "valueA")
107+
}
108+
clientV2.runWrite(branchB) { rootNode ->
109+
rootNode.setPropertyValue("propertyB", "valueB")
110+
}
111+
val branchBHash = clientV2.pullHash(branchB)
112+
113+
clientV1.putA(branchA.getKey(), branchBHash)
114+
115+
val branchAVersion = clientV2.pull(branchA, null) as CLVersion
116+
assertTrue(branchAVersion.isMerge())
117+
}
88118
}

0 commit comments

Comments
 (0)