private void InitializeSourceParameters(JobCreationRequest creationRequest) { creationRequest.Branch = GetRequiredEnvironmentVariable("BUILD_SOURCEBRANCH"); creationRequest.Repository = GetRequiredEnvironmentVariable("BUILD_REPOSITORY_NAME"); creationRequest.TeamProject = GetRequiredEnvironmentVariable("SYSTEM_TEAMPROJECT"); creationRequest.SourcePrefix = GetSourcePrefix(); }
/// <summary> /// Returns an IJobQueue specific to the job type sent in the request /// </summary> /// <param name="request">contains JobType</param> /// <returns></returns> private IJobQueue JobCreationFactory(JobCreationRequest request) { //NOTE:Only SCRAPE job has been implemented. Can be changed to a switch for more jobs //This factory can definitetly be enhanced. //IJobQueue implementations can also be modified to have a constructor that accepts a job request, //and be reponsible for their own validation. if (request.Type == JobType.SCRAPE) { if (request.Data != null) { var job = new WebScrapeJob(); Uri uri; var uriCreated = Uri.TryCreate(request.Data["url"], UriKind.Absolute, out uri); if (uriCreated) { job.Url = uri; } else { throw new JobCreationException("Url request parameter invalid."); } job.Selector = request.Data["selector"]; return(job); } else { throw new JobCreationException("Insufficient request parameters."); } } throw new JobCreationException("Type request parameter not supported."); }
public CreateJob(JobCreationDetails details) { Body = new JobCreationRequest(Origin: details.Origin ?? Constants.Origin) { ParentJob = details.ParentJob, AdditionalDetails = details.AdditionalDetails, ExpectedServices = details.ExpectedServices?.ToList(), ExpectedRecordCount = details.ExpectedRecordCount }; }
public async Task <JobCreationResult> NewAsync( JobCreationRequest newJob, CancellationToken cancellationToken = default ) { using (var _res = await NewInternalAsync( newJob, cancellationToken ).ConfigureAwait(false)) { return(_res.Body); } }
public async Task <JobCreationResult> NewAsync( JobCreationRequest body, string idempotencyKey, CancellationToken cancellationToken = default ) { using (var _res = await NewInternalAsync( body, idempotencyKey, cancellationToken ).ConfigureAwait(false)) { return(_res.Body); } }
/// <summary> /// Schedules a job /// POST: api/job/ /// </summary> /// <param name="createJobRequest">Contains request data such as what type of job was requested (ex Web Scrape), /// and other info necessary for the requested job- Ex if type is Webscrape, Url must be provided</param> /// <returns></returns> public async Task <HttpResponseMessage> Post([FromBody] JobCreationRequest createJobRequest) { try { var job = JobCreationFactory(createJobRequest); await jobSchedulerService.ScheduleJobAsync(job); Console.WriteLine(String.Format("Created {0}", job.RequestId)); return(Request.CreateResponse(HttpStatusCode.Created, job.RequestId)); } catch (JobCreationException ex) { return(Request.CreateResponse(HttpStatusCode.BadRequest, new HttpError(ex.Message))); } catch (Exception ex) { return(Request.CreateResponse(HttpStatusCode.InternalServerError, new HttpError(ex.Message))); } }
public void TestPostJob_Failure_InsufficientRequestParameters() { var jobSchedulerService = new Mock <IJobSchedulerService>(); var jobController = new JobController(jobSchedulerService.Object); jobController.Request = new HttpRequestMessage(); jobController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration()); //Job request with missing information var jobData = new JobCreationRequest { Type = JobType.SCRAPE, }; var controllerResponse = jobController.Post(jobData); Assert.AreEqual(HttpStatusCode.BadRequest, controllerResponse.Result.StatusCode); }
public void TestPostJob_Failure_InvalidJobType() { var jobSchedulerService = new Mock <IJobSchedulerService>(); var jobController = new JobController(jobSchedulerService.Object); jobController.Request = new HttpRequestMessage(); jobController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration()); //Job request with other jobtype var jobData = new JobCreationRequest { Type = JobType.OTHERJOBS, Data = new Dictionary <string, string>() { { "url", @"sdsad://dsa2234.com/" }, { "selector", "span" } } }; var controllerResponse = jobController.Post(jobData); Assert.AreEqual(HttpStatusCode.BadRequest, controllerResponse.Result.StatusCode); }
public void TestPostJob_Success() { var jobSchedulerService = new Mock <IJobSchedulerService>(); jobSchedulerService.Setup(jbs => jbs.ScheduleJobAsync(It.IsAny <IJobQueue>())) .Returns(Task.FromResult(TaskStatus.RanToCompletion)); var jobController = new JobController(jobSchedulerService.Object); jobController.Request = new HttpRequestMessage(); jobController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration()); var jobData = new JobCreationRequest { Type = JobType.SCRAPE, Data = new Dictionary <string, string>() { { "url", @"https://google.com/" }, { "selector", "span" } } }; var controllerResponse = jobController.Post(jobData); Assert.AreEqual(HttpStatusCode.Created, controllerResponse.Result.StatusCode); }
/// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='newJob'> /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> public static async Task <JobCreationResult> NewOperationAsync(this IJob operations, JobCreationRequest newJob, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { using (var _result = await operations.NewOperationWithHttpMessagesAsync(newJob, null, cancellationToken).ConfigureAwait(false)) { return(_result.Body); } }
internal async Task <HttpOperationResponse <JobCreationResult> > NewInternalAsync( JobCreationRequest body, string idempotencyKey, CancellationToken cancellationToken = default ) { if (body == default) { throw new ArgumentNullException(nameof(body)); } if (!body.IsValid) { throw new ArgumentException("The parameter is not valid", nameof(body)); } if (string.IsNullOrEmpty(idempotencyKey)) { throw new ArgumentNullException(nameof(idempotencyKey)); } var _path = "/api/2019-06-17/jobs"; var _query = new QueryBuilder(); var _uriBuilder = new UriBuilder(Client.BaseUri); _uriBuilder.Path = _uriBuilder.Path.TrimEnd('/') + _path; _uriBuilder.Query = _query.ToString(); var _url = _uriBuilder.Uri; HttpRequestMessage _req = null; HttpResponseMessage _res = null; try { _req = new HttpRequestMessage(HttpMethod.Post, _url); if (!string.IsNullOrEmpty(idempotencyKey)) { _req.Headers.Add("Idempotency-Key", idempotencyKey); } string _requestContent = null; if (body != default) { _requestContent = Client.Serialize(body); _req.Content = new StringContent(_requestContent, Encoding.UTF8) { Headers = { ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8"), }, }; } if (Client.Credentials != null) { await Client.Credentials.ProcessHttpRequestAsync(_req, cancellationToken).ConfigureAwait(false); } _res = await Client.SendAsync(_req, cancellationToken).ConfigureAwait(false); if (!_res.IsSuccessStatusCode) { await OnNewFailed(_req, _res); } string _responseContent = await _res.Content.ReadAsStringAsync().ConfigureAwait(false); return(new HttpOperationResponse <JobCreationResult> { Request = _req, Response = _res, Body = Client.Deserialize <JobCreationResult>(_responseContent), }); } catch (Exception) { _req?.Dispose(); _res?.Dispose(); throw; } }
internal async Task <HttpOperationResponse <JobCreationResult> > NewInternalAsync( JobCreationRequest newJob, CancellationToken cancellationToken = default ) { if (newJob == default) { throw new ArgumentNullException(nameof(newJob)); } if (!newJob.IsValid) { throw new ArgumentException("The parameter is not valid", nameof(newJob)); } var _path = "/api/2018-03-14/jobs"; var _query = new QueryBuilder(); var _uriBuilder = new UriBuilder(Client.BaseUri); _uriBuilder.Path = _uriBuilder.Path.TrimEnd('/') + _path; _uriBuilder.Query = _query.ToString(); var _url = _uriBuilder.Uri; HttpRequestMessage _req = null; HttpResponseMessage _res = null; try { _req = new HttpRequestMessage(HttpMethod.Post, _url); string _requestContent = null; if (newJob != default) { _requestContent = Client.Serialize(newJob); _req.Content = new StringContent(_requestContent, Encoding.UTF8) { Headers = { ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8"), }, }; } if (Client.Credentials != null) { await Client.Credentials.ProcessHttpRequestAsync(_req, cancellationToken).ConfigureAwait(false); } _res = await Client.SendAsync(_req, cancellationToken).ConfigureAwait(false); string _responseContent; if (!_res.IsSuccessStatusCode) { _responseContent = await _res.Content.ReadAsStringAsync().ConfigureAwait(false); var ex = new RestApiException( new HttpRequestMessageWrapper(_req, _requestContent), new HttpResponseMessageWrapper(_res, _responseContent)); HandleFailedNewRequest(ex); HandleFailedRequest(ex); Client.OnFailedRequest(ex); throw ex; } _responseContent = await _res.Content.ReadAsStringAsync().ConfigureAwait(false); return(new HttpOperationResponse <JobCreationResult> { Request = _req, Response = _res, Body = Client.Deserialize <JobCreationResult>(_responseContent), }); } catch (Exception) { _req?.Dispose(); _res?.Dispose(); throw; } }
/// <param name='newJob'> /// </param> /// <param name='customHeaders'> /// Headers that will be added to request. /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> /// <exception cref="HttpOperationException"> /// Thrown when the operation returned an invalid status code /// </exception> /// <exception cref="SerializationException"> /// Thrown when unable to deserialize the response /// </exception> /// <exception cref="ValidationException"> /// Thrown when a required parameter is null /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown when a required parameter is null /// </exception> /// <return> /// A response object containing the response body and response headers. /// </return> public async Task <HttpOperationResponse <JobCreationResult> > NewOperationWithHttpMessagesAsync(JobCreationRequest newJob, Dictionary <string, List <string> > customHeaders = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { if (newJob == null) { throw new ValidationException(ValidationRules.CannotBeNull, "newJob"); } if (newJob != null) { newJob.Validate(); } // Tracing bool _shouldTrace = ServiceClientTracing.IsEnabled; string _invocationId = null; if (_shouldTrace) { _invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("newJob", newJob); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(_invocationId, this, "NewOperation", tracingParameters); } // Construct URL var _baseUrl = Client.BaseUri.AbsoluteUri; var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/2018-03-14/jobs").ToString(); // Create HTTP transport objects var _httpRequest = new HttpRequestMessage(); HttpResponseMessage _httpResponse = null; _httpRequest.Method = new HttpMethod("POST"); _httpRequest.RequestUri = new System.Uri(_url); // Set Headers if (customHeaders != null) { foreach (var _header in customHeaders) { if (_httpRequest.Headers.Contains(_header.Key)) { _httpRequest.Headers.Remove(_header.Key); } _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); } } // Serialize Request string _requestContent = null; if (newJob != null) { _requestContent = Rest.Serialization.SafeJsonConvert.SerializeObject(newJob, Client.SerializationSettings); _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); _httpRequest.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); } // Set Credentials if (Client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); } // Send Request if (_shouldTrace) { ServiceClientTracing.SendRequest(_invocationId, _httpRequest); } cancellationToken.ThrowIfCancellationRequested(); _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); if (_shouldTrace) { ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); } HttpStatusCode _statusCode = _httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); string _responseContent = null; if ((int)_statusCode != 202) { var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); if (_httpResponse.Content != null) { _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); } else { _responseContent = string.Empty; } ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); if (_shouldTrace) { ServiceClientTracing.Error(_invocationId, ex); } _httpRequest.Dispose(); if (_httpResponse != null) { _httpResponse.Dispose(); } throw ex; } // Create Result var _result = new HttpOperationResponse <JobCreationResult>(); _result.Request = _httpRequest; _result.Response = _httpResponse; // Deserialize Response if ((int)_statusCode == 202) { _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); try { _result.Body = Rest.Serialization.SafeJsonConvert.DeserializeObject <JobCreationResult>(_responseContent, Client.DeserializationSettings); } catch (JsonException ex) { _httpRequest.Dispose(); if (_httpResponse != null) { _httpResponse.Dispose(); } throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); } } if (_shouldTrace) { ServiceClientTracing.Exit(_invocationId, _result); } return(_result); }
/// <summary> /// Creates a new job. By default the `owner` will be the currently authenticated user, and the `job_status` will be `CREATED`. /// </summary> /// <param name="origin">The originating product/application/service for which this job is being created.</param> public CreateJob(string origin) { Body = new JobCreationRequest(origin); }
public async Task TestPostAndGet() { HttpConfiguration config = new HttpConfiguration(); config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }); HttpServer server = new HttpServer(config); using (HttpMessageInvoker client = new HttpMessageInvoker(server)) { var data = new JobCreationRequest { Type = JobType.SCRAPE, Data = new Dictionary <string, string>() { { "url", @"https://www.eaze.com/" }, { "selector", "footer a" } } }; var postRequest = new HttpRequestMessage { RequestUri = new Uri("http://localhost:10820/api/Job"), Method = HttpMethod.Post, Content = new ObjectContent <JobCreationRequest>(data, new System.Net.Http.Formatting.JsonMediaTypeFormatter()) }; postRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Guid requestId; using (HttpResponseMessage postResponse = client.SendAsync(postRequest, CancellationToken.None).Result) { requestId = postResponse.Content.ReadAsAsync <Guid>().Result; Assert.AreEqual(HttpStatusCode.Created, postResponse.StatusCode); } var getRequest = new HttpRequestMessage { RequestUri = new Uri(string.Format("http://localhost:10820/api/Job/{0}", requestId)), Method = HttpMethod.Get, }; getRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //job is still running using (HttpResponseMessage getResponse1 = client.SendAsync(getRequest, CancellationToken.None).Result) { var job = getResponse1.Content.ReadAsAsync <WebScrapeJob>().Result; Assert.AreEqual(JobStatus.RUNNING, job.Status); Assert.AreEqual(HttpStatusCode.OK, getResponse1.StatusCode); } Thread.Sleep(11000); //job has completed using (HttpResponseMessage getResponse2 = await client.SendAsync(getRequest, CancellationToken.None)) { var job = getResponse2.Content.ReadAsAsync <WebScrapeJob>().Result; Assert.AreEqual(JobStatus.COMPLETED, job.Status); Assert.AreEqual(HttpStatusCode.OK, getResponse2.StatusCode); Assert.AreEqual(6, job.Scrapes.Count); Assert.IsTrue(job.Scrapes.Contains("Privacy")); } } }
public async Task <ISentJob> SendAsync(Action <string> log = null) { IBlobHelper storage; if (string.IsNullOrEmpty(StorageAccountConnectionString)) { storage = new ApiBlobHelper(HelixApi.Storage); } else { storage = new ConnectionStringBlobHelper(StorageAccountConnectionString); } var(queueId, dockerTag, queueAlias) = ParseQueueId(TargetQueueId); IBlobContainer storageContainer = await storage.GetContainerAsync(TargetContainerName, queueId); var jobList = new List <JobListEntry>(); Dictionary <string, string> correlationPayloadUris = (await Task.WhenAll(CorrelationPayloads.Select(async p => (uri: await p.Key.UploadAsync(storageContainer, log), destination: p.Value)))).ToDictionary(x => x.uri, x => x.destination); jobList = (await Task.WhenAll( _workItems.Select(async w => { var entry = await w.SendAsync(storageContainer, TargetContainerName, log); entry.CorrelationPayloadUrisWithDestinations = correlationPayloadUris; return(entry); } ))).ToList(); string jobListJson = JsonConvert.SerializeObject(jobList); Uri jobListUri = await storageContainer.UploadTextAsync( jobListJson, $"job-list-{Guid.NewGuid()}.json"); // Don't log the sas, remove the query string. string jobListUriForLogging = jobListUri.ToString().Replace(jobListUri.Query, ""); log?.Invoke($"Created job list at {jobListUriForLogging}"); // Only specify the ResultContainerPrefix if both repository name and source branch are available. if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_REPOSITORY_NAME")) && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_SOURCEBRANCH"))) { // Container names can only be alphanumeric (plus dashes) lowercase names, with no consecutive dashes. // Replace / with -, make all branch and repository names lowercase, remove any characters not // allowed in container names, and replace any string of dashes with a single dash. Regex illegalCharacters = new Regex("[^a-z0-9-]"); Regex multipleDashes = new Regex("-{2,}"); string repoName = Environment.GetEnvironmentVariable("BUILD_REPOSITORY_NAME"); string branchName = Environment.GetEnvironmentVariable("BUILD_SOURCEBRANCH"); // ResultContainerPrefix will be <Repository Name>-<BranchName> ResultContainerPrefix = $"{repoName}-{branchName}-".Replace("/", "-").ToLower(); ResultContainerPrefix = multipleDashes.Replace(illegalCharacters.Replace(ResultContainerPrefix, ""), "-"); } var creationRequest = new JobCreationRequest(Type, _properties.ToImmutableDictionary(), jobListUri.ToString(), queueId) { Creator = Creator, ResultContainerPrefix = ResultContainerPrefix, Branch = GetBranch(), DockerTag = dockerTag, QueueAlias = queueAlias, }; if (string.IsNullOrEmpty(Source)) { InitializeSourceParameters(creationRequest); } else { creationRequest.Source = Source; } string jobStartIdentifier = Guid.NewGuid().ToString("N"); JobCreationResult newJob = await HelixApi.RetryAsync( () => JobApi.NewAsync(creationRequest, jobStartIdentifier), ex => log?.Invoke($"Starting job failed with {ex}\nRetrying..."), IsRetryableJobListUriHttpError, CancellationToken.None); return(new SentJob(JobApi, newJob, newJob.ResultsUri, newJob.ResultsUriRSAS)); }
public async Task <ISentJob> SendAsync(Action <string> log, CancellationToken cancellationToken) { IBlobHelper storage; if (string.IsNullOrEmpty(StorageAccountConnectionString)) { storage = new ApiBlobHelper(HelixApi.Storage); } else { storage = new ConnectionStringBlobHelper(StorageAccountConnectionString); } var(queueId, dockerTag, queueAlias) = ParseQueueId(TargetQueueId); // Save time / resources by checking that the queue isn't missing before doing any potentially expensive storage operations try { QueueInfo queueInfo = await HelixApi.Information.QueueInfoAsync(queueId, false, cancellationToken); } // 404 = this queue does not exist, or did and was removed. catch (RestApiException ex) when(ex.Response?.Status == 404) { throw new ArgumentException($"Helix API does not contain an entry for {queueId}"); } IBlobContainer storageContainer = await storage.GetContainerAsync(TargetContainerName, queueId, cancellationToken); var jobList = new List <JobListEntry>(); Dictionary <string, string> correlationPayloadUris = (await Task.WhenAll(CorrelationPayloads.Select(async p => (uri: await p.Key.UploadAsync(storageContainer, log, cancellationToken), destination: p.Value)))).ToDictionary(x => x.uri, x => x.destination); jobList = (await Task.WhenAll( _workItems.Select(async w => { var entry = await w.SendAsync(storageContainer, TargetContainerName, log, cancellationToken); entry.CorrelationPayloadUrisWithDestinations = correlationPayloadUris; return(entry); } ))).ToList(); string jobListJson = JsonConvert.SerializeObject(jobList, Formatting.Indented); Uri jobListUri = await storageContainer.UploadTextAsync( jobListJson, $"job-list-{Guid.NewGuid()}.json", cancellationToken); // Don't log the sas, remove the query string. string jobListUriForLogging = jobListUri.ToString().Replace(jobListUri.Query, ""); log?.Invoke($"Created job list at {jobListUriForLogging}"); cancellationToken.ThrowIfCancellationRequested(); // Only specify the ResultContainerPrefix if both repository name and source branch are available. if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_REPOSITORY_NAME")) && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_SOURCEBRANCH"))) { // Container names can only be alphanumeric (plus dashes) lowercase names, with no consecutive dashes. // Replace / with -, make all branch and repository names lowercase, remove any characters not // allowed in container names, and replace any string of dashes with a single dash. Regex illegalCharacters = new Regex("[^a-z0-9-]"); Regex multipleDashes = new Regex("-{2,}"); string repoName = Environment.GetEnvironmentVariable("BUILD_REPOSITORY_NAME"); string branchName = Environment.GetEnvironmentVariable("BUILD_SOURCEBRANCH"); // ResultContainerPrefix will be <Repository Name>-<BranchName> ResultContainerPrefix = $"{repoName}-{branchName}-".Replace("/", "-").ToLower(); ResultContainerPrefix = multipleDashes.Replace(illegalCharacters.Replace(ResultContainerPrefix, ""), "-"); } var creationRequest = new JobCreationRequest(Type, jobListUri.ToString(), queueId) { Properties = _properties.ToImmutableDictionary(), Creator = Creator, ResultContainerPrefix = ResultContainerPrefix, DockerTag = dockerTag, QueueAlias = queueAlias, }; if (string.IsNullOrEmpty(Source)) { // We only want to specify a branch if Source wasn't already provided. // Latest Helix Job API will 400 if both Source and any of SourcePrefix, TeamProject, Repository, or Branch are set. InitializeSourceParameters(creationRequest); } else { creationRequest.Source = Source; } string jobStartIdentifier = Guid.NewGuid().ToString("N"); var newJob = await JobApi.NewAsync(creationRequest, jobStartIdentifier, cancellationToken).ConfigureAwait(false); return(new SentJob(JobApi, newJob, newJob.ResultsUri, newJob.ResultsUriRSAS)); }
public async Task <JobCreationResult> NewAsync( JobCreationRequest body, string idempotencyKey, CancellationToken cancellationToken = default ) { if (body == default(JobCreationRequest)) { throw new ArgumentNullException(nameof(body)); } if (!body.IsValid) { throw new ArgumentException("The parameter is not valid", nameof(body)); } if (string.IsNullOrEmpty(idempotencyKey)) { throw new ArgumentNullException(nameof(idempotencyKey)); } var _baseUri = Client.Options.BaseUri; var _url = new RequestUriBuilder(); _url.Reset(_baseUri); _url.AppendPath( "/api/2019-06-17/jobs", false); using (var _req = Client.Pipeline.CreateRequest()) { _req.Uri = _url; _req.Method = RequestMethod.Post; if (!string.IsNullOrEmpty(idempotencyKey)) { _req.Headers.Add("Idempotency-Key", idempotencyKey); } if (body != default(JobCreationRequest)) { _req.Content = RequestContent.Create(Encoding.UTF8.GetBytes(Client.Serialize(body))); _req.Headers.Add("Content-Type", "application/json; charset=utf-8"); } using (var _res = await Client.SendAsync(_req, cancellationToken).ConfigureAwait(false)) { if (_res.Status < 200 || _res.Status >= 300) { await OnNewFailed(_req, _res).ConfigureAwait(false); } if (_res.ContentStream == null) { await OnNewFailed(_req, _res).ConfigureAwait(false); } using (var _reader = new StreamReader(_res.ContentStream)) { var _content = await _reader.ReadToEndAsync().ConfigureAwait(false); var _body = Client.Deserialize <JobCreationResult>(_content); return(_body); } } } }
/// <summary> /// Creates a new job. By default the `owner` will be the currently authenticated user, and the `job_status` will be `CREATED`. /// </summary> public CreateJob() { Body = new JobCreationRequest(Constants.Origin); }