Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pivotal #ID 176479720: Mongo Metadata Query #328

Merged
merged 3 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import org.springframework.data.mongodb.repository.Query

interface SubmissionMongoRepository : MongoRepository<DocSubmission, String> {

fun findByAccNo(accNo: String): DocSubmission?

fun existsByAccNo(accNo: String): Boolean

fun getByAccNo(accNo: String): DocSubmission
Expand All @@ -15,6 +17,10 @@ interface SubmissionMongoRepository : MongoRepository<DocSubmission, String> {

fun getByAccNoAndVersionGreaterThan(accNo: String, version: Int): List<DocSubmission>

fun findFirstByAccNoOrderByVersionDesc(accNo: String): DocSubmission?

fun getFirstByAccNo(accNo: String): DocSubmission

@Query(value = "{ 'groupId' : ?0 }", fields = "{ '_id': 0, 'user.\$id':1 }")
fun findAllUserIdByGroupId(accNo: String): List<String?>?
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,7 @@ class MongoDbReposConfig {
): SubmissionRequestDocDataRepository = SubmissionRequestDocDataRepository(submissionRequestRepository)

@Bean
internal fun submissionMetaQueryService(): SubmissionMongoMetaQueryService = SubmissionMongoMetaQueryService()
internal fun submissionMongoMetaQueryService(
submissionDocDataRepository: SubmissionDocDataRepository
): SubmissionMongoMetaQueryService = SubmissionMongoMetaQueryService(submissionDocDataRepository)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,74 @@ package ac.uk.ebi.biostd.persistence.doc.service
import ac.uk.ebi.biostd.persistence.common.model.BasicProject
import ac.uk.ebi.biostd.persistence.common.model.BasicSubmission
import ac.uk.ebi.biostd.persistence.common.service.SubmissionMetaQueryService
import ac.uk.ebi.biostd.persistence.doc.db.data.SubmissionDocDataRepository
import ac.uk.ebi.biostd.persistence.doc.model.DocProcessingStatus
import ac.uk.ebi.biostd.persistence.doc.model.DocSubmission
import ac.uk.ebi.biostd.persistence.doc.model.DocSubmissionMethod
import ac.uk.ebi.biostd.persistence.exception.ProjectNotFoundException
import ac.uk.ebi.biostd.persistence.exception.ProjectWithoutPatternException
import ebi.ac.uk.model.SubmissionMethod
import ebi.ac.uk.model.constants.ProcessingStatus
import ebi.ac.uk.model.constants.SubFields.ACC_NO_TEMPLATE
import java.time.ZoneOffset

class SubmissionMongoMetaQueryService(
private val submissionDocDataRepository: SubmissionDocDataRepository
) : SubmissionMetaQueryService {

class SubmissionMongoMetaQueryService : SubmissionMetaQueryService {
override fun getBasicProject(accNo: String): BasicProject {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should consider changing the notation from "projects" to "collections" which is the new term from the business point of view

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's discuss and address individually this looks like a refactor rather than a clean improvement or something that is part of mongo support.

TODO("Not yet implemented")
val projectDb: DocSubmission? = submissionDocDataRepository.findByAccNo(accNo)
require(projectDb != null) { throw ProjectNotFoundException(accNo) }

val projectPattern = projectDb.attributes.firstOrNull { it.name == ACC_NO_TEMPLATE.value }?.value
?: throw ProjectWithoutPatternException(accNo)

return BasicProject(projectDb.accNo, projectPattern, projectDb.releaseTime?.atOffset(ZoneOffset.UTC))
}

override fun findLatestBasicByAccNo(accNo: String): BasicSubmission? {
return null
return submissionDocDataRepository.findFirstByAccNoOrderByVersionDesc(accNo)?.asBasicSubmission()
}

override fun getAccessTags(accNo: String): List<String> {
return emptyList()
}

override fun existByAccNo(accNo: String): Boolean {
return false
override fun existByAccNo(accNo: String): Boolean =
submissionDocDataRepository.existsByAccNo(accNo)

companion object {

private fun DocProcessingStatus.toProcessingStatus(): ProcessingStatus {
return when (this) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These could all be one-liners

DocProcessingStatus.PROCESSED -> ProcessingStatus.PROCESSED
DocProcessingStatus.PROCESSING -> ProcessingStatus.PROCESSING
DocProcessingStatus.REQUESTED -> ProcessingStatus.REQUESTED
}
}

private fun DocSubmissionMethod.toSubmissionMethod(): SubmissionMethod {
return when (this) {
DocSubmissionMethod.FILE -> SubmissionMethod.FILE
DocSubmissionMethod.PAGE_TAB -> SubmissionMethod.PAGE_TAB
DocSubmissionMethod.UNKNOWN -> SubmissionMethod.UNKNOWN
}
}

fun DocSubmission.asBasicSubmission(): BasicSubmission {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these methods should be part of a DocSubmissionExt class instead of being here

return BasicSubmission(
accNo = accNo,
version = version,
secretKey = secretKey,
title = title,
relPath = relPath,
released = released,
creationTime = creationTime.atOffset(ZoneOffset.UTC),
modificationTime = modificationTime.atOffset(ZoneOffset.UTC),
releaseTime = releaseTime?.atOffset(ZoneOffset.UTC),
status = status.toProcessingStatus(),
method = method.toSubmissionMethod(),
owner = owner)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,41 @@ internal class SubmissionDocDataRepositoryTest {
inner class UpdateStatus {
@Test
fun `successful status update`() {
submissionMongoRepository.save(testDocSubmission("accNo1", 1, PROCESSING))
submissionMongoRepository.save(testDocSubmission("accNo10", 1, PROCESSING))

testInstance.updateStatus(PROCESSED, "accNo1", 1)
testInstance.updateStatus(PROCESSED, "accNo10", 1)

assertThat(submissionMongoRepository.getByAccNo("accNo1").status).isEqualTo(PROCESSED)
assertThat(submissionMongoRepository.getByAccNo("accNo10").status).isEqualTo(PROCESSED)
}

@Test
fun `status should not be updated when version does not match`() {
submissionMongoRepository.save(testDocSubmission("accNo2", 1, PROCESSING))
submissionMongoRepository.save(testDocSubmission("accNo20", 1, PROCESSING))

testInstance.updateStatus(PROCESSED, "accNo2", 3)
testInstance.updateStatus(PROCESSED, "accNo20", 3)

assertThat(submissionMongoRepository.getByAccNo("accNo2").status).isEqualTo(PROCESSING)
assertThat(submissionMongoRepository.getByAccNo("accNo20").status).isEqualTo(PROCESSING)
}
}

@Test
fun `successful status update`() {
submissionMongoRepository.save(testDocSubmission("accNo1", 1, PROCESSING))

testInstance.updateStatus(PROCESSED, "accNo1", 1)

assertThat(submissionMongoRepository.getByAccNo("accNo1").status).isEqualTo(PROCESSED)
}

@Test
fun `status update when version does not match so do not update`() {
submissionMongoRepository.save(testDocSubmission("accNo2", 1, PROCESSING))

testInstance.updateStatus(PROCESSED, "accNo2", 3)

assertThat(submissionMongoRepository.getByAccNo("accNo2").status).isEqualTo(PROCESSING)
}

@Test
fun getCurrentVersion() {
submissionMongoRepository.save(testDocSubmission("accNo3", -1, PROCESSED))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package ac.uk.ebi.biostd.persistence.doc.service

import ac.uk.ebi.biostd.persistence.doc.db.repositories.SubmissionMongoRepository
import ac.uk.ebi.biostd.persistence.doc.integration.MongoDbReposConfig
import ac.uk.ebi.biostd.persistence.doc.model.DocAttribute
import ac.uk.ebi.biostd.persistence.doc.model.DocProcessingStatus
import ac.uk.ebi.biostd.persistence.doc.model.DocSection
import ac.uk.ebi.biostd.persistence.doc.model.DocSubmission
import ac.uk.ebi.biostd.persistence.doc.model.DocSubmissionMethod
import ebi.ac.uk.model.constants.SubFields
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.DynamicPropertyRegistry
import org.springframework.test.context.DynamicPropertySource
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.testcontainers.containers.MongoDBContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers
import org.testcontainers.utility.DockerImageName
import java.time.Instant

@ExtendWith(SpringExtension::class)
@Testcontainers
@SpringBootTest(classes = [MongoDbReposConfig::class])
internal class SubmissionMongoMetaQueryServiceTest {

@Autowired
lateinit var testInstance: SubmissionMongoMetaQueryService

@Autowired
lateinit var submissionMongoRepository: SubmissionMongoRepository

@Test
fun getBasicProject() {
submissionMongoRepository.save(testDocSubmission(
accNo = "accNo1",
version = 1,
status = DocProcessingStatus.PROCESSED,
attributes = listOf(DocAttribute(SubFields.ACC_NO_TEMPLATE.value, "template"))
))

val result = testInstance.getBasicProject("accNo1")

assertThat(result.accNo).isEqualTo("accNo1")
}

@Test
fun findLatestBasicByAccNo() {
submissionMongoRepository.save(testDocSubmission("accNo2", 1, DocProcessingStatus.PROCESSED))
submissionMongoRepository.save(testDocSubmission("accNo2", -2, DocProcessingStatus.PROCESSED))
submissionMongoRepository.save(testDocSubmission("accNo2", 4, DocProcessingStatus.PROCESSED))

val lastVersion = testInstance.findLatestBasicByAccNo("accNo2")

assertThat(lastVersion).isNotNull()
assertThat(lastVersion!!.version).isEqualTo(4)
}

@Test
fun getAccessTags() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently, you missed this one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes including this last one in another PR, deleting test method now

}

@Test
fun `exists by AccNo when exists`() {
submissionMongoRepository.save(testDocSubmission("accNo3", 1, DocProcessingStatus.PROCESSED))

assertThat(submissionMongoRepository.existsByAccNo("accNo3")).isTrue()
}

@Test
fun `exist by AccNo when don't exists`() {
submissionMongoRepository.save(testDocSubmission("accNo4", 1, DocProcessingStatus.PROCESSED))

assertThat(submissionMongoRepository.existsByAccNo("accNo5")).isFalse()
}

private fun testDocSubmission(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accNo: String,
version: Int,
status: DocProcessingStatus,
attributes: List<DocAttribute> = listOf()
): DocSubmission {
return DocSubmission(
id = "",
accNo = accNo,
version = version,
owner = "",
submitter = "",
title = "",
method = DocSubmissionMethod.PAGE_TAB,
relPath = "",
rootPath = "",
released = true,
secretKey = "",
status = status,
releaseTime = Instant.ofEpochSecond(1),
modificationTime = Instant.ofEpochSecond(2),
creationTime = Instant.ofEpochSecond(3),
section = DocSection(type = ""),
attributes = attributes,
tags = listOf(),
projects = listOf(),
stats = listOf()
)
}

companion object {

@Container
val mongoContainer: MongoDBContainer = MongoDBContainer(DockerImageName.parse("mongo:4.0.10"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Is this the mongo version we should be using and is it the same as the version provided by IT?
  • Maybe we should have this in some sort of constant. Not sure if the versions declared here can be referenced in the code 🤔


@JvmStatic
@DynamicPropertySource
fun propertySource(register: DynamicPropertyRegistry) {
register.add("spring.data.mongodb.uri") { mongoContainer.getReplicaSetUrl("testDb") }
register.add("spring.data.mongodb.database") { "testDb" }
register.add("app.persistence.enableMongo") { "true" }
}
}
}