diff --git a/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Bot/Bot.cs b/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Bot/Bot.cs index 6c915ee0..78001036 100644 --- a/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Bot/Bot.cs +++ b/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Bot/Bot.cs @@ -247,13 +247,11 @@ public async Task JoinCallAsync(JoinCallRequestData joinCallBody, string .ConfigureAwait(false); meetingInfo = new OrganizerMeetingInfo { Organizer = onlineMeeting.Participants.Organizer.Identity, }; - meetingInfo.AllowConversationWithoutHost = joinCallBody.AllowConversationWithoutHost; chatInfo = onlineMeeting.ChatInfo; } else { (chatInfo, meetingInfo) = JoinInfo.ParseJoinURL(joinCallBody.JoinURL); - meetingInfo.AllowConversationWithoutHost = joinCallBody.AllowConversationWithoutHost; } var tenantId = diff --git a/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Data/JoinCallRequestData.cs b/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Data/JoinCallRequestData.cs index 0ddf6c44..8cc2b9ec 100644 --- a/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Data/JoinCallRequestData.cs +++ b/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Data/JoinCallRequestData.cs @@ -34,10 +34,5 @@ public class JoinCallRequestData /// Gets or sets a value indicating whether to remove the bot from default routing group. /// public bool RemoveFromDefaultRoutingGroup { get; set; } - - /// - /// Gets or sets a value indicating whether allow conversation without host. - /// - public bool AllowConversationWithoutHost { get; set; } } } diff --git a/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/IncidentBot.csproj b/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/IncidentBot.csproj index 4d4fa895..9c7f9200 100644 --- a/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/IncidentBot.csproj +++ b/Samples/BetaSamples/RemoteMediaSamples/IncidentBot/IncidentBot.csproj @@ -24,7 +24,7 @@ - + diff --git a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeeting.cs b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/AppOnlineMeeting.cs similarity index 86% rename from Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeeting.cs rename to Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/AppOnlineMeeting.cs index 8517e5aa..38f29842 100644 --- a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeeting.cs +++ b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/AppOnlineMeeting.cs @@ -1,11 +1,15 @@ -// +// // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. // +// THIS CODE HAS NOT BEEN TESTED RIGOROUSLY.USING THIS CODE IN PRODUCTION ENVIRONMENT IS STRICTLY NOT RECOMMENDED. +// THIS SAMPLE IS PURELY FOR DEMONSTRATION PURPOSES ONLY. +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. namespace Sample.OnlineMeeting { using System; + using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.Graph; @@ -15,17 +19,17 @@ namespace Sample.OnlineMeeting /// /// Online meeting class to fetch meeting info based of meeting id (ex: vtckey). /// - public class OnlineMeeting + public class AppOnlineMeeting { private Uri graphEndpointUri; private IRequestAuthenticationProvider requestAuthenticationProvider; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The request authentication provider. /// The graph url. - public OnlineMeeting(IRequestAuthenticationProvider requestAuthenticationProvider, Uri graphUri) + public AppOnlineMeeting(IRequestAuthenticationProvider requestAuthenticationProvider, Uri graphUri) { this.requestAuthenticationProvider = requestAuthenticationProvider; this.graphEndpointUri = graphUri; @@ -54,13 +58,14 @@ public OnlineMeeting(IRequestAuthenticationProvider requestAuthenticationProvide } /// - /// Creates a new adhoc online meeting. + /// Creates a new online meeting. /// Permissions required : OnlineMeetings.ReadWrite.All. /// /// The tenant identifier. /// The meeting organizer identifier. /// The scenario identifier - needed in case of debugging for correlating client side request with server side logs. /// The onlinemeeting. + [Obsolete("This way of creating meeting is obsolete. Check CreateUserMeetingRequestAsync for creating meetings.")] public async Task CreateOnlineMeetingAsync(string tenantId, string organizerId, Guid scenarioId) { var statelessClient = new CallsGraphServiceClient( @@ -71,7 +76,6 @@ public OnlineMeeting(IRequestAuthenticationProvider requestAuthenticationProvide var onlineMeeting = new Microsoft.Graph.OnlineMeeting() { - MeetingType = MeetingType.MeetNow, Participants = new MeetingParticipants() { Organizer = new MeetingParticipantInfo() diff --git a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeeting.csproj b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeeting.csproj index f9457bf6..7967042e 100644 --- a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeeting.csproj +++ b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeeting.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeetingMeRequest.cs b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeetingMeRequest.cs new file mode 100644 index 00000000..53cd7894 --- /dev/null +++ b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/OnlineMeetingMeRequest.cs @@ -0,0 +1,82 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. +// + +// THIS CODE HAS NOT BEEN TESTED RIGOROUSLY.USING THIS CODE IN PRODUCTION ENVIRONMENT IS STRICTLY NOT RECOMMENDED. +// THIS SAMPLE IS PURELY FOR DEMONSTRATION PURPOSES ONLY. +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. +// +#pragma warning disable SA1100 // Do not prefix calls with base +#pragma warning disable SA1402 // File may contain only single type. +#pragma warning disable SA1121 // Use built-int type alias. +#pragma warning disable SA1649 // Filename should match first type. + +namespace Microsoft.Graph +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + /// + /// IUserRequestBuilder with OnlineMeetings request collection property. + /// + public interface IUserRequestBuilderEx : IUserRequestBuilder + { + /// + /// Gets. + /// + IUserOnlineMeetingsCollectionRequestBuilder OnlineMeetings + { + get; + } + } + + /// + /// UserRequestBuilderEx with support for creating onlinemeetings request collection. + /// + public class UserRequestBuilderEx : UserRequestBuilder, IUserRequestBuilderEx + { + /// + /// Initializes a new instance of the class. + /// + /// The URL for the built request. + /// The Microsoft.Graph.IBaseClient for handling requests. + public UserRequestBuilderEx(String requestUrl, IBaseClient client) + : base(requestUrl, client) + { + } + + /// + /// Gets. + /// + public IUserOnlineMeetingsCollectionRequestBuilder OnlineMeetings => new UserOnlineMeetingsCollectionRequestBuilder(this.AppendSegmentToRequestUrl("onlinemeetings"), base.Client); + } + + /// + /// CallsGraphServiceClientEx adding suport for me with onlinemeetings request collection. + /// + public class CallsGraphServiceClientEx : CallsGraphServiceClient + { + /// + /// Initializes a new instance of the class. + /// + /// a. + /// b. + /// c. + public CallsGraphServiceClientEx(string baseUrl, IAuthenticationProvider authenticationProvider, IHttpProvider httpProvider = null) + : base(baseUrl, authenticationProvider, httpProvider) + { + } + + /// + /// Gets. + /// + public new IUserRequestBuilderEx Me => new UserRequestBuilderEx(base.BaseUrl + "/me", this); + } +} + +#pragma warning restore SA1100 // Do not prefix calls with base +#pragma warning restore SA1402 // File may contain only single type. +#pragma warning restore SA1121 // Use built-int type alias. +#pragma warning restore SA1649 // Filename should match first type. \ No newline at end of file diff --git a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/Program.cs b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/Program.cs index a496f64a..d20b8b92 100644 --- a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/Program.cs +++ b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/Program.cs @@ -3,6 +3,9 @@ // Licensed under the MIT license. // +// THIS CODE HAS NOT BEEN TESTED RIGOROUSLY.USING THIS CODE IN PRODUCTION ENVIRONMENT IS STRICTLY NOT RECOMMENDED. +// THIS SAMPLE IS PURELY FOR DEMONSTRATION PURPOSES ONLY. +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. namespace Sample.OnlineMeeting { using System; @@ -15,12 +18,17 @@ namespace Sample.OnlineMeeting /// public class Program { + // Common settings. private static string appSecret = "__placeholder__"; private static string appId = "__placeholder__"; + private static string tenantId = "__placeholder__"; + // Needed for app token meetings. private static string vtcId = "__placeholder__"; - private static string tenantId = "__placeholder__"; - private static string organizerID = "__placeholder__"; + + // Needed for user token meetings. + private static string userName = "__placeholder__"; + private static string password = "__placeholder__"; private static Uri graphUri = new Uri("https://graph.microsoft.com/beta/"); @@ -34,13 +42,13 @@ public class Program { var name = typeof(Program).Assembly.GetName().Name; var logger = new GraphLogger(name); - var onlineMeeting = new OnlineMeeting( + var onlineMeeting = new AppOnlineMeeting( new AuthenticationProvider(name, appId, appSecret, logger), graphUri); var meetingDetails = await onlineMeeting.GetOnlineMeetingByVtcIdAsync(tenantId, videoTeleconferenceId, default(Guid)).ConfigureAwait(false); - Console.WriteLine(meetingDetails.Id); + Console.WriteLine(meetingDetails.VideoTeleconferenceId); Console.WriteLine(meetingDetails.ChatInfo.ThreadId); return meetingDetails; @@ -52,11 +60,12 @@ public class Program /// The tenant identifier. /// The organizer identifier. /// The newly created onlinemeeting. + [Obsolete("This way of creating meeting is obsolete. Check CreateUserMeetingRequestAsync for creating meetings.")] public static async Task CreateOnlineMeetingAsync(string tenantId, string organizerId) { var name = typeof(Program).Assembly.GetName().Name; var logger = new GraphLogger(name); - var onlineMeeting = new OnlineMeeting( + var onlineMeeting = new AppOnlineMeeting( new AuthenticationProvider(name, appId, appSecret, logger), graphUri); @@ -68,6 +77,28 @@ public class Program return meetingDetails; } + /// + /// Creates the online meeting asynchronous. + /// + /// The tenant identifier. + /// The newly created onlinemeeting. + public static async Task CreateUserOnlineMeetingAsync(string tenantId) + { + var name = typeof(Program).Assembly.GetName().Name; + var logger = new GraphLogger(name); + + var onlineMeeting = new UserOnlineMeeting( + new UserPasswordAuthenticationProvider(name, appId, appSecret, userName, password, logger), + graphUri); + + var meetingDetails = await onlineMeeting.CreateUserMeetingRequestAsync(tenantId, default(Guid)).ConfigureAwait(false); + + Console.WriteLine(meetingDetails.Id); + Console.WriteLine(meetingDetails.ChatInfo.ThreadId); + + return meetingDetails; + } + /// /// The Main entry point. /// @@ -80,7 +111,13 @@ public static void Main(string[] args) { var meetingDetails = await GetOnlineMeetingByVtcIdAsync(tenantId, vtcId).ConfigureAwait(false); - var createdMeetingDetails = await CreateOnlineMeetingAsync(tenantId, organizerID).ConfigureAwait(false); + /* + * THIS WAY OF CREATING MEETING IS OBSOLETE. CHECK CreateUserOnlineMeetingAsync FOR CREATING MEETINGS. + * + * var createdMeetingDetails = await CreateOnlineMeetingAsync(tenantId, organizerID).ConfigureAwait(false); + */ + + var userTokenMeeting = await CreateUserOnlineMeetingAsync(tenantId).ConfigureAwait(false); } catch (Exception ex) { diff --git a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/README.md b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/README.md index 911d681f..2bf346a3 100644 --- a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/README.md +++ b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/README.md @@ -1,28 +1,36 @@ -# Introduction +# THE SAMPLE PROVIDED IS PURELY FOR DEMONSTRATION PURPOSES ONLY.THIS CODE AND INFORMATION IS PROVIDED "AS IS" +# WITHOUT WARRANTY OF ANY KIND. + +# Introduction ## About -The online meeting stateless sample demonstrates how one can consume Microsoft.Skype.Graph.CoreSDK in thier bot application to -1. Get an online meeting based on meetingid (current support is only for [vtcid](https://docs.microsoft.com/en-us/microsoftteams/cloud-video-interop)). -1. Create a adhoc online meeting on behalf of an organizer in your tenant. +The online meeting stateless sample demonstrates how one can consume Microsoft.Graph.Communications.Client in bot application to +1. Get an online meeting based on on [vtcid](https://docs.microsoft.com/en-us/microsoftteams/cloud-video-interop)). +2. Create a online meeting on behalf a user (delegated auth) in your tenant. ## Getting Started ### Prerequisites 1. [Permissions](https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference#online-meetings-permissions) - The following persmissions are needed by the bot application to successfully authenticate against the online meeting service. * OnlineMeetings.Read.All OR OnlineMeetings.ReadWrite.All for getting meeting details - * OnlineMeetings.ReadWrite.All for creating a meeting. + * OnlineMeetings.ReadWrite for creating a meeting. 1. Tools. - * [Visual Studio 2017](https://visualstudio.microsoft.com/downloads/) + * [Visual Studio 2017 or above](https://visualstudio.microsoft.com/downloads/) ## Build and Test -1. Open OnlineMeetingsSample.sln in Visual Studio 2017 and update the values of the following in `program.cs` +1. Open OnlineMeetingsSample.sln in Visual Studio and update the values of the following in `program.cs` * `appId, appSecret` : AppId, Appsecret of your bot application * `tenantId` : Tenant against which to fetch/create the online meeting. - * `meetingId (Only needed for GET)` : The VTC conference id. - * `organizerId (Only needed for Create)` : oid of the user on behalf of whom the adhoc meeting is to be created. - * Note - The organizerId should belong to the same tenant as specified by teanantid + * `vtcid (Only needed for GET)` : The VTC conference id. + * `userName, password (Only needed for Create)` : Username, Password of the user. + * Note - The user should belong to the same tenant as specified by teanantId 2. Build, Run the application. - \ No newline at end of file + + +# References +Please refer following links on various ways to get access tokens. Please use the appropriate mechanism which meets with the requirements of your organization. + * https://docs.microsoft.com/en-us/graph/auth-v2-user + * https://github.com/microsoftgraph/msgraph-sdk-dotnet-auth \ No newline at end of file diff --git a/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/UserOnlineMeeting.cs b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/UserOnlineMeeting.cs new file mode 100644 index 00000000..78d6c0e1 --- /dev/null +++ b/Samples/BetaSamples/StatelessSamples/OnlineMeetingSamples/UserOnlineMeeting.cs @@ -0,0 +1,86 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. +// + +// THIS CODE HAS NOT BEEN TESTED RIGOROUSLY.USING THIS CODE IN PRODUCTION ENVIRONMENT IS STRICTLY NOT RECOMMENDED. +// THIS SAMPLE IS PURELY FOR DEMONSTRATION PURPOSES ONLY. +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. +namespace Sample.OnlineMeeting +{ + using System; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.Graph; + using Microsoft.Graph.Communications.Client.Authentication; + using Microsoft.Graph.Communications.Common; + + /// + /// Online meeting class to fetch meeting info based of meeting id (ex: vtckey). + /// + public class UserOnlineMeeting + { + private Uri graphEndpointUri; + private IRequestAuthenticationProvider requestAuthenticationProvider; + + /// + /// Initializes a new instance of the class. + /// + /// The request authentication provider. + /// The graph url. + public UserOnlineMeeting(IRequestAuthenticationProvider requestAuthenticationProvider, Uri graphUri) + { + this.requestAuthenticationProvider = requestAuthenticationProvider; + this.graphEndpointUri = graphUri; + } + + /// + /// Creates a new online meeting. Meeting organizer would be the oid of the token. + /// Permissions required : OnlineMeetings.ReadWrite. + /// + /// The tenant identifier. + /// The scenario identifier - needed in case of debugging for correlating client side request with server side logs. + /// The onlinemeeting. + public async Task CreateUserMeetingRequestAsync(string tenantId, Guid scenarioId) + { + var statelessClient = new CallsGraphServiceClientEx( + this.graphEndpointUri.AbsoluteUri, + this.GetAuthenticationProvider(tenantId, scenarioId)); + + var meetingRequest = statelessClient.Me.OnlineMeetings.Request(); + + DateTimeOffset startTime = new DateTimeOffset(DateTime.Now, TimeZoneInfo.Local.GetUtcOffset(DateTime.Now)); + DateTimeOffset endTime = new DateTimeOffset(DateTime.Now.AddMinutes(30), TimeZoneInfo.Local.GetUtcOffset(DateTime.Now)); + + var onlineMeeting = new Microsoft.Graph.OnlineMeeting() + { + Subject = "Test User Meeting", + + StartDateTime = startTime, + EndDateTime = endTime, + }; + + var meeting = await meetingRequest.AddAsync(onlineMeeting).ConfigureAwait(false); + + return meeting; + } + + /// + /// Gets the authentication provider1. + /// + /// The tenant identifier. + /// The scenario identifier. + /// Authenticated provider which can be used to authenticate an outbound request. + private IAuthenticationProvider GetAuthenticationProvider(string tenantId, Guid scenarioId) + { + return new DelegateAuthenticationProvider(async request => + { + request.Headers.Add(HttpConstants.HeaderNames.ScenarioId, scenarioId.ToString()); + request.Headers.Add(HttpConstants.HeaderNames.ClientRequestId, Guid.NewGuid().ToString()); + + await this.requestAuthenticationProvider.AuthenticateOutboundRequestAsync(request, tenantId) + .ConfigureAwait(false); + }); + } + } +} \ No newline at end of file diff --git a/Samples/Common/Sample.Common/Authentication/AuthenticationProvider.cs b/Samples/Common/Sample.Common/Authentication/AuthenticationProvider.cs index 000ea1ba..be78d647 100644 --- a/Samples/Common/Sample.Common/Authentication/AuthenticationProvider.cs +++ b/Samples/Common/Sample.Common/Authentication/AuthenticationProvider.cs @@ -3,6 +3,9 @@ // Licensed under the MIT license. // +// THIS CODE HAS NOT BEEN TESTED RIGOROUSLY.USING THIS CODE IN PRODUCTION ENVIRONMENT IS STRICTLY NOT RECOMMENDED. +// THIS SAMPLE IS PURELY FOR DEMONSTRATION PURPOSES ONLY. +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. namespace Sample.Common.Authentication { using System; diff --git a/Samples/Common/Sample.Common/Authentication/UserPasswordAuthenticationProvider.cs b/Samples/Common/Sample.Common/Authentication/UserPasswordAuthenticationProvider.cs index 2ca4ce9c..6d493280 100644 --- a/Samples/Common/Sample.Common/Authentication/UserPasswordAuthenticationProvider.cs +++ b/Samples/Common/Sample.Common/Authentication/UserPasswordAuthenticationProvider.cs @@ -3,7 +3,10 @@ // Licensed under the MIT license. // -namespace OnlineMeeting +// THIS CODE HAS NOT BEEN TESTED RIGOROUSLY.USING THIS CODE IN PRODUCTION ENVIRONMENT IS STRICTLY NOT RECOMMENDED. +// THIS SAMPLE IS PURELY FOR DEMONSTRATION PURPOSES ONLY. +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. +namespace Sample.Common.Authentication { using System; using System.Collections.Generic; @@ -22,28 +25,9 @@ namespace OnlineMeeting public class UserPasswordAuthenticationProvider : ObjectRoot, IRequestAuthenticationProvider { /// - /// Initializes a new instance of the class. + /// The application name. /// - /// The application identifier. - /// The application secret. - /// The username to be used. - /// Password assoicated with the passed username. - /// The logger. - public UserPasswordAuthenticationProvider(string appId, string appSecret, string userName, string password, IGraphLogger logger) - : base(logger.NotNull(nameof(logger)).CreateShim(nameof(UserPasswordAuthenticationProvider))) - { - Debug.Assert(!string.IsNullOrWhiteSpace(appId), $"Invalid {nameof(appId)}."); - Debug.Assert(!string.IsNullOrWhiteSpace(appSecret), $"Invalid {nameof(appSecret)}."); - Debug.Assert(!string.IsNullOrWhiteSpace(userName), $"Invalid {nameof(userName)}."); - Debug.Assert(!string.IsNullOrWhiteSpace(password), $"Invalid {nameof(password)}."); - - this.AppId = appId; - this.AppSecret = appSecret; - - // NOTE: STORING USERNAME/PASSWORD IN A FILE IS NOT SAFE. THIS SAMPLE IS FOR DEMONSTRATION PURPOSE ONLY. - this.UserName = userName; - this.Password = password; - } + private readonly string appName; /// /// Gets the application identifier. @@ -51,7 +35,7 @@ public UserPasswordAuthenticationProvider(string appId, string appSecret, string /// /// The application identifier. /// - private string AppId { get; } + private readonly string appId; /// /// Gets the application secret. @@ -59,17 +43,37 @@ public UserPasswordAuthenticationProvider(string appId, string appSecret, string /// /// The application secret. /// - private string AppSecret { get; } + private readonly string appSecret; /// /// Gets UserName to be passed to oauth service. /// - private string UserName { get; } + private readonly string userName; /// /// Gets password to be passed to oauth service. /// - private string Password { get; } + private readonly string password; + + /// + /// Initializes a new instance of the class. + /// + /// The application name. + /// The application identifier. + /// The application secret. + /// The username to be used. + /// Password assoicated with the passed username. + /// The logger. + public UserPasswordAuthenticationProvider(string appName, string appId, string appSecret, string userName, string password, IGraphLogger logger) + : base(logger.NotNull(nameof(logger)).CreateShim(nameof(UserPasswordAuthenticationProvider))) + { + this.appName = appName.NotNullOrWhitespace(nameof(appName)); + this.appId = appId.NotNullOrWhitespace(nameof(appId)); + this.appSecret = appSecret.NotNullOrWhitespace(nameof(appSecret)); + + this.userName = userName.NotNullOrWhitespace(nameof(userName)); + this.password = password.NotNullOrWhitespace(nameof(password)); + } /// public async Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, string tenantId) @@ -79,7 +83,7 @@ public async Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, s const string BearerPrefix = "Bearer"; const string ReplaceString = "{tenant}"; const string TokenAuthorityMicrosoft = "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token"; - const string Resource = @"https://graph.microsoft.com"; + const string Resource = @"https://graph.microsoft.com/.default"; var tokenLink = TokenAuthorityMicrosoft.Replace(ReplaceString, tenantId); OAuthResponse authResult = null; @@ -88,18 +92,22 @@ public async Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, s { using (var httpClient = new HttpClient()) { - var result1 = await httpClient.PostAsync(tokenLink, new FormUrlEncodedContent(new[] + var result = await httpClient.PostAsync(tokenLink, new FormUrlEncodedContent(new[] { - new KeyValuePair("resource", Resource), - new KeyValuePair("client_id", this.AppId), new KeyValuePair("grant_type", "password"), - new KeyValuePair("username", this.UserName), - new KeyValuePair("password", this.Password), - new KeyValuePair("scope", "openid"), - new KeyValuePair("client_secret", this.AppSecret), + new KeyValuePair("username", this.userName), + new KeyValuePair("password", this.password), + new KeyValuePair("scope", Resource), + new KeyValuePair("client_id", this.appId), + new KeyValuePair("client_secret", this.appSecret), })).ConfigureAwait(false); - var content = await result1.Content.ReadAsStringAsync().ConfigureAwait(false); + if (!result.IsSuccessStatusCode) + { + throw new Exception("Failed to generate user token."); + } + + var content = await result.Content.ReadAsStringAsync().ConfigureAwait(false); authResult = JsonConvert.DeserializeObject(content); request.Headers.Authorization = new AuthenticationHeaderValue(BearerPrefix, authResult.Access_Token); @@ -107,7 +115,7 @@ public async Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, s } catch (Exception ex) { - this.GraphLogger.Error(ex, $"Failed to generate user token for user: {this.UserName}"); + this.GraphLogger.Error(ex, $"Failed to generate user token for user: {this.userName}"); throw; } @@ -117,6 +125,7 @@ public async Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, s /// public Task ValidateInboundRequestAsync(HttpRequestMessage request) { + // Currently no scenarios on /user | /me path for inbound requests. throw new NotImplementedException(); } diff --git a/Samples/Common/Sample.Common/Sample.Common.csproj b/Samples/Common/Sample.Common/Sample.Common.csproj index 9f52df5c..48dce420 100644 --- a/Samples/Common/Sample.Common/Sample.Common.csproj +++ b/Samples/Common/Sample.Common/Sample.Common.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/Samples/V1.0Samples/LocalMediaSamples/AudioVideoPlaybackBot/FrontEnd/FrontEnd.csproj b/Samples/V1.0Samples/LocalMediaSamples/AudioVideoPlaybackBot/FrontEnd/FrontEnd.csproj index b6213b64..a5ef1595 100644 --- a/Samples/V1.0Samples/LocalMediaSamples/AudioVideoPlaybackBot/FrontEnd/FrontEnd.csproj +++ b/Samples/V1.0Samples/LocalMediaSamples/AudioVideoPlaybackBot/FrontEnd/FrontEnd.csproj @@ -60,7 +60,7 @@ - + diff --git a/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/Bot/CallHandler.cs b/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/Bot/CallHandler.cs index a83fc9b2..ac3e0e8e 100644 --- a/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/Bot/CallHandler.cs +++ b/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/Bot/CallHandler.cs @@ -8,13 +8,17 @@ namespace Sample.HueBot.Bot using System; using System.Drawing; using System.Linq; + using System.Runtime.InteropServices; using System.Threading; + using System.Timers; using Microsoft.Graph; using Microsoft.Graph.Communications.Calls; using Microsoft.Graph.Communications.Calls.Media; using Microsoft.Graph.Communications.Common.Telemetry; using Microsoft.Graph.Communications.Resources; using Microsoft.Skype.Bots.Media; + using Sample.Common; + using Timer = System.Timers.Timer; /// /// Call Handler Logic. @@ -26,6 +30,11 @@ public class CallHandler : IDisposable /// public const uint DominantSpeakerNone = DominantSpeakerChangedEventArgs.None; + /// + /// How long the timer should wait before ending the call. + /// + private const double WaitForMs = 1000 * 60 * 5; + /// /// The time between each video frame capturing. /// @@ -66,6 +75,11 @@ public class CallHandler : IDisposable /// private int maxIngestFrameCount = 100; + /// + /// The Timer to end the call. + /// + private Timer endCallTimer; + /// /// Initializes a new instance of the class. /// @@ -83,6 +97,10 @@ public CallHandler(ICall statefulCall) } this.Call.Participants.OnUpdated += this.OnParticipantsUpdated; + this.endCallTimer = new Timer(CallHandler.WaitForMs); + this.endCallTimer.Enabled = false; + this.endCallTimer.AutoReset = false; + this.endCallTimer.Elapsed += this.OnTimerElapsed; } /// @@ -129,6 +147,8 @@ public void Dispose() { participant.OnUpdated -= this.OnParticipantUpdated; } + + this.endCallTimer.Elapsed -= this.OnTimerElapsed; } /// @@ -186,10 +206,40 @@ private void OnParticipantsUpdated(IParticipantCollection sender, CollectionEven participant.OnUpdated -= this.OnParticipantUpdated; } + bool nonBotParticipants = false; + foreach (var participant in sender) + { + var isBot = participant.Resource.Info.Identity.Application != null; + if (!isBot) + { + nonBotParticipants = true; + break; + } + } + + if (nonBotParticipants) + { + this.endCallTimer.Stop(); + } + else + { + this.endCallTimer.Start(); + } + // Subscribed participant might have left the meeting. this.Subscribe(); } + /// + /// When the end call timer elapses, end the call. + /// + /// The sender object. + /// Event args containing the elapsed event information. + private void OnTimerElapsed(object sender, ElapsedEventArgs args) + { + _ = this.Call.DeleteAsync().ForgetAndLogExceptionAsync(this.Call.GraphLogger); + } + /// /// Event triggered when a participant's properties are updated. /// diff --git a/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/HueBot.csproj b/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/HueBot.csproj index 183a08bc..364f71b3 100644 --- a/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/HueBot.csproj +++ b/Samples/V1.0Samples/LocalMediaSamples/HueBot/HueBot/HueBot.csproj @@ -20,7 +20,7 @@ - + diff --git a/changelog.md b/changelog.md index ffcfddec..3a3ea59e 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,12 @@ This changelog covers what's changed in Microsoft Graph Communications SDK and its associated samples. +## Oct 2019 + +- Updated Communications libraries 1.1.0-prerelease.1855 +- Updated to latest /beta contacts. + - For a full list of changes refer to the [graph blog](https://developer.microsoft.com/en-us/graph/blogs/breaking-changes-calls-and-online-meetings-api-updates-in-microsoft-graph-beta-2/). + ## Sept 2019 - Updated Media library 1.13.1.324-alpha diff --git a/docs/client/Microsoft.Graph.Communications.Client.Cache.CacheContext-1.html b/docs/client/Microsoft.Graph.Communications.Client.Cache.CacheContext-1.html index c46a1311..d752bda2 100644 --- a/docs/client/Microsoft.Graph.Communications.Client.Cache.CacheContext-1.html +++ b/docs/client/Microsoft.Graph.Communications.Client.Cache.CacheContext-1.html @@ -112,7 +112,6 @@
Assembly: Microsoft.Graph.Communications.Client.dll
Syntax
public struct CacheContext<TEntity>
-
     where TEntity : Entity
Type Parameters
diff --git a/docs/client/Microsoft.Graph.Communications.Client.Cache.ICache.html b/docs/client/Microsoft.Graph.Communications.Client.Cache.ICache.html index 4a677044..3115a792 100644 --- a/docs/client/Microsoft.Graph.Communications.Client.Cache.ICache.html +++ b/docs/client/Microsoft.Graph.Communications.Client.Cache.ICache.html @@ -104,7 +104,6 @@

Declaration

Task<string> GetDataAsync<T>(IEnumerable<IGraphProperty> properties, string resourcePath, CancellationToken cancellationToken = default(CancellationToken))
-
     where T : Entity
Parameters
@@ -179,7 +178,6 @@

Declaration

Task<IEnumerable<string>> GetDataCollectionAsync<T>(IEnumerable<IGraphProperty> properties, string resourcePath, CancellationToken cancellationToken = default(CancellationToken))
-
     where T : Entity
Parameters
diff --git a/docs/client/Microsoft.Graph.Communications.Client.Cache.ServiceCache.html b/docs/client/Microsoft.Graph.Communications.Client.Cache.ServiceCache.html index 237ccad3..679481eb 100644 --- a/docs/client/Microsoft.Graph.Communications.Client.Cache.ServiceCache.html +++ b/docs/client/Microsoft.Graph.Communications.Client.Cache.ServiceCache.html @@ -161,7 +161,6 @@

Declaration

public Task<string> GetDataAsync<T>(IEnumerable<IGraphProperty> properties, string resourcePath, CancellationToken cancellationToken = default(CancellationToken))
-
     where T : Entity
Parameters
@@ -236,7 +235,6 @@

Declaration

public Task<IEnumerable<string>> GetDataCollectionAsync<T>(IEnumerable<IGraphProperty> properties, string resourcePath, CancellationToken cancellationToken = default(CancellationToken))
-
     where T : Entity
Parameters
diff --git a/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphAuthClient.html b/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphAuthClient.html index bdd18a97..cc580de1 100644 --- a/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphAuthClient.html +++ b/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphAuthClient.html @@ -181,7 +181,6 @@

Declaration

protected override Task<IGraphResponse<T2>> SendHttpRequestAsync<T1, T2>(IGraphRequest<T1> graphRequest, CancellationToken cancellationToken)
-
     where T1 : class where T2 : class
Parameters
diff --git a/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphClientWrapper.html b/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphClientWrapper.html index 1e2fb00f..3448454a 100644 --- a/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphClientWrapper.html +++ b/docs/client/Microsoft.Graph.Communications.Client.Transport.GraphClientWrapper.html @@ -218,7 +218,6 @@

Declaration

public Task<IGraphResponse> SendAsync<T>(IGraphRequest<T> request, CancellationToken cancellationToken = default(CancellationToken))
-
     where T : class
Parameters
@@ -280,7 +279,6 @@

Declaration

public Task<IGraphResponse<T2>> SendAsync<T1, T2>(IGraphRequest<T1> request, CancellationToken cancellationToken = default(CancellationToken))
-
     where T1 : class where T2 : class
Parameters
diff --git a/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventArgs-1.html b/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventArgs-1.html index e771ffa8..ed41bc72 100644 --- a/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventArgs-1.html +++ b/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventArgs-1.html @@ -120,7 +120,6 @@
Assembly: Microsoft.Graph.Communications.Client.dll
Syntax
public class ResourceEventArgs<TEntity>
-
     where TEntity : Entity
Type Parameters
diff --git a/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventHandler-2.html b/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventHandler-2.html index 3784b6a8..39cee709 100644 --- a/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventHandler-2.html +++ b/docs/client/Microsoft.Graph.Communications.Resources.ResourceEventHandler-2.html @@ -91,7 +91,6 @@
Assembly: Microsoft.Graph.Communications.Client.dll
Syntax
public delegate void ResourceEventHandler<in TSender, TEntity>(TSender sender, ResourceEventArgs<TEntity> e)
-
     where TEntity : Entity;
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.CollectionUtils.html b/docs/common/Microsoft.Graph.Communications.Common.CollectionUtils.html index c426487f..9ae363c0 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.CollectionUtils.html +++ b/docs/common/Microsoft.Graph.Communications.Common.CollectionUtils.html @@ -516,7 +516,6 @@

Declaration

public static void TryRemoveAndDispose<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, TKey key)
-
     where TValue : IDisposable
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.EnumUtils.html b/docs/common/Microsoft.Graph.Communications.Common.EnumUtils.html index e1de7654..d868da8b 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.EnumUtils.html +++ b/docs/common/Microsoft.Graph.Communications.Common.EnumUtils.html @@ -174,7 +174,6 @@

Declaration

public static TEnum Parse<TEnum>(string value)
-
     where TEnum : struct, IComparable, IFormattable, IConvertible
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.StateMachine-1.html b/docs/common/Microsoft.Graph.Communications.Common.StateMachine-1.html index 82fde236..70eeaf67 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.StateMachine-1.html +++ b/docs/common/Microsoft.Graph.Communications.Common.StateMachine-1.html @@ -118,7 +118,6 @@
Assembly: Microsoft.Graph.Communications.Common.dll
Syntax
public sealed class StateMachine<TStateEnum>
-
     where TStateEnum : struct, IComparable, IFormattable, IConvertible
Type Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.Telemetry.LoggingExtensions.html b/docs/common/Microsoft.Graph.Communications.Common.Telemetry.LoggingExtensions.html index edeace42..bd025b91 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.Telemetry.LoggingExtensions.html +++ b/docs/common/Microsoft.Graph.Communications.Common.Telemetry.LoggingExtensions.html @@ -759,7 +759,6 @@

Declaration

public static T GetTypedProperty<T>(this LogEvent logEvent)
-
     where T : class
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.Transport.GraphHttpClient.html b/docs/common/Microsoft.Graph.Communications.Common.Transport.GraphHttpClient.html index 440d4875..1dc12fad 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.Transport.GraphHttpClient.html +++ b/docs/common/Microsoft.Graph.Communications.Common.Transport.GraphHttpClient.html @@ -492,7 +492,6 @@

Declaration

public Task<IGraphResponse> SendAsync<T>(IGraphRequest<T> graphRequest, CancellationToken cancellationToken = default(CancellationToken))
-
     where T : class
Parameters
@@ -554,7 +553,6 @@

Declaration

public Task<IGraphResponse<T2>> SendAsync<T1, T2>(IGraphRequest<T1> graphRequest, CancellationToken cancellationToken = default(CancellationToken))
-
     where T1 : class where T2 : class
Parameters
@@ -623,7 +621,6 @@

Declaration

protected virtual Task<IGraphResponse<T2>> SendHttpRequestAsync<T1, T2>(IGraphRequest<T1> graphRequest, CancellationToken cancellationToken)
-
     where T1 : class where T2 : class
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.Transport.HttpResponseMessageExtensions.html b/docs/common/Microsoft.Graph.Communications.Common.Transport.HttpResponseMessageExtensions.html index 437979d0..3fbf2e85 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.Transport.HttpResponseMessageExtensions.html +++ b/docs/common/Microsoft.Graph.Communications.Common.Transport.HttpResponseMessageExtensions.html @@ -266,7 +266,6 @@

Declaration

public static Task<IGraphResponse<T>> ToGraphResponseAsync<T>(this HttpResponseMessage httpResponse, JsonSerializerSettings serializerSettings = null)
-
     where T : class
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.Transport.IGraphClient.html b/docs/common/Microsoft.Graph.Communications.Common.Transport.IGraphClient.html index 453dab45..af198c0e 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.Transport.IGraphClient.html +++ b/docs/common/Microsoft.Graph.Communications.Common.Transport.IGraphClient.html @@ -155,7 +155,6 @@

Declaration

Task<IGraphResponse> SendAsync<TRequest>(IGraphRequest<TRequest> request, CancellationToken cancellationToken = default(CancellationToken))
-
     where TRequest : class
Parameters
@@ -222,7 +221,6 @@

Declaration

Task<IGraphResponse<TResponse>> SendAsync<TRequest, TResponse>(IGraphRequest<TRequest> request, CancellationToken cancellationToken = default(CancellationToken))
-
     where TRequest : class where TResponse : class
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.Utilities.html b/docs/common/Microsoft.Graph.Communications.Common.Utilities.html index d0a28a05..5eb49f08 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.Utilities.html +++ b/docs/common/Microsoft.Graph.Communications.Common.Utilities.html @@ -276,7 +276,6 @@

Declaration

public static void SafeDispose<T>(ref T t, IGraphLogger logger = null)
-
     where T : class, IDisposable
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.Validator.html b/docs/common/Microsoft.Graph.Communications.Common.Validator.html index e5e2a53e..6e9692ae 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.Validator.html +++ b/docs/common/Microsoft.Graph.Communications.Common.Validator.html @@ -366,7 +366,6 @@

Declaration

public static T Equals<T, TE>(this T value, T expected, string message = null)
-
     where TE : Exception
Parameters
@@ -537,7 +536,6 @@

Declaration

public static void InRange<T>(this T value, T minValue, T maxValue, string paramName = null)
-
     where T : IComparable<T>
Parameters
@@ -682,7 +680,6 @@

Declaration

public static void IsFalse<T>(this bool condition, string message = null)
-
     where T : Exception
Parameters
@@ -811,7 +808,6 @@

Declaration

public static void IsTrue<T>(this bool condition, string message = null)
-
     where T : Exception
Parameters
@@ -862,7 +858,6 @@

Declaration

public static T NotEmpty<T>(this T obj, string paramName = null, string message = null)
-
     where T : IEnumerable
Parameters
diff --git a/docs/common/Microsoft.Graph.Communications.Common.WeakKey-1.html b/docs/common/Microsoft.Graph.Communications.Common.WeakKey-1.html index 64f48868..3222ed17 100644 --- a/docs/common/Microsoft.Graph.Communications.Common.WeakKey-1.html +++ b/docs/common/Microsoft.Graph.Communications.Common.WeakKey-1.html @@ -117,7 +117,6 @@
Assembly: Microsoft.Graph.Communications.Common.dll
Syntax
public class WeakKey<T>
-
     where T : class
Type Parameters
diff --git a/docs/index.html b/docs/index.html index 9319805f..f2cca265 100644 --- a/docs/index.html +++ b/docs/index.html @@ -78,8 +78,9 @@

SDK

The Graph Calling SDK is built on top of the Microsoft Graph API and distributed as NuGet packages. The Core Concepts article is designed to better explain all the constructs used by the SDKs. To dive right in and deploy a Calling Bot refer to the documentation in each sample for further instructions.

The SDK is divided into multiple nuget packages each described as below.

    -
  • Microsoft.Graph.Communications.Core (nuget): This library contains the calling contracts and is a duplicate of Microsoft.Graph SDK but only with Communication APIs.
  • Microsoft.Graph.Communications.Common (nuget): This is the nuget containing all the utilities used throughout the Stateful SDK. It contains telemetry, http, obfuscation support along with helper methods.
  • +
  • Microsoft.Graph.Communications.Core (nuget): This library contains the serialization and notification for the communications APIs.
  • +
  • Microsoft.Graph.Communications.Core.Calls (nuget): This library contains the calling contracts and is a duplicate of Microsoft.Graph SDK but only with Communication APIs.
  • Microsoft.Graph.Communications.Client (nuget): This is the base client for the Stateful SDK. This implements all the common SDK features used within different verticals like calling, etc.
  • Microsoft.Graph.Communications.Calls (nuget): This is the SDK that implements calling APIs. This supports making, receiving, and joining calls with Microsoft Teams users, and creating voice and video enabled bots.
  • Microsoft.Graph.Communications.Calls.Media (nuget): This library allows developers to use the Microsoft.Graph.Communications.Calls SDK and gain direct access to the audio, video, screen sharing, and data streams. This is an optional library on top of Microsoft.Graph.Communications.Calls
  • @@ -89,9 +90,9 @@

    Concepts and Examples

    For more details on concepts used by the SDK and examples on joining calls and receiving calls please refer to the concepts and examples page.

    You can find samples using the following service:

    ICommunicationsClient and Extension Methods

    The Stateful SDK is exposed using a single class ICommunicationsClient. This class is defined in the Microsoft.Graph.Communications.Client nuget and has no dependency on the Microsoft.Graph.Communications.Calls calling vertical nuget package. The different verticals therefore make heavy usage of extension methods on ICommunicationsClient rather than standalone functions or properties. The intention here is to add new verticals into the ICommunicationsClient using the same pattern without the ICommunicationsClient itself taking a dependency on the new vertical's nuget, which provides greater decoupling between future verticals we will support. For a usage example please see the ICommunicationsClient.Calls() extension method.

    diff --git a/docs/index.json b/docs/index.json index d2d7ad97..5384ea2b 100644 --- a/docs/index.json +++ b/docs/index.json @@ -1,1998 +1,1993 @@ { - "common/Microsoft.Graph.Communications.Common.WeakKeyDictionary-2.html": { - "href": "common/Microsoft.Graph.Communications.Common.WeakKeyDictionary-2.html", - "title": "Class WeakKeyDictionary", - "keywords": "Class WeakKeyDictionary Dictionary with weak reference for the key. Inheritance Object ConcurrentDictionary < WeakKey , TValue> WeakKeyDictionary Implements IDictionary < WeakKey , TValue> ICollection < KeyValuePair < WeakKey , TValue>> IDictionary ICollection IReadOnlyDictionary < WeakKey , TValue> IReadOnlyCollection < KeyValuePair < WeakKey , TValue>> IEnumerable < KeyValuePair < WeakKey , TValue>> IEnumerable Inherited Members ConcurrentDictionary, TValue>.TryAdd(WeakKey, TValue) ConcurrentDictionary, TValue>.ContainsKey(WeakKey) ConcurrentDictionary, TValue>.TryRemove(WeakKey, TValue) ConcurrentDictionary, TValue>.TryGetValue(WeakKey, TValue) ConcurrentDictionary, TValue>.TryUpdate(WeakKey, TValue, TValue) ConcurrentDictionary, TValue>.Clear() System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.ICollection, TValue>>.CopyTo(System.Collections.Generic.KeyValuePair, TValue>[], System.Int32) ConcurrentDictionary, TValue>.ToArray() ConcurrentDictionary, TValue>.GetEnumerator() ConcurrentDictionary, TValue>.GetOrAdd(WeakKey, Func, TValue>) ConcurrentDictionary, TValue>.GetOrAdd(WeakKey, TValue) ConcurrentDictionary, TValue>.GetOrAdd(WeakKey, Func, TArg, TValue>, TArg) ConcurrentDictionary, TValue>.AddOrUpdate(WeakKey, Func, TArg, TValue>, Func, TValue, TArg, TValue>, TArg) ConcurrentDictionary, TValue>.AddOrUpdate(WeakKey, Func, TValue>, Func, TValue, TValue>) ConcurrentDictionary, TValue>.AddOrUpdate(WeakKey, TValue, Func, TValue, TValue>) System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.IDictionary, TValue>.Add(Microsoft.Graph.Communications.Common.WeakKey, TValue) System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.IDictionary, TValue>.Remove(Microsoft.Graph.Communications.Common.WeakKey) System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.ICollection, TValue>>.Add(System.Collections.Generic.KeyValuePair, TValue>) System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.ICollection, TValue>>.Contains(System.Collections.Generic.KeyValuePair, TValue>) System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.ICollection, TValue>>.Remove(System.Collections.Generic.KeyValuePair, TValue>) ConcurrentDictionary, TValue>.IEnumerable.GetEnumerator() ConcurrentDictionary, TValue>.IDictionary.Add(Object, Object) ConcurrentDictionary, TValue>.IDictionary.Contains(Object) ConcurrentDictionary, TValue>.IDictionary.GetEnumerator() ConcurrentDictionary, TValue>.IDictionary.Remove(Object) System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.IDictionary.get_Item(System.Object) System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.IDictionary.set_Item(System.Object, System.Object) ConcurrentDictionary, TValue>.ICollection.CopyTo(Array, Int32) ConcurrentDictionary, TValue>.Item[WeakKey] ConcurrentDictionary, TValue>.Count ConcurrentDictionary, TValue>.IsEmpty ConcurrentDictionary, TValue>.Keys System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.IReadOnlyDictionary, TValue>.Keys ConcurrentDictionary, TValue>.Values System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.IReadOnlyDictionary, TValue>.Values System.Collections.Concurrent.ConcurrentDictionary, TValue>.System.Collections.Generic.ICollection, TValue>>.IsReadOnly ConcurrentDictionary, TValue>.IDictionary.IsFixedSize ConcurrentDictionary, TValue>.IDictionary.IsReadOnly ConcurrentDictionary, TValue>.IDictionary.Keys ConcurrentDictionary, TValue>.IDictionary.Values ConcurrentDictionary, TValue>.IDictionary.Item[Object] ConcurrentDictionary, TValue>.ICollection.IsSynchronized ConcurrentDictionary, TValue>.ICollection.SyncRoot Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Microsoft.Graph.Communications.Common Assembly : Microsoft.Graph.Communications.Common.dll Syntax public class WeakKeyDictionary : ConcurrentDictionary, TValue>, IDictionary, TValue>, ICollection, TValue>>, IDictionary, ICollection, IReadOnlyDictionary, TValue>, IReadOnlyCollection, TValue>>, IEnumerable, TValue>>, IEnumerable where TKey : class Type Parameters Name Description TKey Key type which must be a reference type. TValue Value type. Constructors WeakKeyDictionary() Declaration public WeakKeyDictionary() Methods Cleanup() Cleans keys where the weak references have been garbage collected. Declaration public void Cleanup() Implements System.Collections.Generic.IDictionary System.Collections.Generic.ICollection System.Collections.IDictionary System.Collections.ICollection System.Collections.Generic.IReadOnlyDictionary System.Collections.Generic.IReadOnlyCollection System.Collections.Generic.IEnumerable System.Collections.IEnumerable Extension Methods AdditionalDataExtensions.SetInAdditionalData(Object, String, Object) Extensions.Pin(Object) Extensions.ChangeType(Object, Type) Extensions.ChangeType(Object) Extensions.TryDispose(Object, IGraphLogger) CollectionUtils.ForEach(IEnumerable, Action) CollectionUtils.ForEachParallel(IEnumerable, Action, IGraphLogger) CollectionUtils.GetValueOrDefault(IDictionary, TKey) CollectionUtils.GetValueOrDefault(IDictionary, TKey, TValue) CollectionUtils.AddRange(ICollection, IEnumerable) CollectionUtils.ToSortedList(IEnumerable, Func) Validator.Any(IEnumerable) Validator.FirstObject(IEnumerable, Func) Validator.FirstObject(IEnumerable) Validator.IsNull(Object, String, String) Validator.NotNull(T, String, String) Validator.NotEmpty(T, String, String) Validator.Equals(T, T, String, String) Validator.Equals(T, T, String) Validator.NotEquals(T, T, String, String) Validator.VerifyNotContainsKey(IDictionary, TK) Validator.VerifyContainsKey(IDictionary, TK) Validator.VerifyContainsKey(IReadOnlyDictionary, TK) Validator.VerifyContains(IEnumerable, T)" + "common/Microsoft.Graph.Communications.Common.Telemetry.LogEvent.html": { + "href": "common/Microsoft.Graph.Communications.Common.Telemetry.LogEvent.html", + "title": "Class LogEvent", + "keywords": "Class LogEvent Log data Inheritance Object LogEvent Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Microsoft.Graph.Communications.Common.Telemetry Assembly : Microsoft.Graph.Communications.Common.dll Syntax public class LogEvent Constructors LogEvent() Declaration public LogEvent() Properties CallerInfo Gets or sets the caller information Declaration public CallerInfo CallerInfo { get; set; } Property Value Type Description CallerInfo CallerInfoString Gets the caller information string. Declaration public string CallerInfoString { get; } Property Value Type Description String Component Gets or sets the component in which the log is created. Declaration public string Component { get; set; } Property Value Type Description String CorrelationId Gets or sets the correlation id Declaration public Guid CorrelationId { get; set; } Property Value Type Description Guid EventType Gets or sets the type of the event. Declaration public LogEventType EventType { get; set; } Property Value Type Description LogEventType Level Gets or sets the trace level of the event. Declaration public TraceLevel Level { get; set; } Property Value Type Description TraceLevel LogicalThreadId Gets or sets the logical thread identifier. Declaration public uint LogicalThreadId { get; set; } Property Value Type Description UInt32 ManagedThreadId Gets or sets the thread ID. Declaration public int ManagedThreadId { get; set; } Property Value Type Description Int32 Message Gets or sets the Description of the event. Declaration public string Message { get; set; } Property Value Type Description String ProcessId Gets or sets the process ID. Declaration public int ProcessId { get; set; } Property Value Type Description Int32 Properties Gets or sets the Custom properties for the event. Declaration public IReadOnlyDictionary Properties { get; set; } Property Value Type Description IReadOnlyDictionary < Type , Object > PropertiesString Gets the custom properties in string format. Declaration public string PropertiesString { get; } Property Value Type Description String RequestId Gets or sets the request identifier. Declaration public Guid RequestId { get; set; } Property Value Type Description Guid Timestamp Gets or sets the Timestamp of the event. Declaration public DateTime Timestamp { get; set; } Property Value Type Description DateTime Extension Methods AdditionalDataExtensions.SetInAdditionalData(Object, String, Object) Extensions.Pin(Object) Extensions.ChangeType(Object, Type) Extensions.ChangeType(Object) Extensions.TryDispose(Object, IGraphLogger) Validator.IsNull(Object, String, String) Validator.NotNull(T, String, String) Validator.Equals(T, T, String, String) Validator.Equals(T, T, String) Validator.NotEquals(T, T, String, String) LoggingExtensions.GetTypedProperties(LogEvent, Type) LoggingExtensions.GetTypedProperty(LogEvent)" }, - "common/Microsoft.Graph.Communications.Common.Telemetry.HttpLogging.Filters.BaseFilter-2.html": { - "href": "common/Microsoft.Graph.Communications.Common.Telemetry.HttpLogging.Filters.BaseFilter-2.html", - "title": "Class BaseFilter", - "keywords": "Class BaseFilter Base filter. Inheritance Object BaseFilter BaseFilter ContentDispositionFilter ContentTypeFilter HeaderFilter UriFilter Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Microsoft.Graph.Communications.Common.Telemetry.HttpLogging.Filters Assembly : Microsoft.Graph.Communications.Common.dll Syntax public abstract class BaseFilter : BaseFilter Type Parameters Name Description T1 Type of input for the filter. T2 Return value for the evaluator. Constructors BaseFilter() Declaration protected BaseFilter() Properties MatchableString Gets or sets the string for which this filter is a match. Declaration public T2 MatchableString { get; protected set; } Property Value Type Description T2 MatchEvaluator Gets or sets the match evaluator that converts the input value to target value. Declaration public Func MatchEvaluator { get; protected set; } Property Value Type Description Func Extension Methods AdditionalDataExtensions.SetInAdditionalData(Object, String, Object) Extensions.Pin(Object) Extensions.ChangeType(Object, Type) Extensions.ChangeType(Object) Extensions.TryDispose(Object, IGraphLogger) Validator.IsNull(Object, String, String) Validator.NotNull(T, String, String) Validator.Equals(T, T, String, String) Validator.Equals(T, T, String) Validator.NotEquals(T, T, String, String)" + "common/Microsoft.Graph.Communications.Common.Telemetry.ClientEtwLogger.html": { + "href": "common/Microsoft.Graph.Communications.Common.Telemetry.ClientEtwLogger.html", + "title": "Class ClientEtwLogger", + "keywords": "Class ClientEtwLogger Logger for client that publishes to ETW. Inheritance Object EventSource ClientEtwLogger Implements IDisposable Inherited Members EventSource.IsEnabled() EventSource.IsEnabled(EventLevel, EventKeywords) EventSource.IsEnabled(EventLevel, EventKeywords, EventChannel) EventSource.GetGuid(Type) EventSource.GetName(Type) EventSource.GenerateManifest(Type, String) EventSource.GenerateManifest(Type, String, EventManifestOptions) EventSource.GetSources() EventSource.SendCommand(EventSource, EventCommand, IDictionary) EventSource.SetCurrentThreadActivityId(Guid) EventSource.SetCurrentThreadActivityId(Guid, Guid) EventSource.GetTrait(String) EventSource.ToString() EventSource.OnEventCommand(EventCommandEventArgs) EventSource.WriteEvent(Int32) EventSource.WriteEvent(Int32, Int32) EventSource.WriteEvent(Int32, Int32, Int32) EventSource.WriteEvent(Int32, Int32, Int32, Int32) EventSource.WriteEvent(Int32, Int64) EventSource.WriteEvent(Int32, Int64, Int64) EventSource.WriteEvent(Int32, Int64, Int64, Int64) EventSource.WriteEvent(Int32, String) EventSource.WriteEvent(Int32, String, String) EventSource.WriteEvent(Int32, String, String, String) EventSource.WriteEvent(Int32, String, Int32) EventSource.WriteEvent(Int32, String, Int32, Int32) EventSource.WriteEvent(Int32, String, Int64) EventSource.WriteEvent(Int32, Int64, String) EventSource.WriteEvent(Int32, Int32, String) EventSource.WriteEvent(Int32, Byte[]) EventSource.WriteEvent(Int32, Int64, Byte[]) EventSource.WriteEventCore(Int32, Int32, EventSource.EventData*) EventSource.WriteEventWithRelatedActivityIdCore(Int32, Guid*, Int32, EventSource.EventData*) EventSource.WriteEvent(Int32, Object[]) EventSource.WriteEventWithRelatedActivityId(Int32, Guid, Object[]) EventSource.Dispose() EventSource.Dispose(Boolean) EventSource.Write(String) EventSource.Write(String, EventSourceOptions) EventSource.Write(String, T) EventSource.Write(String, EventSourceOptions, T) EventSource.Write(String, EventSourceOptions, T) EventSource.Write(String, EventSourceOptions, Guid, Guid, T) EventSource.Name EventSource.Guid EventSource.Settings EventSource.CurrentThreadActivityId EventSource.ConstructionException EventSource.EventCommandExecuted Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Microsoft.Graph.Communications.Common.Telemetry Assembly : Microsoft.Graph.Communications.Common.dll Syntax [EventSource(Name = \"Microsoft-Graph-Telemetry-Client\")] public class ClientEtwLogger : EventSource, IDisposable Constructors ClientEtwLogger(IGraphLogger) Initializes a new instance of the ClientEtwLogger class. Declaration public ClientEtwLogger(IGraphLogger logger) Parameters Type Name Description IGraphLogger logger The logger. Methods HttpTrace(Guid, String, String, String, String, String, String, String, Int32, String, String, String, String, String, String) Trace for client's http calls. Declaration [Event(100, Level = EventLevel.Informational, Message = \"{5}\")] public void HttpTrace(Guid correlationId, string component, string traceLevel, string url, string transactionDirection, string message, string appName, string appId, int mtid, string callingLine, string traceType, string headers, string method, string responseCode, string responseTime) Parameters Type Name Description Guid correlationId The correlation identifier. String component The component. String traceLevel The trace level. String url The URL for the request. String transactionDirection The direction of the request this request/response corresponds to. String message The body for the request/response. String appName Name of the application. String appId The application identifier. Int32 mtid The managed tid. String callingLine The line in which log is produced. String traceType Denote whether this is request/response. String headers The headers. String method The method for the request. String responseCode The response code from response. String responseTime Time taken to process the request. Trace(Guid, String, String, String, String, String, Int32, String) Trace for client's normal trace calls. Declaration [Event(101, Level = EventLevel.Informational, Message = \"{3}\")] public void Trace(Guid correlationId, string component, string traceLevel, string message, string appName, string appId, int mtid, string callingLine) Parameters Type Name Description Guid correlationId The correlation identifier. String component The component. String traceLevel The trace level. String message The message. String appName Name of the application. String appId The application identifier. Int32 mtid The managed tid. String callingLine The line in which log is produced. Implements System.IDisposable Extension Methods AdditionalDataExtensions.SetInAdditionalData(Object, String, Object) Extensions.Pin(Object) Extensions.ChangeType(Object, Type) Extensions.ChangeType(Object) Extensions.TryDispose(Object, IGraphLogger) Validator.IsNull(Object, String, String) Validator.NotNull(T, String, String) Validator.Equals(T, T, String, String) Validator.Equals(T, T, String) Validator.NotEquals(T, T, String, String)" }, - "common/Microsoft.Graph.Communications.Common.Telemetry.Obfuscation.GraphObfuscationAttribute.html": { - "href": "common/Microsoft.Graph.Communications.Common.Telemetry.Obfuscation.GraphObfuscationAttribute.html", - "title": "Class GraphObfuscationAttribute", - "keywords": "Class GraphObfuscationAttribute Attribute used for decoration of data objects. This is used for obfuscation for logging. Inheritance Object Attribute GraphObfuscationAttribute Implements _Attribute Inherited Members Attribute.GetCustomAttributes(MemberInfo, Type) Attribute.GetCustomAttributes(MemberInfo, Type, Boolean) Attribute.GetCustomAttributes(MemberInfo) Attribute.GetCustomAttributes(MemberInfo, Boolean) Attribute.IsDefined(MemberInfo, Type) Attribute.IsDefined(MemberInfo, Type, Boolean) Attribute.GetCustomAttribute(MemberInfo, Type) Attribute.GetCustomAttribute(MemberInfo, Type, Boolean) Attribute.GetCustomAttributes(ParameterInfo) Attribute.GetCustomAttributes(ParameterInfo, Type) Attribute.GetCustomAttributes(ParameterInfo, Type, Boolean) Attribute.GetCustomAttributes(ParameterInfo, Boolean) Attribute.IsDefined(ParameterInfo, Type) Attribute.IsDefined(ParameterInfo, Type, Boolean) Attribute.GetCustomAttribute(ParameterInfo, Type) Attribute.GetCustomAttribute(ParameterInfo, Type, Boolean) Attribute.GetCustomAttributes(Module, Type) Attribute.GetCustomAttributes(Module) Attribute.GetCustomAttributes(Module, Boolean) Attribute.GetCustomAttributes(Module, Type, Boolean) Attribute.IsDefined(Module, Type) Attribute.IsDefined(Module, Type, Boolean) Attribute.GetCustomAttribute(Module, Type) Attribute.GetCustomAttribute(Module, Type, Boolean) Attribute.GetCustomAttributes(Assembly, Type) Attribute.GetCustomAttributes(Assembly, Type, Boolean) Attribute.GetCustomAttributes(Assembly) Attribute.GetCustomAttributes(Assembly, Boolean) Attribute.IsDefined(Assembly, Type) Attribute.IsDefined(Assembly, Type, Boolean) Attribute.GetCustomAttribute(Assembly, Type) Attribute.GetCustomAttribute(Assembly, Type, Boolean) Attribute.Equals(Object) Attribute.GetHashCode() Attribute.Match(Object) Attribute.IsDefaultAttribute() Attribute._Attribute.GetTypeInfoCount(UInt32) Attribute._Attribute.GetTypeInfo(UInt32, UInt32, IntPtr) Attribute._Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr) Attribute._Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) Attribute.TypeId Object.ToString() Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetType() Object.MemberwiseClone() Namespace : Microsoft.Graph.Communications.Common.Telemetry.Obfuscation Assembly : Microsoft.Graph.Communications.Common.dll Syntax [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] public class GraphObfuscationAttribute : Attribute, _Attribute Constructors GraphObfuscationAttribute() Declaration public GraphObfuscationAttribute() Properties Tag Gets or sets the tag. Declaration public ObfuscationTag Tag { get; set; } Property Value Type Description ObfuscationTag Implements System.Runtime.InteropServices._Attribute Extension Methods AdditionalDataExtensions.SetInAdditionalData(Object, String, Object) Extensions.Pin(Object) Extensions.ChangeType(Object, Type) Extensions.ChangeType(Object) Extensions.TryDispose(Object, IGraphLogger) Validator.IsNull(Object, String, String) Validator.NotNull(T, String, String) Validator.Equals(T, T, String, String) Validator.Equals(T, T, String) Validator.NotEquals(T, T, String, String) See Also Attribute" + "core_calls/Microsoft.Graph.ISubscribeToToneOperationRequestBuilder.html": { + "href": "core_calls/Microsoft.Graph.ISubscribeToToneOperationRequestBuilder.html", + "title": "Interface ISubscribeToToneOperationRequestBuilder", + "keywords": "Interface ISubscribeToToneOperationRequestBuilder The interface ISubscribeToToneOperationRequestBuilder. Namespace : Microsoft.Graph Assembly : Microsoft.Graph.Communications.Core.Calls.dll Syntax public interface ISubscribeToToneOperationRequestBuilder : ICommsOperationRequestBuilder, IEntityRequestBuilder, IBaseRequestBuilder Methods Request() Builds the request. Declaration ISubscribeToToneOperationRequest Request() Returns Type Description ISubscribeToToneOperationRequest The built request. Request(IEnumerable