Esempio n. 1
0
        public async Task <IActionResult> RemoveParticipantFromConferenceAsync(Guid conferenceId, Guid participantId)
        {
            _logger.LogDebug("RemoveParticipantFromConference");
            var getConferenceByIdQuery = new GetConferenceByIdQuery(conferenceId);
            var queriedConference      =
                await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (queriedConference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var participant = queriedConference.GetParticipants().SingleOrDefault(x => x.Id == participantId);

            if (participant == null)
            {
                _logger.LogWarning("Unable to find participant");
                return(NotFound());
            }

            var participants = new List <Participant> {
                participant
            };
            var command = new RemoveParticipantsFromConferenceCommand(conferenceId, participants);
            await _commandHandler.Handle(command);

            return(NoContent());
        }
Esempio n. 2
0
        public async Task <IActionResult> LeaveConsultationAsync(LeaveConsultationRequest request)
        {
            var getConferenceByIdQuery = new GetConferenceByIdQuery(request.ConferenceId);
            var conference             = await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var participant = conference.GetParticipants().SingleOrDefault(x => x.Id == request.ParticipantId);

            if (participant == null)
            {
                _logger.LogWarning("Unable to find participant request by id");
                return(NotFound());
            }

            if (!participant.CurrentConsultationRoomId.HasValue)
            {
                return(BadRequest("Participant is not in a consultation"));
            }

            await _consultationService.LeaveConsultationAsync(conference.Id, participant.Id, participant.GetCurrentRoom(), RoomType.WaitingRoom.ToString());

            return(Ok());
        }
Esempio n. 3
0
        public async Task <IActionResult> LeavePrivateConsultationAsync(LeaveConsultationRequest request)
        {
            _logger.LogDebug("LeavePrivateConsultation");
            var getConferenceByIdQuery = new GetConferenceByIdQuery(request.ConferenceId);
            var conference             = await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var participant = conference.GetParticipants().SingleOrDefault(x => x.Id == request.ParticipantId);

            if (participant == null)
            {
                _logger.LogWarning("Unable to find participant request by id");
                return(NotFound());
            }

            var currentRoom = participant.CurrentRoom;

            if (!currentRoom.HasValue || (currentRoom != RoomType.ConsultationRoom1 &&
                                          currentRoom != RoomType.ConsultationRoom2))
            {
                // This could only happen when both the participants press 'Close' button at the same time to end the call
                _logger.LogWarning("Participant is not in a consultation to leave from");
                return(NoContent());
            }

            await _videoPlatformService.StopPrivateConsultationAsync(conference, currentRoom.Value);

            return(NoContent());
        }
        public async Task <IActionResult> BookNewConferenceAsync(BookNewConferenceRequest request)
        {
            _logger.LogDebug("BookNewConference");

            foreach (var participant in request.Participants)
            {
                participant.Username    = participant.Username.ToLower().Trim();
                participant.Name        = participant.Name.Trim();
                participant.FirstName   = participant.FirstName.Trim();
                participant.LastName    = participant.LastName.Trim();
                participant.DisplayName = participant.DisplayName.Trim();
            }

            var createAudioRecordingResponse = await CreateAudioApplicationWithRetryAsync(request);

            if (!createAudioRecordingResponse.Success)
            {
                return(StatusCode((int)createAudioRecordingResponse.StatusCode, createAudioRecordingResponse.Message));
            }

            var conferenceId = await CreateConferenceWithRetiesAsync(request, createAudioRecordingResponse.IngestUrl);

            _logger.LogDebug("Conference Created");

            var conferenceEndpoints =
                await _queryHandler.Handle <GetEndpointsForConferenceQuery, IList <Endpoint> >(
                    new GetEndpointsForConferenceQuery(conferenceId));

            var endpointDtos = conferenceEndpoints.Select(EndpointMapper.MapToEndpoint);

            var kinlyBookedSuccess = await BookKinlyMeetingRoomWithRetriesAsync(conferenceId, request.AudioRecordingRequired,
                                                                                createAudioRecordingResponse.IngestUrl, endpointDtos);

            if (!kinlyBookedSuccess)
            {
                var message = $"Could not book and find kinly meeting room for conferenceId: {conferenceId}";
                _logger.LogError(message);
                return(StatusCode((int)HttpStatusCode.InternalServerError, message));
            }

            _logger.LogDebug("Kinly Room Booked");

            var getConferenceByIdQuery = new GetConferenceByIdQuery(conferenceId);
            var queriedConference      =
                await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            var response =
                ConferenceToDetailsResponseMapper.MapConferenceToResponse(queriedConference,
                                                                          _kinlyConfiguration.PexipSelfTestNode);

            _logger.LogInformation("Created conference {ResponseId} for hearing {HearingRefId}", response.Id, request.HearingRefId);

            return(CreatedAtAction("GetConferenceDetailsById", new { conferenceId = response.Id }, response));
        }
Esempio n. 5
0
        public async Task <IActionResult> RespondToConsultationRequestAsync(ConsultationRequestResponse request)
        {
            var getConferenceByIdQuery = new GetConferenceByIdQuery(request.ConferenceId);
            var conference             = await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var requestedBy = conference.GetParticipants().SingleOrDefault(x => x.Id == request.RequestedBy);

            if (request.RequestedBy != Guid.Empty && requestedBy == null)
            {
                _logger.LogWarning("Unable to find participant request by with id {RequestedBy}", request.RequestedBy);
                return(NotFound());
            }

            var requestedFor = conference.GetParticipants().SingleOrDefault(x => x.Id == request.RequestedFor);

            if (requestedFor == null)
            {
                _logger.LogWarning("Unable to find participant request for with id {RequestedFor}", request.RequestedFor);
                return(NotFound());
            }

            if (string.IsNullOrEmpty(request.RoomLabel))
            {
                _logger.LogWarning("Please provide a room label");
                return(NotFound());
            }

            if (request.Answer != ConsultationAnswer.Accepted)
            {
                _logger.LogWarning($"Answered {request.Answer}");
                return(NoContent());
            }

            var displayName = requestedFor.GetParticipantRoom()?.Label ?? requestedFor.DisplayName;
            var command     = new SaveEventCommand(conference.Id, Guid.NewGuid().ToString(), EventType.Consultation,
                                                   DateTime.UtcNow, null, null, $"Adding {displayName} to {request.RoomLabel}", null)
            {
                ParticipantId = request.RequestedBy
            };
            await _commandHandler.Handle(command);

            await _consultationService.ParticipantTransferToRoomAsync(request.ConferenceId, requestedFor.Id, request.RoomLabel);

            return(NoContent());
        }
Esempio n. 6
0
        public async Task <IActionResult> HandleConsultationRequestAsync(ConsultationRequest request)
        {
            _logger.LogDebug("HandleConsultationRequest");
            var getConferenceByIdQuery = new GetConferenceByIdQuery(request.ConferenceId);
            var conference             = await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var requestedBy = conference.GetParticipants().SingleOrDefault(x => x.Id == request.RequestedBy);

            if (requestedBy == null)
            {
                _logger.LogWarning("Unable to find participant request by with id {RequestedBy}", request.RequestedBy);
                return(NotFound());
            }

            var requestedFor = conference.GetParticipants().SingleOrDefault(x => x.Id == request.RequestedFor);

            if (requestedFor == null)
            {
                _logger.LogWarning("Unable to find participant request for with id {RequestedFor}", request.RequestedFor);
                return(NotFound());
            }

            var command = new SaveEventCommand(conference.Id, Guid.NewGuid().ToString(), EventType.Consultation,
                                               DateTime.UtcNow, null, null, $"Consultation with {requestedFor.DisplayName}", null)
            {
                ParticipantId = requestedBy.Id
            };
            await _commandHandler.Handle(command);

            try
            {
                await InitiateStartConsultationAsync(conference, requestedBy, requestedFor, request.Answer.GetValueOrDefault());
            }
            catch (DomainRuleException ex)
            {
                _logger.LogError(ex, "No consultation room available for conference");
                ModelState.AddModelError("ConsultationRoom", "No consultation room available");
                return(BadRequest(ModelState));
            }

            return(NoContent());
        }
Esempio n. 7
0
        public async Task <IActionResult> StartPrivateConsultationWithEndpointAsync(EndpointConsultationRequest request)
        {
            _logger.LogDebug("StartPrivateConsultationWithEndpoint");

            var getConferenceByIdQuery = new GetConferenceByIdQuery(request.ConferenceId);
            var conference             =
                await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound($"Unable to find conference {request.ConferenceId}"));
            }

            var endpoint = conference.GetEndpoints().SingleOrDefault(x => x.Id == request.EndpointId);

            if (endpoint == null)
            {
                _logger.LogWarning("Unable to find endpoint");
                return(NotFound($"Unable to find endpoint {request.EndpointId}"));
            }

            var defenceAdvocate = conference.GetParticipants().SingleOrDefault(x => x.Id == request.DefenceAdvocateId);

            if (defenceAdvocate == null)
            {
                _logger.LogWarning("Unable to find defence advocate");
                return(NotFound($"Unable to find defence advocate {request.DefenceAdvocateId}"));
            }

            if (string.IsNullOrWhiteSpace(endpoint.DefenceAdvocate))
            {
                var message = "Endpoint does not have a defence advocate linked";
                _logger.LogWarning(message);
                return(Unauthorized(message));
            }

            if (!endpoint.DefenceAdvocate.Trim().Equals(defenceAdvocate.Username.Trim(), StringComparison.CurrentCultureIgnoreCase))
            {
                var message = "Defence advocate is not allowed to speak to requested endpoint";
                _logger.LogWarning(message);
                return(Unauthorized(message));
            }

            await _videoPlatformService.StartEndpointPrivateConsultationAsync(conference, endpoint, defenceAdvocate);

            return(Accepted());
        }
Esempio n. 8
0
        public async Task <IActionResult> GetParticipantsByConferenceId(Guid conferenceId)
        {
            _logger.LogDebug("GetParticipantsByConferenceId");

            var query      = new GetConferenceByIdQuery(conferenceId);
            var conference = await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(query);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var participants = conference.Participants.Select(x => ParticipantToSummaryResponseMapper.MapParticipantToSummary(x)).ToList();

            return(Ok(participants));
        }
        private async Task DeleteAudioRecordingApplication(Guid conferenceId)
        {
            var getConferenceByIdQuery = new GetConferenceByIdQuery(conferenceId);
            var queriedConference      =
                await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (queriedConference != null && queriedConference.AudioRecordingRequired)
            {
                try
                {
                    await EnsureAudioFileExists(queriedConference);

                    await _audioPlatformService.DeleteAudioApplicationAsync(queriedConference.HearingRefId);
                }
                catch (AudioPlatformFileNotFoundException ex)
                {
                    _logger.LogError(ex, ex.Message);
                }
            }
        }
        public async Task <IActionResult> GetConferenceDetailsByIdAsync(Guid conferenceId)
        {
            _logger.LogDebug("GetConferenceDetailsById {ConferenceId}", conferenceId);

            var getConferenceByIdQuery = new GetConferenceByIdQuery(conferenceId);
            var queriedConference      =
                await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (queriedConference == null)
            {
                _logger.LogWarning("Unable to find conference {ConferenceId}", conferenceId);

                return(NotFound());
            }

            var response =
                ConferenceToDetailsResponseMapper.MapConferenceToResponse(queriedConference,
                                                                          _kinlyConfiguration.PexipSelfTestNode);

            return(Ok(response));
        }
Esempio n. 11
0
        public async Task <IActionResult> GetParticipantsByConferenceId(Guid conferenceId)
        {
            _logger.LogDebug("GetParticipantsByConferenceId");

            var query      = new GetConferenceByIdQuery(conferenceId);
            var conference = await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(query);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var participantRooms = conference.Rooms.OfType <ParticipantRoom>().ToList();
            var participants     = conference.Participants.Select(x =>
            {
                var participantRoom =
                    participantRooms.SingleOrDefault(r => r.DoesParticipantExist(new RoomParticipant(x.Id)));
                return(ParticipantToSummaryResponseMapper.MapParticipantToSummary(x, participantRoom));
            }).ToList();

            return(Ok(participants));
        }
Esempio n. 12
0
        public async Task <IActionResult> RespondToAdminConsultationRequestAsync(AdminConsultationRequest request)
        {
            _logger.LogDebug("RespondToAdminConsultationRequest");

            const string modelErrorMessage      = "Response to consultation is missing";
            var          getConferenceByIdQuery = new GetConferenceByIdQuery(request.ConferenceId);
            var          conference             =
                await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (!request.Answer.HasValue)
            {
                ModelState.AddModelError(nameof(request.Answer), modelErrorMessage);
                return(BadRequest(ModelState));
            }

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound());
            }

            var participant = conference.GetParticipants().SingleOrDefault(x => x.Id == request.ParticipantId);

            if (participant == null)
            {
                _logger.LogWarning("Unable to find participant request by id");
                return(NotFound());
            }

            if (request.Answer.Value == ConsultationAnswer.Accepted)
            {
                await _videoPlatformService.TransferParticipantAsync(conference.Id, participant.Id,
                                                                     participant.GetCurrentRoom(), request.ConsultationRoom);
            }

            return(NoContent());
        }
Esempio n. 13
0
        public async Task <IActionResult> StartConsultationWithEndpointAsync(EndpointConsultationRequest request)
        {
            var isVhoRequest           = request.RequestedById == Guid.Empty;
            var getConferenceByIdQuery = new GetConferenceByIdQuery(request.ConferenceId);
            var conference             = await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(getConferenceByIdQuery);

            if (conference == null)
            {
                _logger.LogWarning("Unable to find conference");
                return(NotFound($"Unable to find conference {request.ConferenceId}"));
            }

            var endpoint = conference.GetEndpoints().SingleOrDefault(x => x.Id == request.EndpointId);

            if (endpoint == null)
            {
                _logger.LogWarning("Unable to find endpoint");
                return(NotFound($"Unable to find endpoint {request.EndpointId}"));
            }

            var requestedBy = conference.GetParticipants().SingleOrDefault(x => x.Id == request.RequestedById);

            if (isVhoRequest || requestedBy?.UserRole == UserRole.Judge || requestedBy?.UserRole == UserRole.JudicialOfficeHolder)
            {
                await _consultationService.EndpointTransferToRoomAsync(request.ConferenceId, endpoint.Id, request.RoomLabel);

                return(Ok());
            }


            if (requestedBy == null)
            {
                _logger.LogWarning("Unable to find defence advocate");
                return(NotFound($"Unable to find defence advocate {request.RequestedById}"));
            }

            if (string.IsNullOrWhiteSpace(endpoint.DefenceAdvocate))
            {
                const string message = "Endpoint does not have a defence advocate linked";
                _logger.LogWarning(message);
                return(Unauthorized(message));
            }

            if (!endpoint.DefenceAdvocate.Trim().Equals(requestedBy.Username.Trim(), StringComparison.CurrentCultureIgnoreCase))
            {
                const string message = "Defence advocate is not allowed to speak to requested endpoint";
                _logger.LogWarning(message);
                return(Unauthorized(message));
            }

            var roomQuery = new GetConsultationRoomByIdQuery(request.ConferenceId, request.RoomLabel);
            var room      = await _queryHandler.Handle <GetConsultationRoomByIdQuery, ConsultationRoom>(roomQuery);

            if (room == null)
            {
                _logger.LogWarning($"Unable to find room {request.RoomLabel}");
                return(NotFound($"Unable to find room {request.RoomLabel}"));
            }

            if (room.RoomEndpoints.Any())
            {
                _logger.LogWarning("Unable to join endpoint {endpointId} to {RoomLabel}", endpoint.Id, request.RoomLabel);
                return(BadRequest("Room already has an active endpoint"));
            }

            await _consultationService.EndpointTransferToRoomAsync(request.ConferenceId, endpoint.Id, request.RoomLabel);

            return(Ok());
        }
Esempio n. 14
0
        public async Task <IActionResult> HealthAsync()
        {
            var response = new HealthCheckResponse {
                AppVersion = GetApplicationVersion()
            };

            try
            {
                var hearingId = Guid.NewGuid();
                var query     = new GetConferenceByIdQuery(hearingId);
                await _queryHandler.Handle <GetConferenceByIdQuery, Conference>(query);

                response.DatabaseHealth.Successful = true;
            }
            catch (Exception ex)
            {
                response.DatabaseHealth.Successful   = false;
                response.DatabaseHealth.ErrorMessage = ex.Message;
                response.DatabaseHealth.Data         = ex.Data;
            }

            try
            {
                await _videoPlatformService.GetTestCallScoreAsync(Guid.Empty, 0);

                response.KinlySelfTestHealth.Successful = true;
            }
            catch (Exception ex)
            {
                response.KinlySelfTestHealth.Successful   = false;
                response.KinlySelfTestHealth.ErrorMessage = ex.Message;
                response.KinlySelfTestHealth.Data         = ex.Data;
            }

            try
            {
                var apiHealth = await _videoPlatformService.GetPlatformHealthAsync();

                response.KinlyApiHealth.Successful = apiHealth.Health_status == PlatformHealth.HEALTHY;
            }
            catch (Exception ex)
            {
                response.KinlyApiHealth.Successful   = false;
                response.KinlyApiHealth.ErrorMessage = ex.Message;
                response.KinlyApiHealth.Data         = ex.Data;
            }

            try
            {
                response.WowzaHealth.Successful = false;
                var wowzaResponse = await _audioPlatformService.GetDiagnosticsAsync();

                if (wowzaResponse != null && !wowzaResponse.All(x => string.IsNullOrWhiteSpace(x.ServerVersion)))
                {
                    response.WowzaHealth.Successful = true;
                }
            }
            catch (Exception ex)
            {
                response.WowzaHealth.Successful   = false;
                response.WowzaHealth.ErrorMessage = ex.Message;
                response.WowzaHealth.Data         = ex.Data;
            }

            if (!response.DatabaseHealth.Successful || !response.KinlySelfTestHealth.Successful ||
                !response.KinlyApiHealth.Successful || !response.WowzaHealth.Successful)
            {
                return(StatusCode((int)HttpStatusCode.InternalServerError, response));
            }

            return(Ok(response));
        }