Ejemplo n.º 1
0
        /// <summary>
        /// Method responsible for processing the data sent with POST request to callback URL
        /// </summary>
        /// <param name="content">The content of request</param>
        /// <returns>Returns the response that should be sent to the sender of POST request</returns>
        public async Task <ResponseResult> ProcessCallbackAsync(string content)
        {
            ConversationResult conversationResult;

            if (content == null)
            {
                return(new ResponseResult(ResponseType.BadRequest));
            }
            try
            {
                conversationResult = RealTimeMediaSerializer.DeserializeFromJson <ConversationResult>(content);
                if (conversationResult == null)
                {
                    Trace.TraceWarning($"Could not deserialize the callback.. returning badrequest");
                    return(new ResponseResult(ResponseType.BadRequest));
                }

                conversationResult.Validate();
            }
            catch (Exception ex)
            {
                Trace.TraceWarning($"Exception in conversationResult validate {ex}");
                return(new ResponseResult(ResponseType.BadRequest));
            }

            RealTimeMediaCallService service;

            if (!_activeCalls.TryGetValue(conversationResult.Id, out service))
            {
                Trace.TraceWarning($"CallId {conversationResult.Id} not found");
                return(new ResponseResult(ResponseType.NotFound));
            }
            return(new ResponseResult(ResponseType.Accepted, await service.ProcessConversationResult(conversationResult).ConfigureAwait(false)));
        }
        /// <summary>
        /// Invokes handlers for callback on the bot
        /// </summary>
        /// <param name="conversationResult">ConversationResult that has the details of the callback</param>
        /// <returns></returns>
        internal async Task <string> ProcessConversationResult(ConversationResult conversationResult)
        {
            conversationResult.Validate();
            var newWorkflowResult = await PassActionResultToHandler(conversationResult).ConfigureAwait(false);

            if (newWorkflowResult == null)
            {
                throw new BotCallingServiceException($"[{CallLegId}]: No workflow returned for AnswerAppHostedMediaOutcome");
            }

            bool expectEmptyActions = false;

            if (conversationResult.OperationOutcome.Type == RealTimeMediaValidOutcomes.AnswerAppHostedMediaOutcome && conversationResult.OperationOutcome.Outcome == Outcome.Success)
            {
                Uri link;
                if (conversationResult.Links.TryGetValue("subscriptions", out link))
                {
                    _subscriptionLink = link;
                    Trace.TraceInformation($"RealTimeMediaCallService [{CallLegId}]: Caching subscription link {link}");
                }

                if (conversationResult.Links.TryGetValue("call", out link))
                {
                    _callLink = link;
                    Trace.TraceInformation($"RealTimeMediaCallService [{CallLegId}]: Caching call link {link}");
                }
                expectEmptyActions = true;

                Trace.TraceInformation($"RealTimeMediaCallService [{CallLegId}]: Disposing call expiry timer");
                _timer.Dispose();
            }

            newWorkflowResult.Validate(expectEmptyActions);
            return(RealTimeMediaSerializer.SerializeToJson(newWorkflowResult));
        }
        /// <summary>
        /// Configuration settings like Auth, Routes for OWIN
        /// </summary>
        /// <param name="app"></param>

        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration httpConfig = new HttpConfiguration();

            httpConfig.MapHttpAttributeRoutes();
            httpConfig.MessageHandlers.Add(new LoggingMessageHandler(isIncomingMessageHandler: true, logContext: LogContext.FrontEnd));

            httpConfig.Services.Add(typeof(IExceptionLogger), new ExceptionLogger());
            httpConfig.Formatters.JsonFormatter.SerializerSettings = RealTimeMediaSerializer.GetSerializerSettings();
            httpConfig.EnsureInitialized();

            app.UseWebApi(httpConfig);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Method responsible for processing the data sent with POST request to incoming call URL
        /// </summary>
        /// <param name="content">The content of request</param>
        /// <param name="skypeChainId">X-Microsoft-Skype-Chain-Id header value used to associate calls across different services</param>
        /// <returns>Returns the response that should be sent to the sender of POST request</returns>
        public async Task <ResponseResult> ProcessIncomingCallAsync(string content, string skypeChainId)
        {
            if (content == null)
            {
                return(new ResponseResult(ResponseType.BadRequest));
            }

            Conversation conversation;

            try
            {
                conversation = RealTimeMediaSerializer.DeserializeFromJson <Conversation>(content);
                if (conversation == null)
                {
                    Trace.TraceWarning($"Could not deserialize the incoming request.. returning badrequest");
                    return(new ResponseResult(ResponseType.BadRequest));
                }

                conversation.Validate();
            }
            catch (Exception ex)
            {
                Trace.TraceWarning($"Exception in conversation validate {ex}");
                return(new ResponseResult(ResponseType.BadRequest));
            }

            RealTimeMediaCallService service = new RealTimeMediaCallService(conversation.Id, skypeChainId, _makeBot, _settings);
            var workflow = await service.HandleIncomingCall(conversation).ConfigureAwait(false);

            if (workflow == null)
            {
                throw new BotCallingServiceException("Incoming call not handled. No workflow produced for incoming call.");
            }
            workflow.Validate();

            RealTimeMediaCallService prevService;

            if (_activeCalls.TryRemove(conversation.Id, out prevService))
            {
                Trace.TraceWarning($"Another call with the same Id {conversation.Id} exists. ending the old call");
                await prevService.LocalCleanup().ConfigureAwait(false);
            }

            _activeCalls[conversation.Id] = service;

            var serializedResponse = RealTimeMediaSerializer.SerializeToJson(workflow);

            return(new ResponseResult(ResponseType.Accepted, serializedResponse));
        }
        /// <summary>
        /// Subscribe to a video or video based screen sharing channel
        /// </summary>
        /// <param name="videoSubscription"></param>
        /// <returns></returns>
        public async Task Subscribe(VideoSubscription videoSubscription)
        {
            if (_subscriptionLink == null)
            {
                throw new InvalidOperationException($"[{CallLegId}]: No subscription link was present in the AnswerAppHostedMediaOutcome");
            }

            videoSubscription.Validate();
            HttpContent content = new StringContent(RealTimeMediaSerializer.SerializeToJson(videoSubscription), Encoding.UTF8, JSONConstants.ContentType);

            //Subscribe
            try
            {
                Trace.TraceInformation(
                    $"RealTimeMediaCallService [{CallLegId}]: Sending subscribe request for " +
                    $"user: {videoSubscription.ParticipantIdentity}" +
                    $"subscriptionLink: {_subscriptionLink}");

                //TODO: add retries & logging
                using (var request = new HttpRequestMessage(HttpMethod.Put, _subscriptionLink)
                {
                    Content = content
                })
                {
                    request.Headers.Add("X-Microsoft-Skype-Chain-ID", CorrelationId);
                    request.Headers.Add("X-Microsoft-Skype-Message-ID", Guid.NewGuid().ToString());

                    var client   = GetHttpClient();
                    var response = await client.SendAsync(request).ConfigureAwait(false);

                    response.EnsureSuccessStatusCode();

                    Trace.TraceInformation($"RealTimeMediaCallService [{CallLegId}]: Response to subscribe: {response}");
                }
            }
            catch (Exception exception)
            {
                Trace.TraceError($"RealTimeMediaCallService [{CallLegId}]: Received error while sending request to subscribe participant. Message: {exception}");
                throw;
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Method responsible for processing the data sent with POST request to notification URL
        /// </summary>
        /// <param name="content">The content of request</param>
        /// <returns>Returns the response that should be sent to the sender of POST request</returns>
        public async Task <ResponseResult> ProcessNotificationAsync(string content)
        {
            NotificationBase notification;

            if (content == null)
            {
                return(new ResponseResult(ResponseType.BadRequest));
            }
            try
            {
                Trace.TraceWarning($"Received notification {content}");
                notification = RealTimeMediaSerializer.DeserializeFromJson <NotificationBase>(content);
                if (notification == null)
                {
                    Trace.TraceWarning($"Could not deserialize the notification.. returning badrequest");
                    return(new ResponseResult(ResponseType.BadRequest));
                }

                notification.Validate();
            }
            catch (Exception ex)
            {
                Trace.TraceWarning($"Exception in notification validate {ex}");
                return(new ResponseResult(ResponseType.BadRequest));
            }

            RealTimeMediaCallService service;

            if (!_activeCalls.TryGetValue(notification.Id, out service))
            {
                return(new ResponseResult(ResponseType.NotFound, $"Call {notification.Id} not found"));
            }

            await service.ProcessNotificationResult(notification).ConfigureAwait(false);

            return(new ResponseResult(ResponseType.Accepted));
        }