Split controller for better maintainability
This commit is contained in:
parent
742faa7bf3
commit
9e86e1a593
@ -62,6 +62,18 @@ data class ChartDataset(
|
|||||||
constructor(label: String, color: String, data: List<Double>) : this(label, color, color, data)
|
constructor(label: String, color: String, data: List<Double>) : this(label, color, color, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class AverageData(
|
||||||
|
val monitoring: Double,
|
||||||
|
val controlProcedural: Double,
|
||||||
|
val control: Double,
|
||||||
|
val conservatism: Double,
|
||||||
|
val teamworkCommunications: Double,
|
||||||
|
val teamworkLeadership: Double,
|
||||||
|
val teamworkWorkload: Double,
|
||||||
|
val knowledge: Double,
|
||||||
|
val date: LocalDate
|
||||||
|
)
|
||||||
|
|
||||||
data class AfiPieChart(
|
data class AfiPieChart(
|
||||||
val labels: List<String> = listOf("Monitoring", "Knowledge", "Control", "Conservatism", "Teamwork"),
|
val labels: List<String> = listOf("Monitoring", "Knowledge", "Control", "Conservatism", "Teamwork"),
|
||||||
val datasets: List<AfiPieChartDataset>
|
val datasets: List<AfiPieChartDataset>
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package uk.co.neviyn.observationdatabase.controller
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.core.env.Environment
|
||||||
|
import org.springframework.core.env.get
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import uk.co.neviyn.observationdatabase.GroupObservation
|
||||||
|
import uk.co.neviyn.observationdatabase.GroupObservationInit
|
||||||
|
import uk.co.neviyn.observationdatabase.GroupSessionManager
|
||||||
|
import uk.co.neviyn.observationdatabase.Observation
|
||||||
|
import uk.co.neviyn.observationdatabase.Person
|
||||||
|
import uk.co.neviyn.observationdatabase.PersonRepository
|
||||||
|
import uk.co.neviyn.observationdatabase.SiteRepository
|
||||||
|
import uk.co.neviyn.observationdatabase.TutorRepository
|
||||||
|
import java.net.Inet4Address
|
||||||
|
import java.net.NetworkInterface
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/grpob")
|
||||||
|
@CrossOrigin
|
||||||
|
class GroupSessionController {
|
||||||
|
|
||||||
|
private val logger: Logger = LoggerFactory.getLogger(javaClass)!!
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
lateinit var environment: Environment
|
||||||
|
@Autowired
|
||||||
|
lateinit var siteRepository: SiteRepository
|
||||||
|
@Autowired
|
||||||
|
lateinit var tutorRepository: TutorRepository
|
||||||
|
@Autowired
|
||||||
|
lateinit var observationsController: ObservationsController
|
||||||
|
@Autowired
|
||||||
|
lateinit var personRepository: PersonRepository
|
||||||
|
|
||||||
|
@PostMapping("/start")
|
||||||
|
fun startGroupObservation(initData: GroupObservationInit): Map<String, String> {
|
||||||
|
val site = siteRepository.findById(initData.site)
|
||||||
|
val tutors = tutorRepository.findAllById(initData.tutors).toSet()
|
||||||
|
if (!site.isPresent) {
|
||||||
|
logger.info("Attempted to add Observation without a site.")
|
||||||
|
return mapOf("error" to "Site required")
|
||||||
|
}
|
||||||
|
if (tutors.isEmpty() || tutors.size != initData.tutors.size) {
|
||||||
|
logger.info("Attempted to add Observation without a tutor")
|
||||||
|
return mapOf("error" to "Tutor(s) required")
|
||||||
|
}
|
||||||
|
val sessionId = GroupSessionManager.startNewSession(site.get(), tutors, initData.type, initData.scenarioTitles)
|
||||||
|
return getConnectionDetails().plus("id" to sessionId.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/recover")
|
||||||
|
fun reconnectToGroupObservation(): Map<String, Any> {
|
||||||
|
logger.debug("Previous group observation requested")
|
||||||
|
return getConnectionDetails().plus(mapOf("id" to GroupSessionManager.sessionId.toString(), "observations" to GroupSessionManager.observations))
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/valid/{id}")
|
||||||
|
fun checkGroupObservationValidityById(@PathVariable id: Int): Map<String, Any> {
|
||||||
|
if (GroupSessionManager.isValid(id)) {
|
||||||
|
return mapOf("titles" to GroupSessionManager.scenarioTitles!!)
|
||||||
|
}
|
||||||
|
logger.warn("Group observation requested with id $id but there is no valid session")
|
||||||
|
return mapOf("error" to "no valid session")
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/valid")
|
||||||
|
fun checkGroupObservationValidity(): Boolean {
|
||||||
|
return GroupSessionManager.isValid()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/submit")
|
||||||
|
fun addGroupObservation(observationData: GroupObservation) {
|
||||||
|
if (GroupSessionManager.isValid()) {
|
||||||
|
var observation = Observation(
|
||||||
|
site = GroupSessionManager.site!!,
|
||||||
|
date = LocalDate.now(),
|
||||||
|
type = GroupSessionManager.trainingType!!,
|
||||||
|
observed = observationData.scenarios.joinToString { it.title },
|
||||||
|
monitoring = observationData.scenarios.map { it.monitoring.rating }.average(),
|
||||||
|
conservatism = observationData.scenarios.map { it.conservatism.rating }.average(),
|
||||||
|
controlProcedural = observationData.scenarios.map { it.controlProcedural.rating }.average(),
|
||||||
|
control = observationData.scenarios.map { it.control.rating }.average(),
|
||||||
|
teamworkCommunications = observationData.scenarios.map { it.teamworkCommunications.rating }.average(),
|
||||||
|
teamworkLeadership = observationData.scenarios.map { it.teamworkLeadership.rating }.average(),
|
||||||
|
teamworkWorkload = observationData.scenarios.map { it.teamworkWorkload.rating }.average(),
|
||||||
|
knowledge = observationData.scenarios.map { it.knowledge.rating }.average(),
|
||||||
|
scenarios = observationData.scenarios,
|
||||||
|
tutors = GroupSessionManager.tutors!!,
|
||||||
|
person = personRepository.findFirstByNameLike(observationData.person.toUpperCase()) ?: personRepository.save(Person(name = observationData.person.toUpperCase()))
|
||||||
|
)
|
||||||
|
observation = observationsController.saveObservation(observation)
|
||||||
|
GroupSessionManager.addObservation(observation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/address")
|
||||||
|
fun getConnectionDetails(): Map<String, String> {
|
||||||
|
var ipv4: String? = null
|
||||||
|
var retryCount = 0
|
||||||
|
while (ipv4 == null && retryCount < 3) {
|
||||||
|
ipv4 = NetworkInterface.getNetworkInterfaces().asSequence()
|
||||||
|
.filter { !it.isLoopback }.map { x -> x.inetAddresses.asSequence()
|
||||||
|
.filter { it is Inet4Address }.map { it.hostAddress } }.flatten().firstOrNull()
|
||||||
|
retryCount++
|
||||||
|
Thread.sleep(1_000) // Sleep for 1 second
|
||||||
|
}
|
||||||
|
if (ipv4 != null)
|
||||||
|
return mapOf("ip" to ipv4, "port" to environment["local.server.port"])
|
||||||
|
return mapOf("error" to "Could not determine IP Address")
|
||||||
|
}
|
||||||
|
}
|
@ -1,33 +1,44 @@
|
|||||||
package uk.co.neviyn.observationdatabase
|
package uk.co.neviyn.observationdatabase.controller
|
||||||
|
|
||||||
import org.joda.time.LocalDate
|
import org.joda.time.LocalDate
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.cache.annotation.Cacheable
|
import org.springframework.cache.annotation.Cacheable
|
||||||
import org.springframework.core.env.Environment
|
import org.springframework.web.bind.annotation.CrossOrigin
|
||||||
import org.springframework.core.env.get
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
import org.springframework.web.bind.annotation.PostMapping
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin
|
import uk.co.neviyn.observationdatabase.AfiPieChart
|
||||||
import java.net.Inet4Address
|
import uk.co.neviyn.observationdatabase.AfiPieChartDataset
|
||||||
import java.net.NetworkInterface
|
import uk.co.neviyn.observationdatabase.AverageData
|
||||||
|
import uk.co.neviyn.observationdatabase.ChartData
|
||||||
|
import uk.co.neviyn.observationdatabase.ChartDataset
|
||||||
|
import uk.co.neviyn.observationdatabase.NameValue
|
||||||
|
import uk.co.neviyn.observationdatabase.NewObservation
|
||||||
|
import uk.co.neviyn.observationdatabase.NewSite
|
||||||
|
import uk.co.neviyn.observationdatabase.NewTutor
|
||||||
|
import uk.co.neviyn.observationdatabase.Observation
|
||||||
|
import uk.co.neviyn.observationdatabase.ObservationRepository
|
||||||
|
import uk.co.neviyn.observationdatabase.ObservationsRequest
|
||||||
|
import uk.co.neviyn.observationdatabase.Person
|
||||||
|
import uk.co.neviyn.observationdatabase.PersonRepository
|
||||||
|
import uk.co.neviyn.observationdatabase.Site
|
||||||
|
import uk.co.neviyn.observationdatabase.SiteRepository
|
||||||
|
import uk.co.neviyn.observationdatabase.Tutor
|
||||||
|
import uk.co.neviyn.observationdatabase.TutorRepository
|
||||||
import javax.validation.Valid
|
import javax.validation.Valid
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api")
|
@RequestMapping("/api")
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
class Controller {
|
class ObservationsController {
|
||||||
|
|
||||||
private val logger: Logger = LoggerFactory.getLogger(javaClass)!!
|
private val logger: Logger = LoggerFactory.getLogger(javaClass)!!
|
||||||
|
|
||||||
@Autowired
|
|
||||||
lateinit var environment: Environment
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var siteRepository: SiteRepository
|
lateinit var siteRepository: SiteRepository
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -262,93 +273,4 @@ class Controller {
|
|||||||
}
|
}
|
||||||
return AfiPieChart(AfiPieChartDataset(monitoring, knowledge, control, conservatism, teamwork))
|
return AfiPieChart(AfiPieChartDataset(monitoring, knowledge, control, conservatism, teamwork))
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/grpob/start")
|
|
||||||
fun startGroupObservation(initData: GroupObservationInit): Map<String, String> {
|
|
||||||
val site = siteRepository.findById(initData.site)
|
|
||||||
val tutors = tutorRepository.findAllById(initData.tutors).toSet()
|
|
||||||
if (!site.isPresent) {
|
|
||||||
logger.info("Attempted to add Observation without a site.")
|
|
||||||
return mapOf("error" to "Site required")
|
|
||||||
}
|
|
||||||
if (tutors.isEmpty() || tutors.size != initData.tutors.size) {
|
|
||||||
logger.info("Attempted to add Observation without a tutor")
|
|
||||||
return mapOf("error" to "Tutor(s) required")
|
|
||||||
}
|
|
||||||
val sessionId = GroupSessionManager.startNewSession(site.get(), tutors, initData.type, initData.scenarioTitles)
|
|
||||||
return getConnectionDetails().plus("id" to sessionId.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/grpob/recover")
|
|
||||||
fun reconnectToGroupObservation(): Map<String, Any> {
|
|
||||||
logger.debug("Previous group observation requested")
|
|
||||||
return getConnectionDetails().plus(mapOf("id" to GroupSessionManager.sessionId.toString(), "observations" to GroupSessionManager.observations))
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/grpob/valid/{id}")
|
|
||||||
fun checkGroupObservationValidityById(@PathVariable id: Int): Map<String, Any> {
|
|
||||||
if (GroupSessionManager.isValid(id)) {
|
|
||||||
return mapOf("titles" to GroupSessionManager.scenarioTitles!!)
|
|
||||||
}
|
|
||||||
logger.warn("Group observation requested with id $id but there is no valid session")
|
|
||||||
return mapOf("error" to "no valid session")
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/grpob/valid")
|
|
||||||
fun checkGroupObservationValidity(): Boolean {
|
|
||||||
return GroupSessionManager.isValid()
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/grpob/submit")
|
|
||||||
fun addGroupObservation(observationData: GroupObservation) {
|
|
||||||
if (GroupSessionManager.isValid()) {
|
|
||||||
var observation = Observation(
|
|
||||||
site = GroupSessionManager.site!!,
|
|
||||||
date = LocalDate.now(),
|
|
||||||
type = GroupSessionManager.trainingType!!,
|
|
||||||
observed = observationData.scenarios.joinToString { it.title },
|
|
||||||
monitoring = observationData.scenarios.map { it.monitoring.rating }.average(),
|
|
||||||
conservatism = observationData.scenarios.map { it.conservatism.rating }.average(),
|
|
||||||
controlProcedural = observationData.scenarios.map { it.controlProcedural.rating }.average(),
|
|
||||||
control = observationData.scenarios.map { it.control.rating }.average(),
|
|
||||||
teamworkCommunications = observationData.scenarios.map { it.teamworkCommunications.rating }.average(),
|
|
||||||
teamworkLeadership = observationData.scenarios.map { it.teamworkLeadership.rating }.average(),
|
|
||||||
teamworkWorkload = observationData.scenarios.map { it.teamworkWorkload.rating }.average(),
|
|
||||||
knowledge = observationData.scenarios.map { it.knowledge.rating }.average(),
|
|
||||||
scenarios = observationData.scenarios,
|
|
||||||
tutors = GroupSessionManager.tutors!!,
|
|
||||||
person = personRepository.findFirstByNameLike(observationData.person.toUpperCase()) ?: personRepository.save(Person(name = observationData.person.toUpperCase()))
|
|
||||||
)
|
|
||||||
observation = saveObservation(observation)
|
|
||||||
GroupSessionManager.addObservation(observation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/address")
|
|
||||||
fun getConnectionDetails(): Map<String, String> {
|
|
||||||
var ipv4: String? = null
|
|
||||||
var retryCount = 0
|
|
||||||
while (ipv4 == null && retryCount < 3) {
|
|
||||||
ipv4 = NetworkInterface.getNetworkInterfaces().asSequence()
|
|
||||||
.filter { !it.isLoopback }.map { x -> x.inetAddresses.asSequence()
|
|
||||||
.filter { it is Inet4Address }.map { it.hostAddress } }.flatten().firstOrNull()
|
|
||||||
retryCount++
|
|
||||||
Thread.sleep(1_000) // Sleep for 1 second
|
|
||||||
}
|
|
||||||
if (ipv4 != null)
|
|
||||||
return mapOf("ip" to ipv4, "port" to environment["local.server.port"])
|
|
||||||
return mapOf("error" to "Could not determine IP Address")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class AverageData(
|
|
||||||
val monitoring: Double,
|
|
||||||
val controlProcedural: Double,
|
|
||||||
val control: Double,
|
|
||||||
val conservatism: Double,
|
|
||||||
val teamworkCommunications: Double,
|
|
||||||
val teamworkLeadership: Double,
|
|
||||||
val teamworkWorkload: Double,
|
|
||||||
val knowledge: Double,
|
|
||||||
val date: LocalDate
|
|
||||||
)
|
|
@ -6,16 +6,21 @@ import org.junit.runner.RunWith
|
|||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.boot.test.context.SpringBootTest
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
import org.springframework.test.context.junit4.SpringRunner
|
import org.springframework.test.context.junit4.SpringRunner
|
||||||
|
import uk.co.neviyn.observationdatabase.controller.GroupSessionController
|
||||||
|
import uk.co.neviyn.observationdatabase.controller.ObservationsController
|
||||||
|
|
||||||
@RunWith(SpringRunner::class)
|
@RunWith(SpringRunner::class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class ObservationDatabaseApplicationTests {
|
class ObservationDatabaseApplicationTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var controller: Controller
|
lateinit var observationsController: ObservationsController
|
||||||
|
@Autowired
|
||||||
|
lateinit var groupSessionController: GroupSessionController
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun contextLoads() {
|
fun contextLoads() {
|
||||||
assertNotNull(controller)
|
assertNotNull(observationsController)
|
||||||
|
assertNotNull(groupSessionController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,14 @@ import org.junit.runner.RunWith
|
|||||||
import org.mockito.*
|
import org.mockito.*
|
||||||
import org.mockito.Mockito.*
|
import org.mockito.Mockito.*
|
||||||
import org.mockito.junit.MockitoJUnitRunner
|
import org.mockito.junit.MockitoJUnitRunner
|
||||||
|
import uk.co.neviyn.observationdatabase.controller.ObservationsController
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner::class)
|
@RunWith(MockitoJUnitRunner::class)
|
||||||
class ControllerTest {
|
class ObservationsControllerTest {
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
lateinit var controller: Controller
|
lateinit var controller: ObservationsController
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var siteRepository: SiteRepository
|
lateinit var siteRepository: SiteRepository
|
Loading…
Reference in New Issue
Block a user