Skip to content

Commit

Permalink
Pivotal ID # 172817960: Resubmit Notfication (#253)
Browse files Browse the repository at this point in the history
* Pivotal ID # 172817960: Resubmit Notfication

- Create an extended user endpoint
- Use the endpoint to get the user information in the notifications side
  • Loading branch information
jhoanmanuelms authored Aug 10, 2020
1 parent ad95fb8 commit f130dba
Show file tree
Hide file tree
Showing 14 changed files with 235 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@ class SubmissionSubmitted(
@JsonProperty("accNo")
val accNo: String,

@JsonProperty("ownerFullName")
val ownerFullName: String,

@JsonProperty("notificationsEnabled")
val notificationsEnabled: Boolean,

@JsonProperty("uiUrl")
val uiUrl: String,

@JsonProperty("pagetabUrl")
val pagetabUrl: String,

@JsonProperty("extTabUrl")
val extTabUrl: String
val extTabUrl: String,

@JsonProperty("extUserUrl")
val extUserUrl: String
) : Serializable
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,10 @@ data class ExtSubmission(
val accessTags: List<ExtAccessTag> = listOf(),
val section: ExtSection
)

data class ExtUser(
val email: String,
val fullName: String,
val login: String?,
val notificationsEnabled: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ac.uk.ebi.biostd.handlers.api

import ebi.ac.uk.extended.model.ExtSubmission
import ebi.ac.uk.extended.model.ExtUser
import org.springframework.web.client.RestTemplate
import org.springframework.web.client.getForObject
import uk.ac.ebi.extended.serialization.service.ExtSerializationService
Expand All @@ -11,4 +12,6 @@ class BioStudiesWebConsumer(
) {
fun getExtSubmission(url: String): ExtSubmission =
extSerializationService.deserialize(restTemplate.getForObject(url), ExtSubmission::class.java)

fun getExtUser(url: String): ExtUser = restTemplate.getForObject(url)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ class SubmissionNotificationsListener(
@RabbitListener(queues = [NOTIFICATIONS_QUEUE])
fun receiveMessage(message: SubmissionSubmitted) {
logger.info { "notification for ${ message.accNo }" }
val extUser = webConsumer.getExtUser(message.extUserUrl)

if (message.notificationsEnabled) {
if (extUser.notificationsEnabled) {
val submission = webConsumer.getExtSubmission(message.extTabUrl)
rtNotificationService.notifySuccessfulSubmission(submission, message.ownerFullName, message.uiUrl)
rtNotificationService.notifySuccessfulSubmission(submission, extUser.fullName, message.uiUrl)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ac.uk.ebi.biostd.handlers.api

import ebi.ac.uk.extended.model.ExtSubmission
import ebi.ac.uk.extended.model.ExtUser
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
Expand Down Expand Up @@ -32,4 +33,13 @@ class BioStudiesWebConsumerTest(
verify { restTemplate.getForObject<String>(url) }
verify { extSerializationService.deserialize("the-submission", ExtSubmission::class.java) }
}

@Test
fun `get extended user`(@MockK extUser: ExtUser) {
val url = "http://biostudy:8788/security/user/extended/5"

every { restTemplate.getForObject<ExtUser>(url) } returns extUser

assertThat(testInstance.getExtUser(url)).isEqualTo(extUser)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ac.uk.ebi.biostd.handlers.listeners
import ac.uk.ebi.biostd.handlers.api.BioStudiesWebConsumer
import ebi.ac.uk.extended.events.SubmissionSubmitted
import ebi.ac.uk.extended.model.ExtSubmission
import ebi.ac.uk.extended.model.ExtUser
import ebi.ac.uk.notifications.service.RtNotificationService
import io.mockk.clearAllMocks
import io.mockk.every
Expand All @@ -16,6 +17,7 @@ import org.junit.jupiter.api.extension.ExtendWith

@ExtendWith(MockKExtension::class)
class SubmissionNotificationsListenerTest(
@MockK private val submitter: ExtUser,
@MockK private val submission: ExtSubmission,
@MockK private val message: SubmissionSubmitted,
@MockK private val webConsumer: BioStudiesWebConsumer,
Expand All @@ -26,6 +28,8 @@ class SubmissionNotificationsListenerTest(
@BeforeEach
fun beforeEach() {
mockMessage()
mockSubmitter()
every { webConsumer.getExtUser("ext-user-url") } returns submitter
every { webConsumer.getExtSubmission("ext-tab-url") } returns submission
every { rtNotificationService.notifySuccessfulSubmission(submission, "Dr Owner", "ui-url") } answers { nothing }
}
Expand All @@ -43,7 +47,7 @@ class SubmissionNotificationsListenerTest(

@Test
fun `notifications disabled`() {
every { message.notificationsEnabled } returns false
every { submitter.notificationsEnabled } returns false

testInstance.receiveMessage(message)

Expand All @@ -54,7 +58,11 @@ class SubmissionNotificationsListenerTest(
private fun mockMessage() {
every { message.uiUrl } returns "ui-url"
every { message.extTabUrl } returns "ext-tab-url"
every { message.ownerFullName } returns "Dr Owner"
every { message.notificationsEnabled } returns true
every { message.extUserUrl } returns "ext-user-url"
}

private fun mockSubmitter() {
every { submitter.fullName } returns "Dr Owner"
every { submitter.notificationsEnabled } returns true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ac.uk.ebi.biostd.persistence.service.UserPermissionsService
import ac.uk.ebi.biostd.security.web.SecurityMapper
import ac.uk.ebi.biostd.security.web.exception.SecurityAccessDeniedHandler
import ac.uk.ebi.biostd.security.web.exception.SecurityAuthEntryPoint
import ac.uk.ebi.biostd.security.domain.service.ExtUserService
import com.fasterxml.jackson.databind.ObjectMapper
import ebi.ac.uk.security.integration.SecurityModuleConfig
import ebi.ac.uk.security.integration.components.IGroupService
Expand Down Expand Up @@ -45,6 +46,7 @@ class SecurityConfig(
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(GET, "/security/users/extended/**").permitAll()
.antMatchers(GET, "/submissions/extended/*").permitAll()
.antMatchers(GET, "/submissions/*").permitAll()
.antMatchers("/auth/**").permitAll()
Expand Down Expand Up @@ -111,4 +113,7 @@ class SecurityBeansConfig(private val objectMapper: ObjectMapper, properties: Ap

@Bean
fun preRegister(securityConfig: SecurityModuleConfig): Observable<UserRegister> = securityConfig.userRegister

@Bean
fun extUserService(userDataRepository: UserDataRepository): ExtUserService = ExtUserService(userDataRepository)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ class EventsService(
fun submissionSubmitted(submission: ExtSubmission, user: SecurityUser) {
val submissionNotification = SubmissionSubmitted(
accNo = submission.accNo,
ownerFullName = user.fullName,
notificationsEnabled = user.notificationsEnabled,
uiUrl = properties.instanceBaseUrl,
pagetabUrl = "${properties.instanceBaseUrl}/submissions/${submission.accNo}.json",
extTabUrl = "${properties.instanceBaseUrl}/submissions/extended/${submission.accNo}")
extTabUrl = "${properties.instanceBaseUrl}/submissions/extended/${submission.accNo}",
extUserUrl = "${properties.instanceBaseUrl}/security/users/extended/${user.email}")

rabbitTemplate.convertAndSend(BIOSTUDIES_EXCHANGE, SUBMISSIONS_ROUTING_KEY, submissionNotification)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ac.uk.ebi.biostd.security.domain.service

import ac.uk.ebi.biostd.persistence.model.DbUser
import ac.uk.ebi.biostd.persistence.repositories.UserDataRepository
import ebi.ac.uk.extended.model.ExtUser
import ebi.ac.uk.security.integration.exception.UserNotFoundByEmailException

class ExtUserService(private val userDataRepository: UserDataRepository) {
fun getExtUser(email: String): ExtUser =
toExtUser(userDataRepository
.findByEmail(email)
.orElseThrow { UserNotFoundByEmailException(email) })

private fun toExtUser(user: DbUser) = ExtUser(
email = user.email,
fullName = user.fullName,
login = user.login,
notificationsEnabled = user.notificationsEnabled)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ac.uk.ebi.biostd.security.web

import ac.uk.ebi.biostd.security.domain.service.ExtUserService
import ebi.ac.uk.extended.model.ExtUser
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/security/users/extended")
@Api(tags = ["Extended User"])
class ExtUserResource(private val extUserService: ExtUserService) {
@GetMapping("/{email:.*}")
@ApiOperation("Get the extended information for a user")
fun getExtUser(
@ApiParam(name = "email", value = "The user email")
@PathVariable email: String
): ExtUser = extUserService.getExtUser(email)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.RestController
class ExtSubmissionResource(private val extSubmissionService: ExtSubmissionService) {
@GetMapping("/{accNo}")
@ApiOperation("Get the extended model for a submission")
@ApiImplicitParam(name = "X-SESSION-TOKEN", value = "User authentication token", required = true, type = "header")
fun getExtended(
@ApiParam(name = "accNo", value = "The submission accNo")
@PathVariable accNo: String
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ac.uk.ebi.biostd.events

import ac.uk.ebi.biostd.common.property.ApplicationProperties
import ebi.ac.uk.extended.events.SubmissionSubmitted
import ebi.ac.uk.extended.model.ExtSubmission
import ebi.ac.uk.security.integration.model.api.SecurityUser
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.slot
import io.mockk.verify
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.amqp.rabbit.core.RabbitTemplate

@ExtendWith(MockKExtension::class)
class EventsServiceTest(
@MockK private val rabbitTemplate: RabbitTemplate,
@MockK private val properties: ApplicationProperties
) {
private val testInstance = EventsService(rabbitTemplate, properties)

@Test
fun submissionSubmitted(
@MockK user: SecurityUser,
@MockK submission: ExtSubmission
) {
val notificationSlot = slot<SubmissionSubmitted>()

every { user.email } returns "test@ebi.ac.uk"
every { submission.accNo } returns "S-BSST0"
every { properties.instanceBaseUrl } returns "http://biostudies:8788"
every {
rabbitTemplate.convertAndSend(BIOSTUDIES_EXCHANGE, SUBMISSIONS_ROUTING_KEY, capture(notificationSlot))
} answers { nothing }

testInstance.submissionSubmitted(submission, user)

val notification = notificationSlot.captured
assertThat(notification.accNo).isEqualTo("S-BSST0")
assertThat(notification.uiUrl).isEqualTo("http://biostudies:8788")
assertThat(notification.pagetabUrl).isEqualTo("http://biostudies:8788/submissions/S-BSST0.json")
assertThat(notification.extTabUrl).isEqualTo("http://biostudies:8788/submissions/extended/S-BSST0")
assertThat(notification.extUserUrl).isEqualTo("http://biostudies:8788/security/users/extended/test@ebi.ac.uk")

verify { rabbitTemplate.convertAndSend(BIOSTUDIES_EXCHANGE, SUBMISSIONS_ROUTING_KEY, notification) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ac.uk.ebi.biostd.security.domain.service

import ac.uk.ebi.biostd.persistence.model.DbUser
import ac.uk.ebi.biostd.persistence.repositories.UserDataRepository
import ebi.ac.uk.security.integration.exception.UserNotFoundByEmailException
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.mockk
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.extension.ExtendWith
import java.util.Optional

@ExtendWith(MockKExtension::class)
class ExtUserServiceTest(@MockK private val userDataRepository: UserDataRepository) {
private val testInstance = ExtUserService(userDataRepository)

@Test
fun getExtUser() {
val user = mockUser()
every { userDataRepository.findByEmail("test@ebi.ac.uk") } returns Optional.of(user)

val extUser = testInstance.getExtUser("test@ebi.ac.uk")
assertThat(extUser.login).isEqualTo("test")
assertThat(extUser.fullName).isEqualTo("Test User")
assertThat(extUser.email).isEqualTo("test@ebi.ac.uk")
assertThat(extUser.notificationsEnabled).isTrue()
}

@Test
fun `non existing user`() {
every { userDataRepository.findByEmail("test@ebi.ac.uk") } returns Optional.empty()

val exception = assertThrows<UserNotFoundByEmailException> { testInstance.getExtUser("test@ebi.ac.uk") }
assertThat(exception.message).isEqualTo("Could not find user with the provided email 'test@ebi.ac.uk'.")
}

private fun mockUser(): DbUser {
val user = mockk<DbUser>()
every { user.login } returns "test"
every { user.fullName } returns "Test User"
every { user.email } returns "test@ebi.ac.uk"
every { user.notificationsEnabled } returns true

return user
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ac.uk.ebi.biostd.submission.web.resources

import ac.uk.ebi.biostd.security.web.ExtUserResource
import ac.uk.ebi.biostd.security.domain.service.ExtUserService
import ebi.ac.uk.dsl.json.jsonObj
import ebi.ac.uk.extended.model.ExtUser
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.verify
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.http.MediaType.APPLICATION_JSON
import org.springframework.test.web.servlet.get
import org.springframework.test.web.servlet.setup.MockMvcBuilders

@ExtendWith(MockKExtension::class)
class ExtUserResourceTest(@MockK private val extUserService: ExtUserService) {
private val mvc = MockMvcBuilders
.standaloneSetup(ExtUserResource(extUserService))
.build()

@Test
fun `get ext user`() {
val expectedJson = jsonObj {
"login" to "test_user"
"fullName" to "Test User"
"email" to "test@ebi.ac.uk"
"notificationsEnabled" to true
}.toString()

every { extUserService.getExtUser("test@ebi.ac.uk") } returns testUser()

mvc.get("/security/users/extended/test@ebi.ac.uk") {
accept = APPLICATION_JSON
}.andExpect {
status { isOk }
content { json(expectedJson) }
}

verify { extUserService.getExtUser("test@ebi.ac.uk") }
}

private fun testUser() = ExtUser(
login = "test_user",
fullName = "Test User",
email = "test@ebi.ac.uk",
notificationsEnabled = true
)
}

0 comments on commit f130dba

Please sign in to comment.