public void ReturnsFalseIfNotCorrectExceptionType()
            {
                var e      = new Exception();
                var result = RetryWithExponentialBackoff.IsTransientError(e, null);

                Assert.False(result);
            }
        /// <summary>
        /// Retrieve a list of plannerPlan objects owned by a group object.
        /// </summary>
        /// <param name="groupId">The ID of the group (team) to retrieve the list of plannerPlan from.</param>
        /// <returns>If successful, this method returns a 200 OK response code and collection of plannerPlan objects in the response body. In case of errors, see HTTP status codes.</returns>
        public async Task <PlannerPlan[]> GetPlanners(string groupId)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            PlannerPlan[] planners;
            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.GetAsync(O365Settings.MsGraphBetaEndpoint + $"/groups/{groupId}/planner/plans/");
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
                var httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result;
                var root             = JsonConvert.DeserializeObject <RootElem <PlannerPlan> >(httpResultString);
                planners = root.Values;
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }
            return(planners);
        }
            public void ReturnsFalseIfResponseStatusBelow500OrWhitelisted(Exception e, HttpStatusCode status)
            {
                var response = new HttpResponseMessage(status);
                var result   = RetryWithExponentialBackoff.IsTransientError(e, response);

                Assert.False(result);
            }
            public void ReturnsTrueIfResponseStatusAbove500(Exception e, HttpStatusCode status)
            {
                var response = new HttpResponseMessage(status);
                var result   = RetryWithExponentialBackoff.IsTransientError(e, response);

                Assert.True(result);
            }
Example #5
0
        /// <summary>
        /// Send event card
        /// </summary>
        /// <param name="eventMessages">List of EventMessage</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        private async Task SendEventCard(List <EventMessage> eventMessages)
        {
            var tasks = Task.Run(() =>
            {
                Parallel.ForEach(eventMessages, new ParallelOptions {
                    MaxDegreeOfParallelism = MaxParallelism
                }, async(eventMessage) =>
                {
                    var activity  = eventMessage.Activity;
                    HeroCard card = null;
                    switch (eventMessage.MessageType)
                    {
                    case MessageType.Event:
                        card = CelebrationCard.GetEventCard(activity);
                        break;

                    case MessageType.Preview:
                        card = CelebrationCard.GetPreviewCard(activity);
                        break;
                    }

                    var task = this.connectorServiceHelper.SendPersonalMessageAsync(string.Empty, new List <Attachment> {
                        card.ToAttachment()
                    }, activity.ConversationId);

                    RetryWithExponentialBackoff retryBackOff = new RetryWithExponentialBackoff();
                    await retryBackOff.RunAsync(task, eventMessage, this.SuccessCallback, this.FailureCallback);
                });
            });

            await tasks;
        }
        /// <summary>
        /// Use this API to create a new plannerTask.
        /// </summary>
        /// <param name="planId">The plannerplan's ID to create a new plannerTask into.</param>
        /// <param name="bucket"></param>
        /// <param name="sTask"></param>
        /// <returns>If successful, this method returns 201 Created response code and plannerTask object in the response body. In case of errors, see HTTP status codes.</returns>
        private async Task <PlannerTask> CreateTask(string planId, PlannerBucket bucket, PlannerTask sTask)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            if (string.IsNullOrWhiteSpace(planId) ||
                bucket == null ||
                sTask == null)
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return(null);
            }

            dynamic body = new ExpandoObject();

            body.planId        = planId;
            body.bucketId      = bucket.Id;
            body.title         = sTask.Title;
            body.startDateTime = sTask.StartDateTime;
            body.dueDateTime   = sTask.DueDateTime;
            var bodyContent = JsonConvert.SerializeObject(body);

            cs.Debug($"\nBody content:\n-Title: {body.title}\n-Plan Id: {body.planId}");

            PlannerTask newTask;

            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.PostAsync(
                        new Uri(O365Settings.MsGraphBetaEndpoint + $"/planner/tasks"),
                        new StringContent(bodyContent, Encoding.UTF8, "application/json"));
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
                var httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result;
                newTask = JsonConvert.DeserializeObject <PlannerTask>(httpResultString);
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }
            return(newTask);
        }
        /// <summary>
        /// Update the properties of plannerplandetails object.
        /// </summary>
        /// <param name="planId"></param>
        /// <param name="eTag"></param>
        /// <param name="categoryDescriptions"></param>
        /// <param name="sharedWith"></param>
        /// <returns>If successful, this method returns a 200 OK response code and updated plannerPlanDetails object in the response body. In case of errors, see HTTP status codes.</returns>
        public async Task UpdatePlannerDetails(string planId, string eTag, object categoryDescriptions, object sharedWith)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            if (string.IsNullOrWhiteSpace(planId) ||
                string.IsNullOrWhiteSpace(eTag) ||
                categoryDescriptions == null ||
                sharedWith == null)
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return;
            }

            dynamic body = new ExpandoObject();

            body.categoryDescriptions = categoryDescriptions;
            body.sharedWith           = sharedWith;
            var bodyContent = JsonConvert.SerializeObject(body);

            cs.Debug($"Body content:\n-Plan Id: {planId}\n-Category Description: {body.categoryDescriptions}\n-Shared With: {body.sharedWith}");
            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.SendTeamsAsync
                                          (
                        HttpVerb.PATCH,
                        new Uri(O365Settings.MsGraphBetaEndpoint + $"/planner/plans/{planId}/details"),
                        eTag,
                        new StringContent(bodyContent, Encoding.UTF8, "application/json")
                                          );
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }
        }
Example #8
0
        /// <summary>
        /// Create a copy of a team. This operation also creates a copy of the corresponding group.
        /// </summary>
        /// <param name="request"></param>
        /// <returns>If successful, this method will return a 202 Accepted response code with a Location: header pointing to the operation resource.
        /// When the operation is complete, the operation resource will tell you the id of the created team.</returns>
        public async Task <bool> CloneTeam(InCloneTeamMessage request)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            bool created = false;

            if (request == null)
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return(created);
            }

            var bodyContent = JsonConvert.SerializeObject(request);

            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.PostAsync(O365Settings.MsGraphBetaEndpoint + $"/teams/{request.TeamId}/clone",
                                                                     new StringContent(bodyContent, Encoding.UTF8, "application/json"));
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
                created = true;
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }

            return(created);
        }
        /// <summary>
        /// Use this API to create a new plannerPlan.
        /// </summary>
        /// <param name="groupId">The group's ID (team) to create the plannerPlan into.</param>
        /// <returns>If successful, this method returns 201 Created response code and plannerPlan object in the response body. In case of errors, see HTTP status codes.</returns>
        public async Task CreatePlannerPlan(string groupId)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            if (string.IsNullOrWhiteSpace(groupId))
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return;
            }

            var plannerPlan = new PlannerPlan()
            {
                Id = groupId
            };
            var plannerPlanContent = JsonConvert.SerializeObject(plannerPlan);

            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.PostAsync(O365Settings.MsGraphBetaEndpoint + "/planner/plans",
                                                                     new StringContent(plannerPlanContent, Encoding.UTF8, "application/json"));
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }
        }
        /// <summary>
        /// Retrieve the properties and relationships of a channel.
        /// </summary>
        /// <param name="teamId"></param>
        /// <returns>If successful, this method returns a 200 OK response code and a channel object in the response body.</returns>
        public async Task <Channel[]> GetChannels(string teamId)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            if (string.IsNullOrWhiteSpace(teamId))
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return(null);
            }

            Channel[] channels = null;
            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.GetAsync(O365Settings.MsGraphBetaEndpoint + "teams/" + teamId + "/channels");
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
                var httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result;
                var root             = JsonConvert.DeserializeObject <RootElem <Channel> >(httpResultString);
                channels = root.Values;
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }
            return(channels);
        }
        /// <summary>
        /// Retrieve the properties and relationships of plannerplandetails object.
        /// </summary>
        /// <param name="planId">The plan's ID to get the properties and relationships from.</param>
        /// <returns>If successful, this method returns a 200 OK response code and plannerPlanDetails object in the response body. In case of errors, see HTTP status codes.</returns>
        public async Task <PlannerPlanDetails> GetPlannerDetails(string planId)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            if (string.IsNullOrWhiteSpace(planId))
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return(null);
            }

            PlannerPlanDetails details;

            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.GetAsync(O365Settings.MsGraphBetaEndpoint + $"/planner/plans/{planId}/details");
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
                var httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result;
                details = JsonConvert.DeserializeObject <PlannerPlanDetails>(httpResultString);
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }
            return(details);
        }
Example #12
0
        /// <summary>
        /// Delete a plannerBucket.
        /// </summary>
        /// <param name="bucketId">The plannerBucket's ID to delete.</param>
        /// <param name="eTag">eTag of the plannerBucket resource.</param>
        /// <returns>If successful, this method returns 204 No Content response code. It does not return anything in the response body. In case of errors, see HTTP status codes.</returns>
        public async Task DeleteBucket(string bucketId, string eTag)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            if (string.IsNullOrWhiteSpace(bucketId) ||
                string.IsNullOrWhiteSpace(eTag))
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return;
            }

            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.SendTeamsAsync(
                        HttpVerb.DELETE,
                        new Uri(O365Settings.MsGraphBetaEndpoint + $"/planner/buckets/{bucketId}"),
                        eTag,
                        null);
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw ex;
            }
        }
Example #13
0
        internal static TResponse DecorateWithRetry <TResponse>(Func <TResponse> apiCall)
        {
            var retry = new RetryWithExponentialBackoff();

            return(retry.Run(apiCall));
        }
            public void ReturnsTrueIfResponseNull(Exception e)
            {
                var result = RetryWithExponentialBackoff.IsTransientError(e, null);

                Assert.True(result);
            }
Example #15
0
        /// <summary>
        /// Update the properties of plannertaskdetails object.
        /// </summary>
        /// <param name="taskId"></param>
        /// <param name="eTag"></param>
        /// <param name="checklist"></param>
        /// <param name="description"></param>
        /// <param name="previewType"></param>
        /// <param name="references"></param>
        /// <returns>If successful, this method returns a 200 OK response code and updated plannerTaskDetails object in the response body. In case of errors, see HTTP status codes.</returns>
        public async Task UpdateTaskDetails(string taskId, string eTag, Dictionary <string, Checklist> checklist = null, string description = null, string previewType = null, object references = null)
        {
            // C# 8.0 Preview 2 feature.
            using var cs = this.GetCodeSection();

            if (string.IsNullOrWhiteSpace(taskId) ||
                string.IsNullOrWhiteSpace(eTag))
            {
                cs.Warning(Constants.MESSAGE_WARNING_NULLARGUMENTS);
                return;
            }

            dynamic body = new ExpandoObject();

            if (checklist?.Count > 0)
            {
                var newChecklist = new Dictionary <string, object>();
                foreach (string k in checklist.Keys)
                {
                    var ch = new Dictionary <string, string>
                    {
                        { "@odata.type", "#microsoft.graph.plannerChecklistItem" },
                        { "title", checklist[k].Title },
                        { "isChecked", checklist[k].IsChecked.ToString() }
                    };
                    newChecklist.Add(Guid.NewGuid().ToString(), ch);
                }
                body.checklist = newChecklist;
            }
            body.description = description;
            body.previewType = previewType;
            body.references  = references;
            // TODO: use JsonConverter.
            var bodyContent = JsonConvert.SerializeObject(body);

            try
            {
                HttpResponseMessage httpResponseMessage = null;
                var retry = new RetryWithExponentialBackoff <HttpResponseMessage>();
                await retry.RunAsync(
                    async() =>
                {
                    httpResponseMessage = await HttpClient.SendTeamsAsync(
                        HttpVerb.PATCH,
                        new Uri(O365Settings.MsGraphBetaEndpoint + $"/planner/tasks/{taskId}/details"),
                        eTag,
                        new StringContent(bodyContent, Encoding.UTF8, "application/json"));
                    return(httpResponseMessage);
                });

                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    var ex = new HttpRequestException(Constants.EXCEPTION_HTTPREQUEST + $" Status Code: {httpResponseMessage.StatusCode}.");
                    cs.Exception(ex);
                    throw ex;
                }
            }
            catch (Exception ex)
            {
                cs.Exception(ex);
                throw;
            }
        }