Exemplo n.º 1
0
        /// <summary>
        /// Initialize the instance.
        /// </summary>
        /// <param name="service">Service instance.</param>
        /// <param name="logger">Graph logger.</param>
        internal void Initialize(Service service, IGraphLogger logger)
        {
            Validator.IsNull(this.Logger, "Multiple initializations are not allowed.");

            this.Logger   = logger;
            this.Observer = new SampleObserver(logger);

            var name    = this.GetType().Assembly.GetName().Name;
            var builder = new CommunicationsClientBuilder(
                name,
                service.Configuration.AadAppId,
                this.Logger);

            var authProvider = new AuthenticationProvider(
                name,
                service.Configuration.AadAppId,
                service.Configuration.AadAppSecret,
                this.Logger);

            builder.SetAuthenticationProvider(authProvider);
            builder.SetNotificationUrl(service.Configuration.CallControlBaseUrl);
            builder.SetMediaPlatformSettings(service.Configuration.MediaPlatformSettings);
            builder.SetServiceBaseUrl(service.Configuration.PlaceCallEndpointUrl);

            this.Client = builder.Build();
            this.Client.Calls().OnIncoming += this.CallsOnIncoming;
            this.Client.Calls().OnUpdated  += this.CallsOnUpdated;
        }
Exemplo n.º 2
0
 /// <inheritdoc />
 public void Dispose()
 {
     this.Observer?.Dispose();
     this.Observer = null;
     this.Logger   = null;
     this.Client?.Dispose();
     this.Client = null;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Rehydrates and validates the group call.
        /// </summary>
        /// <param name="client">The communications client.</param>
        /// <param name="call">The call to validate.</param>
        /// <returns>The rehydrated call.</returns>
        private async Task <ICall> RehydrateAndValidateGroupCallAsync(ICommunicationsClient client, ICall call)
        {
            // Wait for roster so we ensure that events were already raised.
            await call.Participants.WaitForParticipantAsync(call.Resource.MyParticipantId).ConfigureAwait(false);

            // Remove call from memory.
            this.Client.Calls().TryForceRemove(call.Id, out ICall removedCall);
            this.graphLogger.Info($"Check whether the removed call is desired: {call == removedCall}");
            this.graphLogger.Info($"Check whether the call get removed: {this.Client.Calls()[removedCall.Id] == null}");

            // Rehydrate here... after this point all the data should be rebuilt
            // This calls:
            // GET /communications/calls/{id}
            // GET /communications/calls/{id}/participants
            // GET /communications/calls/{id}/audioRoutingGroups
            var tenantId   = call.TenantId;
            var scenarioId = call.ScenarioId;
            await client.RehydrateAsync(removedCall.ResourcePath, tenantId, scenarioId).ConfigureAwait(false);

            var rehydratedCall = client.Calls()[removedCall.Id];

            this.graphLogger.Info($"Check whether the call get rehydrated: {rehydratedCall != null}");
            this.graphLogger.Info($"Check whether the rehydrated call is a new object: {removedCall == rehydratedCall}");

            // deployments and Graph is stripping out some parameters.
            // E2EAssert.IsContentEqual(removedCall.Resource, rehydratedCall.Resource);
            var myParticipant = rehydratedCall.Participants[removedCall.Resource.MyParticipantId];

            this.graphLogger.Info($"Check whether myParticipant get rehydrated: {myParticipant != null}");

            // Remove participant from memory.
            rehydratedCall.Participants.TryForceRemove(call.Resource.MyParticipantId, out IParticipant removedParticipant);
            this.graphLogger.Info($"Check whether participant get removed from memory: {rehydratedCall.Participants[call.Resource.MyParticipantId] == null}");

            // Rehydrate here... after this point the participant should be rebuilt.
            // This calls:
            // GET /communications/calls/{id}/participants/{id}
            var rehydratedParticipant = await rehydratedCall.Participants.GetAsync(call.Resource.MyParticipantId).ConfigureAwait(false);

            this.graphLogger.Info($"Check whether participant get rehydrated: {rehydratedParticipant != null}");
            this.graphLogger.Info($"Check whether the rehydrated participant is a new object: {removedParticipant != rehydratedParticipant}");

            return(rehydratedCall);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Initialize the instance.
        /// </summary>
        public void Initialize()
        {
            var name    = this.GetType().Assembly.GetName().Name;
            var builder = new CommunicationsClientBuilder(
                name,
                _settings.AadAppId,
                _logger);

            var authProvider = new AuthenticationProvider(
                name,
                _settings.AadAppId,
                _settings.AadAppSecret,
                _logger);

            builder.SetAuthenticationProvider(authProvider);
            builder.SetNotificationUrl(_settings.CallControlBaseUrl);
            builder.SetMediaPlatformSettings(_settings.MediaPlatformSettings);
            builder.SetServiceBaseUrl(_settings.PlaceCallEndpointUrl);

            this.Client = builder.Build();
            this.Client.Calls().OnIncoming += this.CallsOnIncoming;
            this.Client.Calls().OnUpdated  += this.CallsOnUpdated;
        }
        /// <summary>
        /// Processes the notifications and raises the required callbacks.
        /// This function should be called in order for the SDK to raise
        /// any required events and process state changes.
        /// </summary>
        /// <param name="client">The stateful client.</param>
        /// <param name="request">The http request that is incoming from service.</param>
        /// <returns>Http Response Message after processed by the SDK. This has to
        /// be returned to the server.</returns>
        private static async Task <HttpResponseMessage> ProcessNotificationAsync(ICommunicationsClient client, HttpRequestMessage request)
        {
            client.NotNull(nameof(client));
            request.NotNull(nameof(request));
            var stopwatch = Stopwatch.StartNew();

            var scenarioId = client.GraphLogger.ParseScenarioId(request);
            var requestId  = client.GraphLogger.ParseRequestId(request);

            CommsNotifications notifications = null;

            try
            {
                // Parse out the notification content.
                var content = await request.Content.ReadAsStringAsync().ConfigureAwait(false);

                var serializer = client.Serializer;
                notifications = NotificationProcessor.ExtractNotifications(content, serializer);
            }
            catch (ServiceException ex)
            {
                var statusCode = (int)ex.StatusCode >= 200
                    ? ex.StatusCode
                    : HttpStatusCode.BadRequest;
                return(client.LogAndCreateResponse(request, requestId, scenarioId, notifications, statusCode, stopwatch, ex));
            }
            catch (Exception ex)
            {
                var statusCode = HttpStatusCode.BadRequest;
                return(client.LogAndCreateResponse(request, requestId, scenarioId, notifications, statusCode, stopwatch, ex));
            }

            RequestValidationResult result;

            try
            {
                // Autenticate the incoming request.
                result = await client.AuthenticationProvider
                         .ValidateInboundRequestAsync(request)
                         .ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                var clientEx = new ClientException(
                    new Error
                {
                    Code    = ErrorConstants.Codes.ClientCallbackError,
                    Message = ErrorConstants.Messages.ClientErrorAuthenticatingRequest,
                },
                    ex);

                throw clientEx;
            }

            if (!result.IsValid)
            {
                var statusCode = HttpStatusCode.Unauthorized;
                return(client.LogAndCreateResponse(request, requestId, scenarioId, notifications, statusCode, stopwatch));
            }

            // The request is valid. Let's evaluate any policies on the
            // incoming call before sending it off to the SDK for processing.
            var call     = notifications?.Value?.FirstOrDefault()?.GetResourceData() as Call;
            var response = await EvaluateAndHandleIncomingCallPoliciesAsync(call).ConfigureAwait(false);

            if (response != null)
            {
                var level = client.GraphLogger.LogHttpRequest(request, response.StatusCode, notifications);
                client.GraphLogger.LogHttpResponse(level, request, response, stopwatch.ElapsedMilliseconds);
                stopwatch.Stop();
                return(response);
            }

            try
            {
                var additionalData = request.GetHttpAndContentHeaders().ToDictionary(
                    pair => pair.Key,
                    pair => (object)string.Join(",", pair.Value),
                    StringComparer.OrdinalIgnoreCase);
                client.ProcessNotifications(request.RequestUri, notifications, result.TenantId, requestId, scenarioId, additionalData);
            }
            catch (ServiceException ex)
            {
                var statusCode = (int)ex.StatusCode >= 200
                    ? ex.StatusCode
                    : HttpStatusCode.InternalServerError;
                return(client.LogAndCreateResponse(request, requestId, scenarioId, notifications, statusCode, stopwatch, ex));
            }
            catch (Exception ex)
            {
                var statusCode = HttpStatusCode.InternalServerError;
                return(client.LogAndCreateResponse(request, requestId, scenarioId, notifications, statusCode, stopwatch, ex));
            }

            return(client.LogAndCreateResponse(request, requestId, scenarioId, notifications, HttpStatusCode.Accepted, stopwatch));
        }
Exemplo n.º 6
0
 /// <inheritdoc />
 public void Dispose()
 {
     this.Client?.Dispose();
     this.Client = null;
 }