From 63098910f409610f3d447f8b9b2617bc025cf077 Mon Sep 17 00:00:00 2001 From: Henrik Gedionsen Date: Thu, 28 Feb 2019 08:47:30 +0100 Subject: [PATCH 1/9] Avoid doing string concat when not needed --- .../Document/Multiple/Bulk/BulkRequestJsonConverter.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs b/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs index ac65bb699d5..85ca2ba3c67 100644 --- a/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs +++ b/src/Nest/Document/Multiple/Bulk/BulkRequestJsonConverter.cs @@ -29,7 +29,11 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s op.Routing = op.GetRoutingForOperation(settings.Inferrer); var opJson = requestResponseSerializer.SerializeToString(op, SerializationFormatting.None); - writer.WriteRaw($"{{\"{op.Operation}\":" + opJson + "}\n"); + writer.WriteRaw("{\""); + writer.WriteRaw(op.Operation); + writer.WriteRaw("\":"); + writer.WriteRaw(opJson); + writer.WriteRaw("}\n"); var body = op.GetBody(); if (body == null) continue; @@ -40,7 +44,8 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s ) .SerializeToString(body, SerializationFormatting.None); - writer.WriteRaw(bodyJson + "\n"); + writer.WriteRaw(bodyJson); + writer.WriteRaw("\n"); } } From 4aa8ad121cd4830afe98f1dbcdcc3790fd2e291d Mon Sep 17 00:00:00 2001 From: Stuart Cam Date: Tue, 5 Mar 2019 16:06:55 +1100 Subject: [PATCH 2/9] Implement Delete Forecast API + integration tests --- .../ApiGenerator/ApiGenerator.cs | 1 - .../ApiGenerator/Domain/ApiUrlPart.cs | 1 + .../xpack.ml.delete_forecast.patch.json | 16 +++++ .../RequestParameters.Generated.cs | 9 +++ .../ElasticLowLevelClient.Generated.cs | 12 ++++ .../IElasticLowLevelClient.Generated.cs | 10 +++ .../CommonAbstractions/Request/RouteValues.cs | 1 + .../DeleteForecast/DeleteForecastRequest.cs | 9 +++ .../DeleteForecast/DeleteForecastResponse.cs | 6 ++ .../ElasticClient-DeleteForecast.cs | 56 ++++++++++++++++ src/Nest/_Generated/_Descriptors.generated.cs | 18 ++++++ .../_Generated/_LowLevelDispatch.generated.cs | 22 +++++++ src/Nest/_Generated/_Requests.generated.cs | 48 ++++++++++---- .../DeleteForecast/DeleteForecastApiTests.cs | 64 +++++++++++++++++++ .../DeleteForecast/DeleteForecastUrlTests.cs | 20 ++++++ .../GetOverallBucketsApiTests.cs | 21 +----- .../MachineLearningIntegrationTestBase.cs | 63 ++++++++++++++++++ 17 files changed, 344 insertions(+), 33 deletions(-) create mode 100644 src/CodeGeneration/ApiGenerator/RestSpecification/XPack/MachineLearning/xpack.ml.delete_forecast.patch.json create mode 100644 src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastRequest.cs create mode 100644 src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastResponse.cs create mode 100644 src/Nest/XPack/MachineLearning/DeleteForecast/ElasticClient-DeleteForecast.cs create mode 100644 src/Tests/Tests/XPack/MachineLearning/DeleteForecast/DeleteForecastApiTests.cs create mode 100644 src/Tests/Tests/XPack/MachineLearning/DeleteForecast/DeleteForecastUrlTests.cs diff --git a/src/CodeGeneration/ApiGenerator/ApiGenerator.cs b/src/CodeGeneration/ApiGenerator/ApiGenerator.cs index 405b0c1ee08..f3881460d1a 100644 --- a/src/CodeGeneration/ApiGenerator/ApiGenerator.cs +++ b/src/CodeGeneration/ApiGenerator/ApiGenerator.cs @@ -37,7 +37,6 @@ public class ApiGenerator "xpack.ml.put_calendar.json", "xpack.ml.put_calendar_job.json", "xpack.ml.get_calendar_job.json", - "xpack.ml.delete_forecast.json", "xpack.ml.find_file_structure.json", "delete_by_query_rethrottle.json", "update_by_query_rethrottle.json", diff --git a/src/CodeGeneration/ApiGenerator/Domain/ApiUrlPart.cs b/src/CodeGeneration/ApiGenerator/Domain/ApiUrlPart.cs index dcdfd1bfbce..396a2cdf910 100644 --- a/src/CodeGeneration/ApiGenerator/Domain/ApiUrlPart.cs +++ b/src/CodeGeneration/ApiGenerator/Domain/ApiUrlPart.cs @@ -46,6 +46,7 @@ public string ClrTypeName case "datafeed_id": case "snapshot_id": case "filter_id": + case "forecast_id": case "id": return Type == "string" ? "Id" : "Ids"; case "category_id": return "CategoryId"; case "nodes": diff --git a/src/CodeGeneration/ApiGenerator/RestSpecification/XPack/MachineLearning/xpack.ml.delete_forecast.patch.json b/src/CodeGeneration/ApiGenerator/RestSpecification/XPack/MachineLearning/xpack.ml.delete_forecast.patch.json new file mode 100644 index 00000000000..3e7aacf7855 --- /dev/null +++ b/src/CodeGeneration/ApiGenerator/RestSpecification/XPack/MachineLearning/xpack.ml.delete_forecast.patch.json @@ -0,0 +1,16 @@ +{ + "xpack.ml.delete_forecast": { + "url": { + "path": "/_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id}", + "paths": [ + "/_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id}" + ], + "parts": { + "forecast_id": { + "required": true, + "description": "The ID of the forecast to delete, can be comma delimited list or `_all`" + } + } + } + } +} diff --git a/src/Elasticsearch.Net/Domain/RequestParameters/RequestParameters.Generated.cs b/src/Elasticsearch.Net/Domain/RequestParameters/RequestParameters.Generated.cs index e032c8e5e69..7405db51f51 100644 --- a/src/Elasticsearch.Net/Domain/RequestParameters/RequestParameters.Generated.cs +++ b/src/Elasticsearch.Net/Domain/RequestParameters/RequestParameters.Generated.cs @@ -2323,6 +2323,15 @@ public partial class DeleteExpiredDataRequestParameters : RequestParameters HttpMethod.DELETE; } + ///Request options for XpackMlDeleteForecast
http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html
+ public partial class DeleteForecastRequestParameters : RequestParameters + { + public override HttpMethod DefaultHttpMethod => HttpMethod.DELETE; + ///Whether to ignore if `_all` matches no forecasts + public bool? AllowNoForecasts { get => Q("allow_no_forecasts"); set => Q("allow_no_forecasts", value); } + ///Controls the time to wait until the forecast(s) are deleted. Default to 30 seconds + public TimeSpan Timeout { get => Q("timeout"); set => Q("timeout", value); } + } ///Request options for XpackMlDeleteJob
http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html
public partial class DeleteJobRequestParameters : RequestParameters { diff --git a/src/Elasticsearch.Net/ElasticLowLevelClient.Generated.cs b/src/Elasticsearch.Net/ElasticLowLevelClient.Generated.cs index 39279aeed86..21edff720ca 100644 --- a/src/Elasticsearch.Net/ElasticLowLevelClient.Generated.cs +++ b/src/Elasticsearch.Net/ElasticLowLevelClient.Generated.cs @@ -3182,6 +3182,18 @@ public TResponse XpackMlDeleteExpiredData(DeleteExpiredDataRequestPar ///A func that allows you to describe the querystring parameters & request specific connection settings. public Task XpackMlDeleteExpiredDataAsync(DeleteExpiredDataRequestParameters requestParameters = null, CancellationToken ctx = default(CancellationToken)) where TResponse : class, IElasticsearchResponse, new() => this.DoRequestAsync(DELETE, Url($"_xpack/ml/_delete_expired_data"), ctx, null, _params(requestParameters)); + ///DELETE on /_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id} http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html + ///The ID of the job from which to delete forecasts + ///The ID of the forecast to delete, can be comma delimited list or `_all` + ///A func that allows you to describe the querystring parameters & request specific connection settings. + public TResponse XpackMlDeleteForecast(string job_id, string forecast_id, DeleteForecastRequestParameters requestParameters = null) + where TResponse : class, IElasticsearchResponse, new() => this.DoRequest(DELETE, Url($"_xpack/ml/anomaly_detectors/{job_id.NotNull("job_id")}/_forecast/{forecast_id.NotNull("forecast_id")}"), null, _params(requestParameters)); + ///DELETE on /_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id} http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html + ///The ID of the job from which to delete forecasts + ///The ID of the forecast to delete, can be comma delimited list or `_all` + ///A func that allows you to describe the querystring parameters & request specific connection settings. + public Task XpackMlDeleteForecastAsync(string job_id, string forecast_id, DeleteForecastRequestParameters requestParameters = null, CancellationToken ctx = default(CancellationToken)) + where TResponse : class, IElasticsearchResponse, new() => this.DoRequestAsync(DELETE, Url($"_xpack/ml/anomaly_detectors/{job_id.NotNull("job_id")}/_forecast/{forecast_id.NotNull("forecast_id")}"), ctx, null, _params(requestParameters)); ///DELETE on /_xpack/ml/anomaly_detectors/{job_id} http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html ///The ID of the job to delete ///A func that allows you to describe the querystring parameters & request specific connection settings. diff --git a/src/Elasticsearch.Net/IElasticLowLevelClient.Generated.cs b/src/Elasticsearch.Net/IElasticLowLevelClient.Generated.cs index 53e7391e819..c2ab49a3ff5 100644 --- a/src/Elasticsearch.Net/IElasticLowLevelClient.Generated.cs +++ b/src/Elasticsearch.Net/IElasticLowLevelClient.Generated.cs @@ -2576,6 +2576,16 @@ public partial interface IElasticLowLevelClient ///DELETE on /_xpack/ml/_delete_expired_data ///A func that allows you to describe the querystring parameters & request specific connection settings. Task XpackMlDeleteExpiredDataAsync(DeleteExpiredDataRequestParameters requestParameters = null, CancellationToken ctx = default(CancellationToken)) where TResponse : class, IElasticsearchResponse, new(); + ///DELETE on /_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id} http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html + ///The ID of the job from which to delete forecasts + ///The ID of the forecast to delete, can be comma delimited list or `_all` + ///A func that allows you to describe the querystring parameters & request specific connection settings. + TResponse XpackMlDeleteForecast(string job_id, string forecast_id, DeleteForecastRequestParameters requestParameters = null) where TResponse : class, IElasticsearchResponse, new(); + ///DELETE on /_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id} http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html + ///The ID of the job from which to delete forecasts + ///The ID of the forecast to delete, can be comma delimited list or `_all` + ///A func that allows you to describe the querystring parameters & request specific connection settings. + Task XpackMlDeleteForecastAsync(string job_id, string forecast_id, DeleteForecastRequestParameters requestParameters = null, CancellationToken ctx = default(CancellationToken)) where TResponse : class, IElasticsearchResponse, new(); ///DELETE on /_xpack/ml/anomaly_detectors/{job_id} http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html ///The ID of the job to delete ///A func that allows you to describe the querystring parameters & request specific connection settings. diff --git a/src/Nest/CommonAbstractions/Request/RouteValues.cs b/src/Nest/CommonAbstractions/Request/RouteValues.cs index 93821e94cbd..7bc51394724 100644 --- a/src/Nest/CommonAbstractions/Request/RouteValues.cs +++ b/src/Nest/CommonAbstractions/Request/RouteValues.cs @@ -10,6 +10,7 @@ public class RouteValues public string ActionId => GetResolved("action_id"); public string Alias => GetResolved("alias"); public string CategoryId => GetResolved("category_id"); + public string ForecastId => GetResolved("forecast_id"); public string Context => GetResolved("context"); public string DatafeedId => GetResolved("datafeed_id"); public string Feature => GetResolved("feature"); diff --git a/src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastRequest.cs b/src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastRequest.cs new file mode 100644 index 00000000000..4132bd32479 --- /dev/null +++ b/src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastRequest.cs @@ -0,0 +1,9 @@ +namespace Nest +{ + public partial interface IDeleteForecastRequest { } + + public partial class DeleteForecastRequest { } + + [DescriptorFor("XpackMlDeleteForecast")] + public partial class DeleteForecastDescriptor { } +} diff --git a/src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastResponse.cs b/src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastResponse.cs new file mode 100644 index 00000000000..ac88ede6ee6 --- /dev/null +++ b/src/Nest/XPack/MachineLearning/DeleteForecast/DeleteForecastResponse.cs @@ -0,0 +1,6 @@ +namespace Nest +{ + public interface IDeleteForecastResponse : IAcknowledgedResponse { } + + public class DeleteForecastResponse : AcknowledgedResponseBase, IDeleteForecastResponse { } +} diff --git a/src/Nest/XPack/MachineLearning/DeleteForecast/ElasticClient-DeleteForecast.cs b/src/Nest/XPack/MachineLearning/DeleteForecast/ElasticClient-DeleteForecast.cs new file mode 100644 index 00000000000..626372db9c6 --- /dev/null +++ b/src/Nest/XPack/MachineLearning/DeleteForecast/ElasticClient-DeleteForecast.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Elasticsearch.Net; + +namespace Nest +{ + public partial interface IElasticClient + { + /// + /// Deletes forecasts from a machine learning job. + /// + IDeleteForecastResponse DeleteForecast(Id jobId, Id forecastId, Func selector = null); + + /// + IDeleteForecastResponse DeleteForecast(IDeleteForecastRequest request); + + /// + Task DeleteForecastAsync(Id jobId, Id forecastId, Func selector = null, + CancellationToken cancellationToken = default(CancellationToken) + ); + + /// + Task DeleteForecastAsync(IDeleteForecastRequest request, + CancellationToken cancellationToken = default(CancellationToken) + ); + } + + public partial class ElasticClient + { + /// + public IDeleteForecastResponse DeleteForecast(Id jobId, Id forecastId, Func selector = null) => + DeleteForecast(selector.InvokeOrDefault(new DeleteForecastDescriptor(jobId, forecastId))); + + /// + public IDeleteForecastResponse DeleteForecast(IDeleteForecastRequest request) => + Dispatcher.Dispatch( + request, + (p, d) => LowLevelDispatch.XpackMlDeleteForecastDispatch(p) + ); + + /// + public Task DeleteForecastAsync(Id jobId, Id forecastId, + Func selector = null, CancellationToken cancellationToken = default(CancellationToken)) => + DeleteForecastAsync(selector.InvokeOrDefault(new DeleteForecastDescriptor(jobId, forecastId)), cancellationToken); + + /// + public Task DeleteForecastAsync(IDeleteForecastRequest request, + CancellationToken cancellationToken = default(CancellationToken)) => + Dispatcher.DispatchAsync( + request, + cancellationToken, + (p, d, c) => LowLevelDispatch.XpackMlDeleteForecastDispatchAsync(p, c) + ); + } +} diff --git a/src/Nest/_Generated/_Descriptors.generated.cs b/src/Nest/_Generated/_Descriptors.generated.cs index f82cea82ac4..cfee60ed6de 100644 --- a/src/Nest/_Generated/_Descriptors.generated.cs +++ b/src/Nest/_Generated/_Descriptors.generated.cs @@ -4136,6 +4136,24 @@ public partial class DeleteExpiredDataDescriptor : RequestDescriptorBasedescriptor for XpackMlDeleteForecast
http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html
+ public partial class DeleteForecastDescriptor : RequestDescriptorBase, IDeleteForecastRequest + { + /// /_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id} + /// this parameter is required + /// this parameter is required + public DeleteForecastDescriptor(Id job_id, Id forecast_id) : base(r=>r.Required("job_id", job_id).Required("forecast_id", forecast_id)){} + // values part of the url path + Id IDeleteForecastRequest.JobId => Self.RouteValues.Get("job_id"); + Id IDeleteForecastRequest.ForecastId => Self.RouteValues.Get("forecast_id"); + + // Request parameters + + ///Whether to ignore if `_all` matches no forecasts + public DeleteForecastDescriptor AllowNoForecasts(bool? allowNoForecasts = true) => Qs("allow_no_forecasts", allowNoForecasts); + ///Controls the time to wait until the forecast(s) are deleted. Default to 30 seconds + public DeleteForecastDescriptor Timeout(Time timeout) => Qs("timeout", timeout); + } ///descriptor for XpackMlDeleteJob
http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html
public partial class DeleteJobDescriptor : RequestDescriptorBase, IDeleteJobRequest { diff --git a/src/Nest/_Generated/_LowLevelDispatch.generated.cs b/src/Nest/_Generated/_LowLevelDispatch.generated.cs index f85c3f6fab6..e5d4e183b2e 100644 --- a/src/Nest/_Generated/_LowLevelDispatch.generated.cs +++ b/src/Nest/_Generated/_LowLevelDispatch.generated.cs @@ -3396,6 +3396,28 @@ internal partial class LowLevelDispatch throw InvalidDispatch("XpackMlDeleteExpiredData", p, new [] { DELETE }, "/_xpack/ml/_delete_expired_data"); } + internal TResponse XpackMlDeleteForecastDispatch(IRequest p) where TResponse : class, IElasticsearchResponse, new() + { + switch(p.HttpMethod) + { + case DELETE: + if (AllSetNoFallback(p.RouteValues.JobId, p.RouteValues.ForecastId)) return _lowLevel.XpackMlDeleteForecast(p.RouteValues.JobId,p.RouteValues.ForecastId,p.RequestParameters); + break; + } + throw InvalidDispatch("XpackMlDeleteForecast", p, new [] { DELETE }, "/_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id}"); + } + + internal Task XpackMlDeleteForecastDispatchAsync(IRequest p, CancellationToken ct) where TResponse : class, IElasticsearchResponse, new() + { + switch(p.HttpMethod) + { + case DELETE: + if (AllSetNoFallback(p.RouteValues.JobId, p.RouteValues.ForecastId)) return _lowLevel.XpackMlDeleteForecastAsync(p.RouteValues.JobId,p.RouteValues.ForecastId,p.RequestParameters,ct); + break; + } + throw InvalidDispatch("XpackMlDeleteForecast", p, new [] { DELETE }, "/_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id}"); + } + internal TResponse XpackMlDeleteJobDispatch(IRequest p) where TResponse : class, IElasticsearchResponse, new() { switch(p.HttpMethod) diff --git a/src/Nest/_Generated/_Requests.generated.cs b/src/Nest/_Generated/_Requests.generated.cs index b95093f2b27..6d6ac062184 100644 --- a/src/Nest/_Generated/_Requests.generated.cs +++ b/src/Nest/_Generated/_Requests.generated.cs @@ -1809,6 +1809,30 @@ public partial class DeleteExpiredDataRequest : PlainRequestBase + { + Id JobId { get; } + Id ForecastId { get; } + } + ///Request parameters for XpackMlDeleteForecast
http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html
+ public partial class DeleteForecastRequest : PlainRequestBase, IDeleteForecastRequest + { + protected IDeleteForecastRequest Self => this; + ////_xpack/ml/anomaly_detectors/{job_id}/_forecast/{forecast_id} + ///this parameter is required + ///this parameter is required + public DeleteForecastRequest(Id job_id, Id forecast_id) : base(r=>r.Required("job_id", job_id).Required("forecast_id", forecast_id)){} + // values part of the url path + Id IDeleteForecastRequest.JobId => Self.RouteValues.Get("job_id"); + Id IDeleteForecastRequest.ForecastId => Self.RouteValues.Get("forecast_id"); + + // Request parameters + ///Whether to ignore if `_all` matches no forecasts + public bool? AllowNoForecasts { get => Q("allow_no_forecasts"); set => Q("allow_no_forecasts", value); } + ///Controls the time to wait until the forecast(s) are deleted. Default to 30 seconds + public Time Timeout { get => Q