Added some implementation for group multihead session
This commit is contained in:
parent
b7858d0de5
commit
e6f2963e88
@ -25,6 +25,18 @@ data class NewObservation(
|
||||
val person: String
|
||||
)
|
||||
|
||||
data class GroupObservationInit(
|
||||
val site: Long,
|
||||
val type: TrainingType,
|
||||
val tutors: List<Long>,
|
||||
val scenarioTitles: List<String>
|
||||
)
|
||||
|
||||
data class GroupObservation(
|
||||
val scenarios: List<Scenario>,
|
||||
val person: String
|
||||
)
|
||||
|
||||
data class ObservationsRequest(
|
||||
val site: Long?,
|
||||
val tutor: Long?,
|
||||
|
@ -1,18 +1,21 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import org.joda.time.LocalDate
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.cache.annotation.Cacheable
|
||||
import org.springframework.core.env.Environment
|
||||
import org.springframework.core.env.get
|
||||
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.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||
import org.springframework.web.bind.annotation.CrossOrigin
|
||||
import java.net.InetAddress
|
||||
import java.net.Inet4Address
|
||||
import java.net.NetworkInterface
|
||||
import javax.validation.Valid
|
||||
|
||||
@RestController
|
||||
@ -20,10 +23,10 @@ import javax.validation.Valid
|
||||
@CrossOrigin
|
||||
class Controller {
|
||||
|
||||
val logger = LoggerFactory.getLogger(javaClass)
|
||||
private val logger: Logger = LoggerFactory.getLogger(javaClass)!!
|
||||
|
||||
@Autowired
|
||||
lateinit var websocketMessenger: SimpMessagingTemplate
|
||||
lateinit var environment: Environment
|
||||
|
||||
@Autowired
|
||||
lateinit var siteRepository: SiteRepository
|
||||
@ -85,6 +88,18 @@ class Controller {
|
||||
return nameValue
|
||||
}
|
||||
|
||||
fun saveObservation(observation: Observation): Observation {
|
||||
logger.debug("Saving new Observation to database")
|
||||
val committedObservation = observationRepository.save(observation)
|
||||
logger.debug("Adding Observation data to Tutor records")
|
||||
committedObservation.tutors.forEach {
|
||||
it.observations.add(committedObservation)
|
||||
tutorRepository.save(it)
|
||||
}
|
||||
logger.debug("Observation addition completed")
|
||||
return committedObservation
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new observation to the database using data provided in [newObservation].
|
||||
*/
|
||||
@ -118,14 +133,7 @@ class Controller {
|
||||
person = personRepository.findFirstByNameLike(newObservation.person.toUpperCase()) ?: personRepository.save(Person(name = newObservation.person.toUpperCase()))
|
||||
)
|
||||
logger.debug("Saving new Observation to database")
|
||||
observation = observationRepository.save(observation)
|
||||
logger.debug("Adding Observation data to Tutor records")
|
||||
tutors.forEach {
|
||||
it.observations.add(observation)
|
||||
tutorRepository.save(it)
|
||||
}
|
||||
sendObservationToSocket(observation)
|
||||
logger.debug("Observation addition completed")
|
||||
observation = saveObservation(observation)
|
||||
return observation.id
|
||||
}
|
||||
|
||||
@ -255,17 +263,81 @@ class Controller {
|
||||
return AfiPieChart(AfiPieChartDataset(monitoring, knowledge, control, conservatism, teamwork))
|
||||
}
|
||||
|
||||
fun sendObservationToSocket(observation: Observation) {
|
||||
if (::websocketMessenger.isInitialized) {
|
||||
websocketMessenger.convertAndSend("/ws/observations", observation)
|
||||
} else {
|
||||
logger.warn("WebSocket messenger is not initialized. Not sending data to socket.")
|
||||
@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> {
|
||||
return mapOf("ip" to InetAddress.getLocalHost().hostAddress)
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||
import org.springframework.stereotype.Service
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
|
||||
@Service
|
||||
object GroupSessionManager {
|
||||
|
||||
private val logger: Logger = LoggerFactory.getLogger(javaClass)!!
|
||||
|
||||
@Autowired
|
||||
lateinit var websocketMessenger: SimpMessagingTemplate
|
||||
|
||||
var sessionId = ThreadLocalRandom.current().nextInt(1000, 9999)
|
||||
var site: Site? = null
|
||||
var tutors: Set<Tutor>? = null
|
||||
var trainingType: TrainingType? = null
|
||||
var scenarioTitles: List<String>? = null
|
||||
var observations: MutableList<Observation> = mutableListOf()
|
||||
|
||||
fun startNewSession(site: Site, tutors: Set<Tutor>, trainingType: TrainingType, scenarioTitles: List<String>): Int {
|
||||
logger.info("Starting new Group Session")
|
||||
logger.debug("Previous ID was $sessionId")
|
||||
val prevId = sessionId
|
||||
while (sessionId == prevId) {
|
||||
this.sessionId = ThreadLocalRandom.current().nextInt(1000, 9999)
|
||||
}
|
||||
logger.debug("New ID is $sessionId")
|
||||
this.site = site
|
||||
this.tutors = tutors
|
||||
this.trainingType = trainingType
|
||||
this.scenarioTitles = scenarioTitles
|
||||
observations = mutableListOf()
|
||||
logger.debug("Group session initialized")
|
||||
return sessionId
|
||||
}
|
||||
|
||||
fun isValid(sessionId: Int): Boolean {
|
||||
return isValid() && sessionId == this.sessionId
|
||||
}
|
||||
|
||||
fun isValid(): Boolean {
|
||||
return site != null && tutors != null && trainingType != null && scenarioTitles != null
|
||||
}
|
||||
|
||||
fun addObservation(observation: Observation) {
|
||||
observations.add(observation)
|
||||
sendObservationsToSocket()
|
||||
}
|
||||
|
||||
private fun sendObservationsToSocket() {
|
||||
if (::websocketMessenger.isInitialized) {
|
||||
websocketMessenger.convertAndSend("/ws/observations", mapOf("observations" to observations))
|
||||
} else {
|
||||
logger.warn("WebSocket messenger is not initialized. Not sending data to socket.")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user