public async Task CheckBuildAsync(Guid productId)
        {
            var product = await ProductRepository.Get()
                          .Where(p => p.Id == productId)
                          .Include(p => p.ProductDefinition)
                          .Include(p => p.Project)
                          .ThenInclude(pr => pr.Organization)
                          .Include(p => p.Project)
                          .ThenInclude(pr => pr.Owner)
                          .FirstOrDefaultAsync();

            if ((product == null) || (product.WorkflowJobId == 0))
            {
                // Can't find the product record associated with
                // this process or there is no job created for this product.
                // Exception will trigger retry
                // Don't send exception because there doesn't seem to be a point in retrying
                var messageParms = new Dictionary <string, object>()
                {
                    { "productId", productId.ToString() }
                };
                await SendNotificationSvc.SendNotificationToSuperAdminsAsync("buildProductRecordNotFound",
                                                                             messageParms);

                ClearRecurringJob(productId);
                return;
            }
            // Since this is a recurring task, there is no need to throw an exception
            // if the link is unavailable.  It will retry
            if (BuildEngineLinkAvailable(product.Project.Organization))
            {
                await CheckExistingBuildAsync(product);
            }
            return;
        }
        public async Task CreateBuildAsync(Guid productId, Dictionary <string, object> parmsDictionary, PerformContext context)
        {
            var product = await ProductRepository.Get()
                          .Where(p => p.Id == productId)
                          .Include(p => p.ProductDefinition)
                          .Include(p => p.Project)
                          .ThenInclude(pr => pr.Organization)
                          .Include(p => p.Project)
                          .ThenInclude(pr => pr.Owner)
                          .FirstOrDefaultAsync();

            if ((product == null) || (product.WorkflowJobId == 0))
            {
                // Can't find the product record associated with
                // this process or there is no job created for this product.
                // Exception will trigger retry
                // Don't send exception because there doesn't seem to be a point in retrying
                var messageParms = new Dictionary <string, object>
                {
                    { "productId", productId.ToString() }
                };
                await SendNotificationSvc.SendNotificationToSuperAdminsAsync("buildProductRecordNotFound",
                                                                             messageParms);

                return;
            }
            if (!BuildEngineLinkAvailable(product.Project.Organization))
            {
                // If the build engine isn't available, there is no point in continuing
                var messageParms = new Dictionary <string, object>()
                {
                    { "projectName", product.Project.Name },
                    { "productName", product.ProductDefinition.Name }
                };
                await SendNotificationOnFinalRetryAsync(context, product.Project.Organization, product.Project.Owner, "buildFailedUnableToConnect", messageParms);

                // Throw exception to retry
                throw new Exception("Connection not available");
            }

            // Clear current BuildId used by Workflow
            product.WorkflowBuildId = 0;
            await ProductRepository.UpdateAsync(product);

            await CreateBuildEngineBuildAsync(product, parmsDictionary, context);
        }