コード例 #1
0
ファイル: BulkOperations.cs プロジェクト: onka13/clarizen
 /// <summary>
 /// Starts the bulk service. After this point every operation on API is put in a bulk buffer and not sent to Clarizen until CheckCommit or Close functions are executed.
 /// </summary>
 /// <param name="isTransactional"></param>
 /// <param name="batch"></param>
 public void Start(bool isTransactional = false, bool batch = false, bool includeRequestsInResponse = false, int timeout = 120000)
 {
     _isBulkTransactional = isTransactional;
     _batch = batch;
     _includeRequestsInResponse = includeRequestsInResponse;
     _timeout         = timeout;
     APIBulkCallCount = 0;
     ClarizenAPI.StartBulkService();
 }
コード例 #2
0
        /// <summary>
        /// Sends any items in the bulk buffer to the API and then closes the bulk service. Results are returned as objects of type T.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="hasErrors">Identifies if the API returned any errors</param>
        /// <param name="enableTimeAudit">Log how long each operation takes</param>
        /// <param name="sleepTime">Seconds to wait between each API call</param>
        /// <returns></returns>
        public async Task <Tuple <List <T>, bool> > Close <T>(bool enableTimeAudit = false, int sleepTime = 0)
        {
            Tuple <List <T>, bool> result = null;

            if (APIBulkCallCount > 0)
            {
                result = await Commit <T>(enableTimeAudit, sleepTime);
            }
            ClarizenAPI.CancelBulkService();
            return(result);
        }
コード例 #3
0
        /// <summary>
        /// Sends any items in the bulk buffer to the API and then closes the bulk service.
        /// </summary>
        /// <param name="enableTimeAudit">Log how long each operation takes</param>
        /// <param name="sleepTime">Seconds to wait between each API call</param>
        /// <returns></returns>
        public async Task <bool> Close(bool enableTimeAudit = false, int sleepTime = 0)
        {
            bool result = true;

            if (APIBulkCallCount > 0)
            {
                result = await Commit(enableTimeAudit, sleepTime);
            }
            ClarizenAPI.CancelBulkService();
            return(result);
        }
コード例 #4
0
        /// <summary>
        /// Get multiple objects of type T by running a query (IClarizenQuery)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query">Clarizen Query Language (CZQL) query</param>
        /// <param name="pageSize">Default size to be used for pagination</param>
        /// <returns></returns>
        public async Task <List <T> > GetAll <T>(Ekin.Clarizen.Interfaces.IClarizenQuery query, int?pageSize = null, int?sleepTime = null)
        {
            GetAllResult result = await ClarizenAPI.GetAll(query, typeof(T), pageSize, sleepTime);

            if (result == null || result.Errors.Any())
            {
                var detailedMsg = "Error: " + string.Join(System.Environment.NewLine, result.Errors.Select(i => i.Message));
                Logs.AddError("Ekin.Clarizen.BulkOperations", "Get All (Query)", detailedMsg);
                return(null);
            }
            return((List <T>)result.Data);
        }
コード例 #5
0
 /// <summary>
 /// Starts the bulk service. After this point every operation on API is put in a bulk buffer and not sent to Clarizen until CheckCommit or Close functions are executed.
 /// </summary>
 /// <param name="isTransactional"></param>
 /// <param name="batch"></param>
 public void Start(bool isTransactional = false, bool batch = false, bool includeRequestsInResponse = false, int?timeout = null)
 {
     _isBulkTransactional = isTransactional;
     _batch = batch;
     _includeRequestsInResponse = includeRequestsInResponse;
     if (timeout != null)
     {
         _timeout = timeout.Value;
     }
     APIBulkCallCount = 0;
     ClarizenAPI.StartBulkService();
 }
コード例 #6
0
        /// <summary>
        /// Get multiple objects of type T by providing an EntityName
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityName">Name of the Clarizen entity, e.g. Timesheet, WorkItem, etc.</param>
        /// <param name="customCondition"></param>
        /// <returns></returns>
        public async Task <List <T> > GetAll <T>(string entityName, string customCondition = "", int sleepTime = 0)
        {
            customCondition = customCondition?.Trim();
            CZQLCondition condition = null;

            if (!string.IsNullOrEmpty(customCondition))
            {
                condition = new CZQLCondition(customCondition);
            }
            GetAllResult result = await ClarizenAPI.GetAll(entityName, typeof(T), condition, sleepTime);

            if (result == null || result.Errors.Any())
            {
                var detailedMsg = "Error: " + string.Join(System.Environment.NewLine, result.Errors.Select(i => i.Message));
                Logs.AddError("Ekin.Clarizen.BulkOperations", "Get All " + entityName, detailedMsg);
                return(null);
            }
            return((List <T>)result.Data);
        }
コード例 #7
0
        internal async Task <bool> Commit(bool enableTimeAudit = false, int sleepTime = 0)
        {
            bool     result    = true;
            DateTime startTime = DateTime.Now;

            Ekin.Clarizen.Bulk.Execute bulkService = await ClarizenAPI.CommitBulkService(_isBulkTransactional, _batch, _includeRequestsInResponse, _timeout);

            if (bulkService.IsCalledSuccessfully)
            {
                foreach (Response res in bulkService.Data.Responses)
                {
                    if (res.StatusCode != 200)
                    {
                        Logs.AddError("Ekin.Clarizen.BulkOperations", "CommitBulkService", "Bulk item failed. Error: " + ((Error)res.Body).Formatted, _includeRequestsInResponse ? res.Request : null);
                        result = false;
                    }
                }
            }
            else
            {
                Logs.AddError("Ekin.Clarizen.BulkOperations", "CommitBulkService", "Bulk service failed. Error: " + bulkService.Error);
                result = false;
            }

            DateTime endTime = DateTime.Now;

            if (enableTimeAudit)
            {
                Logs.AddAudit("Ekin.Clarizen.BulkOperations", "CommitBulkService", string.Format("Bulk API call completed in {0:0.00}s", (endTime - startTime).TotalSeconds));
            }
            if (sleepTime > 0)
            {
                await Task.Delay(sleepTime * 1000);
            }
            return(result);
        }
コード例 #8
0
        /// <summary>
        /// Uploads a file and links it to an entity
        /// </summary>
        /// <param name="InputData">Either a string or a byte[] to upload</param>
        /// <param name="DocumentName">Name of the document entity in Clarizen</param>
        /// <param name="FileType">File Type in Clarizen, e.g. /FileType/PDF</param>
        /// <param name="DocumentType">Document Type in Clarizen, e.g. /DocumentType/YourCustomType (Optional)</param>
        /// <param name="LinkedEntity">An entity in Clarizen to link the uploaded file to (Optional)</param>
        /// <returns></returns>
        public async Task <bool> Upload(object InputData, string DocumentName, string FileName, EntityId FileType, EntityId DocumentType = null, EntityId LinkedEntity = null)
        {
            Logs = new Ekin.Log.LogFactory();

            #region Validate input

            if (InputData == null)
            {
                Logs.AddError("Ekin.Clarizen.FileUploadHelper", "Upload", "InputData cannot be null");
                return(false);
            }

            if (!(InputData is string || InputData is byte[]))
            {
                Logs.AddError("Ekin.Clarizen.FileUploadHelper", "Upload", "InputData should be a string or a byte array");
                return(false);
            }

            #endregion Validate input

            #region Create a Document entity

            Document document = new Document
            {
                Id           = "/Document",
                Name         = DocumentName,
                FileType     = FileType,
                DocumentType = DocumentType
            };

            Ekin.Clarizen.Data.Objects_put clarizenDocument = await ClarizenAPI.CreateObject(document.Id, document);

            if (!clarizenDocument.IsCalledSuccessfully || clarizenDocument.Data == null || string.IsNullOrWhiteSpace(clarizenDocument.Data.Id))
            {
                Logs.AddError("Ekin.Clarizen.FileUploadHelper", "Upload", "Blank document couldn't be created in Clarizen. Error: " + clarizenDocument.Error);
                return(false);
            }
            else
            {
                document.Id = clarizenDocument.Data.Id;
            }

            #endregion Create a Document entity

            #region Get Upload URL from Clarizen

            Ekin.Clarizen.Files.GetUploadUrl uploadUrlCall = await ClarizenAPI.GetUploadUrl();

            if (!uploadUrlCall.IsCalledSuccessfully || uploadUrlCall.Data == null || string.IsNullOrWhiteSpace(uploadUrlCall.Data.UploadUrl))
            {
                Logs.AddError("Ekin.Clarizen.FileUploadHelper", "Upload", "Document upload url couldn't be retrieved from Clarizen. Error: " + uploadUrlCall.Error);
                return(false);
            }

            string uploadUrl = uploadUrlCall.Data.UploadUrl;

            #endregion Get Upload URL from Clarizen

            #region Send the file to the Upload URL

            using (var client = new HttpClient())
            {
                using (var formData = new MultipartFormDataContent())
                {
                    if (InputData is string)
                    {
                        formData.Add(new StringContent((string)InputData), "file", FileName);
                    }
                    else if (InputData is byte[])
                    {
                        formData.Add(new ByteArrayContent((byte[])InputData), "file", FileName);
                    }
                    HttpResponseMessage response = await client.PostAsync(uploadUrl, formData).ConfigureAwait(false);

                    if (!response.IsSuccessStatusCode)
                    {
                        using (HttpContent content = response.Content)
                        {
                            string data = await content.ReadAsStringAsync().ConfigureAwait(false);

                            Logs.AddError("Ekin.Clarizen.FileUploadHelper", "Upload", "Document couldn't be uploaded. Error: " + data);
                        }
                        return(false);
                    }
                    System.IO.Stream resultStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
                }
            }

            #endregion Send the file to the Upload URL

            #region Complete the Upload

            var          subType         = "";
            var          extendedInfo    = "";
            var          fileInformation = new FileInformation(StorageType.Server, document.Id, FileName, subType, extendedInfo);
            var          uploadRequest   = new Ekin.Clarizen.Files.Request.Upload(document.Id, fileInformation, uploadUrl);
            CallSettings callSettings    = CallSettings.GetFromAPI(ClarizenAPI);
            callSettings.IsBulk = false;
            var  uploadCall   = new Ekin.Clarizen.Files.Upload(uploadRequest, callSettings);
            bool uploadResult = await uploadCall.Execute();

            if (!uploadResult)
            {
                Logs.AddError("Ekin.Clarizen.FileUploadHelper", "Upload", "Document couldn't be uploaded to Clarizen. Error: " + uploadCall.Error);
                return(false);
            }

            #endregion Complete the Upload

            #region If a LinkedEntity object is provided link the file to it

            if (LinkedEntity != null)
            {
                AttachmentLink attachmentLink = new AttachmentLink
                {
                    Id       = "/AttachmentLink",
                    Entity   = LinkedEntity,
                    Document = new EntityId(document.Id)
                };

                Ekin.Clarizen.Data.Objects_put clarizenDocumentLink = await ClarizenAPI.CreateObject(attachmentLink.Id, attachmentLink);

                if (!clarizenDocumentLink.IsCalledSuccessfully || clarizenDocumentLink.Data == null || clarizenDocumentLink.Data.Id == null)
                {
                    Logs.AddError("Ekin.Clarizen.FileUploadHelper", "Upload", "Document successfully created in Clarizen but it could not be linked to the System Admin user. Error: " + clarizenDocumentLink.Error);
                    return(false);
                }
            }

            #endregion If a LinkedEntity object is provided link the file to it

            return(true);
        }
コード例 #9
0
        internal async Task <Tuple <List <T>, bool> > Commit <T>(bool enableTimeAudit = false, int sleepTime = 0)
        {
            List <T> result    = new List <T> {
            };
            DateTime startTime = DateTime.Now;
            bool     hasErrors = false;

            Ekin.Clarizen.Bulk.Execute bulkService = await ClarizenAPI.CommitBulkService(_isBulkTransactional, _batch, _includeRequestsInResponse, _timeout);

            if (bulkService.IsCalledSuccessfully)
            {
                foreach (Response res in bulkService.Data.Responses)
                {
                    if (res.StatusCode != 200)
                    {
                        Logs.AddError("Ekin.Clarizen.BulkOperations", "CommitBulkServiceAndGetData", "Bulk item failed. Error: " + ((Error)res.Body).Formatted, _includeRequestsInResponse ? res.Request : null);
                        hasErrors = true;
                    }
                    else
                    {
                        try
                        {
                            if (res.Body is T)
                            {
                                result.Add((T)res.Body);
                            }
                            else
                            {
                                result.Add(default(T));
                            }
                        }
                        catch (Exception ex)
                        {
                            Logs.AddError("Ekin.Clarizen.BulkOperations", "CommitBulkServiceAndGetData", string.Format("Item returned from Clarizen API could not be parsed to type {0}. Error: {1}", typeof(T), ex.Message));
                            hasErrors = true;
                        }
                    }
                }
            }
            else
            {
                Logs.AddError("Ekin.Clarizen.BulkOperations", "CommitBulkServiceAndGetData", "Bulk service failed. Error: " + bulkService.Error);
                hasErrors = true;
            }

            DateTime endTime = DateTime.Now;

            if (enableTimeAudit)
            {
                Logs.AddAudit("Ekin.Clarizen.BulkOperations", "CommitBulkServiceAndGetData", string.Format("Bulk API call completed in {0:0.00}s", (endTime - startTime).TotalSeconds));
            }

            if (sleepTime > 0)
            {
                await Task.Delay(sleepTime * 1000);
            }

            if (hasErrors)
            {
                return(new Tuple <List <T>, bool>(null, true));
            }
            else
            {
                return(new Tuple <List <T>, bool>(result, false));
            }
        }
コード例 #10
0
        /// <summary>
        /// Run multiple queries in bulk. This method returns the results recursively so if any of the queries result in pagination more bulk queries are executed until all data is retrieved.
        /// </summary>
        /// <param name="Queries">List of Clarizen Query Language (CZQL) queries</param>
        /// <param name="bulkSize">Number of items to send in a bulk call</param>
        /// <returns></returns>
        public async Task <List <Ekin.Clarizen.Data.Result.Query> > BulkQuery(List <Ekin.Clarizen.Data.Request.Query> Queries, int bulkSize = 100)
        {
            if (Queries?.Count == 0)
            {
                return(null);
            }
            int        totalQueryCount         = 0;
            List <int> itemsThatNeedPagination = new List <int> {
            };

            List <Ekin.Clarizen.Data.Result.Query> results = new List <Ekin.Clarizen.Data.Result.Query> {
            };
            bool bulkHasErrors = false;

            Start(false, false);
            for (int QueryCount = 0; QueryCount < Queries.Count; QueryCount++)
            {
                Ekin.Clarizen.Data.Request.Query query = Queries[QueryCount];
                if (string.IsNullOrWhiteSpace(query.Q))
                {
                    continue;
                }
                await ClarizenAPI.ExecuteQuery(query);

                Tuple <List <Ekin.Clarizen.Data.Result.Query>, bool> bulkResult = await CheckCommit <Ekin.Clarizen.Data.Result.Query>(true, 0, bulkSize);

                bulkHasErrors = bulkResult.Item2;
                if (!bulkHasErrors)
                {
                    if (bulkResult != null)
                    {
                        totalQueryCount += QueryCount + 1;
                        results.AddRange(bulkResult.Item1);
                        foreach (Ekin.Clarizen.Data.Result.Query queryResult in bulkResult.Item1)
                        {
                            if (queryResult.Paging.HasMore)
                            {
                                query.Paging = queryResult.Paging;
                                itemsThatNeedPagination.Add(QueryCount);
                            }
                            else
                            {
                                query.Q = null;
                            }
                        }
                    }
                }
                else
                {
                    break;
                }
            }

            if (!bulkHasErrors)
            {
                Tuple <List <Ekin.Clarizen.Data.Result.Query>, bool> bulkResult = await Close <Ekin.Clarizen.Data.Result.Query>(true, 0);

                bulkHasErrors = bulkResult.Item2;
                if (!bulkHasErrors)
                {
                    if (bulkResult != null)
                    {
                        results.AddRange(bulkResult.Item1);
                        for (int QueryCount = 0; QueryCount < bulkResult.Item1.Count; QueryCount++)
                        {
                            Ekin.Clarizen.Data.Result.Query queryResult = bulkResult.Item1[QueryCount];
                            if (queryResult.Paging.HasMore)
                            {
                                Queries[totalQueryCount + QueryCount].Paging = queryResult.Paging;
                                itemsThatNeedPagination.Add(totalQueryCount + QueryCount);
                            }
                            else
                            {
                                Queries[totalQueryCount + QueryCount].Q = null;
                            }
                        }
                    }
                }
            }

            if (bulkHasErrors)
            {
                return(null);
            }

            if (itemsThatNeedPagination.Count > 0)
            {
                List <Ekin.Clarizen.Data.Result.Query> subResults = await BulkQuery(Queries, bulkSize);

                if (subResults == null)
                {
                    return(null);
                }
                for (int QueryCount = 0; QueryCount < subResults.Count; QueryCount++)
                {
                    int resultIndex = itemsThatNeedPagination[QueryCount];
                    if (subResults[QueryCount].Entities != null)
                    {
                        List <dynamic> mergeItems = new List <dynamic>(results[resultIndex].Entities);
                        mergeItems.AddRange(subResults[QueryCount].Entities);
                        results[resultIndex].Entities = mergeItems.ToArray();
                    }
                }
            }

            return(results);
        }