From fe83cf269f4386dc8c15cbb3676d11e964478ee4 Mon Sep 17 00:00:00 2001
From: Qinyouzeng <102203523+Qinyouzeng@users.noreply.github.com>
Date: Thu, 30 Jun 2022 15:30:51 +0800
Subject: [PATCH] Feat: Add Prometheus http api query client sdk (#78)
* feat: add promethus http api query client
* feat: add test project
* feat: api query add
* feat: update code and add tests
* docs: add docs
* feat: add convert json value to object
* feat: fix enume and comments
* feat: code styles and other specifications update
* feat: update callerprovider inject
* feat: update jsonelement convert to obj
* feat: update extensions
* feat: update internal to public
* feat: update directory
* feat: test refrence update
* chore: comments and filename update
* chore: remove not exists project id
* chore: update docs and code style
* chore: enums update
* chore: doc code style update
* chore: dosc update
* chore: docs update
* feat: add promethus http api query client
* feat: add test project
* feat: api query add
* feat: update code and add tests
* docs: add docs
* feat: add convert json value to object
* feat: fix enume and comments
* feat: code styles and other specifications update
* feat: update callerprovider inject
* feat: update jsonelement convert to obj
* feat: update extensions
* feat: update internal to public
* feat: update directory
* feat: test refrence update
* chore: comments and filename update
* chore: remove not exists project id
* chore: update docs and code style
* chore: enums update
* chore: doc code style update
* chore: dosc update
* chore: docs update
* chore: name update and remove no used files
* chore: folder name update
* chore: file rename
* chore: class split
---
Masa.Utils.sln | 16 +-
.../Enums/ResultStatuses.cs | 10 +
.../Enums/ResultTypes.cs | 15 ++
.../Extensions/CallerProviderExtensions.cs | 15 ++
.../Extensions/ObjectExtensions.cs | 142 +++++++++++++++
.../Extensions/StringExtensions.cs | 20 ++
.../IMasaPrometheusClient.cs | 19 ++
.../Masa.Utils.Data.Prometheus.csproj | 14 ++
.../MasaPrometheusClient.cs | 127 +++++++++++++
.../Reponse/Exemplar/ExemplarDataModel.cs | 13 ++
.../Model/Reponse/Exemplar/ExemplarModel.cs | 11 ++
.../Exemplar/ExemplarResultResponse.cs | 9 +
.../Reponse/MetaData/LabelResultResponse.cs | 9 +
.../Reponse/MetaData/SeriesResultResponse.cs | 9 +
.../Query/QueryResultCommonResponse.cs | 9 +
.../Reponse/Query/QueryResultDataResponse.cs | 11 ++
.../Query/QueryResultInstantVectorResponse.cs | 11 ++
.../Query/QueryResultMatrixRangeResponse.cs | 11 ++
.../Model/Reponse/ResultBaseResponse.cs | 15 ++
.../Model/Request/LableValueQueryRequest.cs | 9 +
.../Model/Request/MetaDataQueryRequest.cs | 13 ++
.../Model/Request/QueryExemplarRequest.cs | 14 ++
.../Model/Request/QueryRangeRequest.cs | 17 ++
.../Model/Request/QueryRequest.cs | 13 ++
src/Data/Masa.Utils.Data.Prometheus/README.md | 75 ++++++++
.../README.zh-CN.md | 75 ++++++++
.../ServiceCollectionExtensions.cs | 39 ++++
.../Masa.Utils.Data.Prometheus/_Imports.cs | 15 ++
.../Extensions/ObjectExtensionsTests.cs | 171 ++++++++++++++++++
.../Extensions/StringExtensionsTests.cs | 30 +++
.../Masa.Utils.Data.Prometheus.Test.csproj | 21 +++
.../MasaPrometheusClientTests.cs | 116 ++++++++++++
.../UserStruct.cs | 13 ++
.../_Imports.cs | 12 ++
34 files changed, 1118 insertions(+), 1 deletion(-)
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Enums/ResultStatuses.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Enums/ResultTypes.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Extensions/CallerProviderExtensions.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Extensions/ObjectExtensions.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Extensions/StringExtensions.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/IMasaPrometheusClient.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Masa.Utils.Data.Prometheus.csproj
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/MasaPrometheusClient.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarDataModel.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarModel.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarResultResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/LabelResultResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/SeriesResultResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultCommonResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultDataResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultInstantVectorResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultMatrixRangeResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/ResultBaseResponse.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Request/LableValueQueryRequest.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Request/MetaDataQueryRequest.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Request/QueryExemplarRequest.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Request/QueryRangeRequest.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/Model/Request/QueryRequest.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/README.md
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/README.zh-CN.md
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/ServiceCollectionExtensions.cs
create mode 100644 src/Data/Masa.Utils.Data.Prometheus/_Imports.cs
create mode 100644 test/Masa.Utils.Data.Prometheus.Test/Extensions/ObjectExtensionsTests.cs
create mode 100644 test/Masa.Utils.Data.Prometheus.Test/Extensions/StringExtensionsTests.cs
create mode 100644 test/Masa.Utils.Data.Prometheus.Test/Masa.Utils.Data.Prometheus.Test.csproj
create mode 100644 test/Masa.Utils.Data.Prometheus.Test/MasaPrometheusClientTests.cs
create mode 100644 test/Masa.Utils.Data.Prometheus.Test/UserStruct.cs
create mode 100644 test/Masa.Utils.Data.Prometheus.Test/_Imports.cs
diff --git a/Masa.Utils.sln b/Masa.Utils.sln
index cc2d590..3b75c81 100644
--- a/Masa.Utils.sln
+++ b/Masa.Utils.sln
@@ -101,7 +101,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Validations", "Validations"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Extensions.Validations.FluentValidation", "src\Extensions\Validations\Masa.Utils.Extensions.Validations.FluentValidation\Masa.Utils.Extensions.Validations.FluentValidation.csproj", "{B0E3CA19-C101-4E30-9401-C017B7088F4E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Utils.Security.Authentication.OpenIdConnect", "src\Security\Masa.Utils.Security.Authentication.OpenIdConnect\Masa.Utils.Security.Authentication.OpenIdConnect.csproj", "{D17B5B36-5773-4827-9D5D-44390DF666CA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Security.Authentication.OpenIdConnect", "src\Security\Masa.Utils.Security.Authentication.OpenIdConnect\Masa.Utils.Security.Authentication.OpenIdConnect.csproj", "{D17B5B36-5773-4827-9D5D-44390DF666CA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Data.Prometheus", "src\Data\Masa.Utils.Data.Prometheus\Masa.Utils.Data.Prometheus.csproj", "{81E8A8F5-91EA-43F2-9B19-83B85EED7DB7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Data.Prometheus.Test", "test\Masa.Utils.Data.Prometheus.Test\Masa.Utils.Data.Prometheus.Test.csproj", "{CAB4132B-82E4-4B37-AF05-7F446DE3AF04}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -249,6 +253,14 @@ Global
{D17B5B36-5773-4827-9D5D-44390DF666CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D17B5B36-5773-4827-9D5D-44390DF666CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D17B5B36-5773-4827-9D5D-44390DF666CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {81E8A8F5-91EA-43F2-9B19-83B85EED7DB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {81E8A8F5-91EA-43F2-9B19-83B85EED7DB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {81E8A8F5-91EA-43F2-9B19-83B85EED7DB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {81E8A8F5-91EA-43F2-9B19-83B85EED7DB7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CAB4132B-82E4-4B37-AF05-7F446DE3AF04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAB4132B-82E4-4B37-AF05-7F446DE3AF04}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CAB4132B-82E4-4B37-AF05-7F446DE3AF04}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CAB4132B-82E4-4B37-AF05-7F446DE3AF04}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -299,6 +311,8 @@ Global
{533BCE80-61BC-443A-95D3-2C6328921ED8} = {B2DA607D-4A39-4F0C-A9B3-DD9A061B0B4E}
{B0E3CA19-C101-4E30-9401-C017B7088F4E} = {533BCE80-61BC-443A-95D3-2C6328921ED8}
{D17B5B36-5773-4827-9D5D-44390DF666CA} = {4FB3BD6D-D4C1-4BEF-AD62-8FD6EAEEB4DF}
+ {81E8A8F5-91EA-43F2-9B19-83B85EED7DB7} = {F844C2A1-C36D-400E-A0D8-7658EF9C3B93}
+ {CAB4132B-82E4-4B37-AF05-7F446DE3AF04} = {4F908878-0EB8-43E4-96E4-8B1F32E9B635}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D7DAA0E6-098F-4B18-8775-64FDA96F1FF0}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Enums/ResultStatuses.cs b/src/Data/Masa.Utils.Data.Prometheus/Enums/ResultStatuses.cs
new file mode 100644
index 0000000..b4f33b1
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Enums/ResultStatuses.cs
@@ -0,0 +1,10 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Enums;
+
+public enum ResultStatuses
+{
+ Success = 1,
+ Error
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Enums/ResultTypes.cs b/src/Data/Masa.Utils.Data.Prometheus/Enums/ResultTypes.cs
new file mode 100644
index 0000000..35391ff
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Enums/ResultTypes.cs
@@ -0,0 +1,15 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Enums;
+
+///
+/// reference https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats
+///
+public enum ResultTypes
+{
+ Matrix = 1,
+ Vector,
+ Scalar,
+ String
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Extensions/CallerProviderExtensions.cs b/src/Data/Masa.Utils.Data.Prometheus/Extensions/CallerProviderExtensions.cs
new file mode 100644
index 0000000..e0d49e8
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Extensions/CallerProviderExtensions.cs
@@ -0,0 +1,15 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+[assembly: InternalsVisibleTo("Masa.Utils.Data.Prometheus.Test")]
+namespace Masa.Utils.Caller.Core;
+
+internal static class CallerProviderExtensions
+{
+ public static async Task GetAsync(this ICallerProvider caller, string url, object data)
+ {
+ var request = new HttpRequestMessage(HttpMethod.Get, $"{url}?{data.ToUrlParam()}");
+ var response = await caller.SendAsync(request);
+ return await response.Content.ReadAsStringAsync();
+ }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Extensions/ObjectExtensions.cs b/src/Data/Masa.Utils.Data.Prometheus/Extensions/ObjectExtensions.cs
new file mode 100644
index 0000000..040a876
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Extensions/ObjectExtensions.cs
@@ -0,0 +1,142 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace System;
+
+public static class ObjectExtensions
+{
+ ///
+ /// Currently supported types: class, struct and types implementing the IEnumerable interface,
+ /// struct and class use public get properties and fields by default,
+ /// The IEnumerable type is directly converted to: key[]=value1&key[]=value2
+ /// enum uses strings by default. If you need to use numeric values, please set isEnumString=false
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string? ToUrlParam(this object? obj, bool isEnumString = true, bool isCamelCase = true, bool isUrlEncode = true)
+ {
+ return GetValue(obj, string.Empty, isEnumString, isCamelCase, isUrlEncode);
+ }
+
+ private static string? GetValue(object? obj, string preStr, bool isEnumString = false, bool isCamelCase = true, bool isUrlEncode = true)
+ {
+ if (obj == null) return null;
+ var type = obj.GetType();
+ if (type == typeof(string))
+ {
+ var str = (string)obj;
+ return AppendValue(preStr, str, "=", isUrlEncode);
+ }
+
+ if (type.IsValueType)
+ {
+ if (type.IsEnum)
+ {
+ var str = isEnumString ? obj.ToString() : Convert.ToInt32(obj).ToString();
+ return AppendValue(preStr, str, "=", isUrlEncode);
+ }
+
+ //sample value
+ if (type.IsPrimitive)
+ {
+ var str = obj.ToString();
+ return AppendValue(preStr, str, "=", isUrlEncode);
+ }
+
+ //struct
+ return GetObjValue(type, obj, preStr, isEnumString, isCamelCase, isUrlEncode);
+ }
+
+ if (type.IsArray || type.GetInterfaces().Any(t => t.Name.IndexOf("IEnumerable") == 0))
+ return GetEnumerableValue(obj, preStr, isEnumString, isCamelCase, isUrlEncode);
+
+ if (type.IsClass)
+ return GetObjValue(type, obj, preStr, isEnumString, isCamelCase, isUrlEncode);
+
+ //current type not suport
+ return null;
+ }
+
+ private static string GetObjValue(Type type, object obj, string preStr, bool isEnumString = false, bool isCamelCase = true, bool isUrlEncode = true)
+ {
+ var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
+ var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetField);
+ var list = new List();
+
+ foreach (var item in properties)
+ {
+ var str = GetMemerInfoValue(item, item.GetValue(obj), preStr, isEnumString, isCamelCase, isUrlEncode);
+ if (string.IsNullOrEmpty(str))
+ continue;
+ list.Add(str);
+ }
+
+ foreach (var item in fields)
+ {
+ var str = GetMemerInfoValue(item, item.GetValue(obj), preStr, isEnumString, isCamelCase, isUrlEncode);
+ if (string.IsNullOrEmpty(str))
+ continue;
+ list.Add(str);
+ }
+
+ if (!list.Any())
+ return default!;
+
+ list.Sort();
+ return string.Join('&', list);
+ }
+
+ private static string? GetMemerInfoValue(MemberInfo info, object? value, string preStr, bool isEnumString = false, bool isCamelCase = true, bool isUrlEncode = true)
+ {
+ if (value == null)
+ return null;
+
+ var name = info.Name;
+ if (isCamelCase)
+ name = name.ToCamelCase();
+
+ return GetValue(value, AppendValue(preStr, name, ".", isUrlEncode) ?? default!, isEnumString, isCamelCase, isUrlEncode);
+ }
+
+ private static string? GetEnumerableValue(object obj, string preStr, bool isEnumString = false, bool isCamelCase = true, bool isUrlEncode = true)
+ {
+ var list = new List();
+ foreach (var item in (IEnumerable)obj)
+ {
+ if (item is KeyValuePair keyValue)
+ {
+ var name = keyValue.Key;
+ if (isCamelCase)
+ name = name.ToCamelCase();
+ var str = GetValue(keyValue.Value, AppendValue(preStr, name, ".", isUrlEncode) ?? default!, isEnumString, isCamelCase, isUrlEncode);
+ if (!string.IsNullOrEmpty(str))
+ list.Add(str);
+ }
+ else
+ {
+ var str = GetValue(item, $"{preStr}{(isUrlEncode ? HttpUtility.UrlEncode("[]", Encoding.UTF8) : "[]")}", isEnumString, isCamelCase, isUrlEncode);
+ if (!string.IsNullOrEmpty(str))
+ list.Add(str);
+ }
+ }
+ if (!list.Any())
+ return default!;
+
+ list.Sort();
+ return string.Join('&', list);
+ }
+
+ private static string? AppendValue(string preStr, string? value, string splitChar, bool isUrlEncode)
+ {
+ if (string.IsNullOrEmpty(preStr) || string.IsNullOrEmpty(value))
+ return value;
+
+ if (isUrlEncode)
+ return $"{preStr}{splitChar}{HttpUtility.UrlEncode(value, Encoding.UTF8)}";
+ else
+ return $"{preStr}{splitChar}{value}";
+ }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Extensions/StringExtensions.cs b/src/Data/Masa.Utils.Data.Prometheus/Extensions/StringExtensions.cs
new file mode 100644
index 0000000..a484b7f
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Extensions/StringExtensions.cs
@@ -0,0 +1,20 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace System;
+
+internal static class StringExtensions
+{
+ public static string ToCamelCase(this string str)
+ {
+ if (string.IsNullOrEmpty(str))
+ return default!;
+
+ var span = new ReadOnlySpan(str.ToArray());
+ var c = span[0];
+ if (c - 'A' >= 0 && c - 'Z' <= 0)
+ return $"{(char)(c + 32)}{span[1..]}";
+
+ return str;
+ }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/IMasaPrometheusClient.cs b/src/Data/Masa.Utils.Data.Prometheus/IMasaPrometheusClient.cs
new file mode 100644
index 0000000..cc8c5d5
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/IMasaPrometheusClient.cs
@@ -0,0 +1,19 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus;
+
+public interface IMasaPrometheusClient
+{
+ Task QueryAsync(QueryRequest query);
+
+ Task QueryRangeAsync(QueryRangeRequest query);
+
+ Task SeriesQueryAsync(MetaDataQueryRequest query);
+
+ Task LabelsQueryAsync(MetaDataQueryRequest query);
+
+ Task LabelValuesQueryAsync(LableValueQueryRequest query);
+
+ Task ExemplarQueryAsync(QueryExemplarRequest query);
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Masa.Utils.Data.Prometheus.csproj b/src/Data/Masa.Utils.Data.Prometheus/Masa.Utils.Data.Prometheus.csproj
new file mode 100644
index 0000000..d3bd13a
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Masa.Utils.Data.Prometheus.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/src/Data/Masa.Utils.Data.Prometheus/MasaPrometheusClient.cs b/src/Data/Masa.Utils.Data.Prometheus/MasaPrometheusClient.cs
new file mode 100644
index 0000000..e243e99
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/MasaPrometheusClient.cs
@@ -0,0 +1,127 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+[assembly: InternalsVisibleTo("Masa.Utils.Data.Prometheus.Test")]
+namespace Masa.Utils.Data.Prometheus;
+
+internal class MasaPrometheusClient : IMasaPrometheusClient
+{
+ private readonly ICallerProvider _caller;
+ private readonly JsonSerializerOptions _jsonSerializerOptions;
+
+ public MasaPrometheusClient(ICallerProvider caller, JsonSerializerOptions jsonSerializerOptions)
+ {
+ _caller = caller;
+ _jsonSerializerOptions = jsonSerializerOptions;
+ }
+
+ public async Task ExemplarQueryAsync(QueryExemplarRequest query)
+ {
+ return await QueryDataAsync("/api/v1/query_exemplars", query);
+ }
+
+ public async Task LabelsQueryAsync(MetaDataQueryRequest query)
+ {
+ return await QueryDataAsync("/api/v1/labels", query);
+ }
+
+ public async Task LabelValuesQueryAsync(LableValueQueryRequest query)
+ {
+ var name = query.Lable;
+ query.Lable = null;
+ return await QueryDataAsync($"/api/v1/label/{name}/values", query);
+ }
+
+ public async Task QueryAsync(QueryRequest query)
+ {
+ return await QueryDataAsync("/api/v1/query", query);
+ }
+
+ public async Task QueryRangeAsync(QueryRangeRequest query)
+ {
+ return await QueryDataAsync("/api/v1/query_range", query);
+ }
+
+ public async Task SeriesQueryAsync(MetaDataQueryRequest query)
+ {
+ return await QueryDataAsync("/api/v1/series", query);
+ }
+
+ private async Task QueryDataAsync(string url, object data) where T : ResultBaseResponse
+ {
+ var str = await _caller.GetAsync(url, data);
+ if (string.IsNullOrEmpty(str))
+ return default!;
+
+ var baseResult = JsonSerializer.Deserialize(str, _jsonSerializerOptions);
+
+ if (baseResult == null || baseResult.Status != ResultStatuses.Success)
+ {
+ return baseResult ?? default!;
+ }
+
+ if (typeof(T) == typeof(QueryResultCommonResponse))
+ {
+ var result = baseResult as QueryResultCommonResponse;
+ if (result == null || result.Data == null)
+ return baseResult;
+ switch (result.Data.ResultType)
+ {
+ case ResultTypes.Matrix:
+ {
+ var temp = JsonSerializer.Serialize(result.Data.Result, _jsonSerializerOptions);
+ result.Data.Result = JsonSerializer.Deserialize(temp, _jsonSerializerOptions);
+ if (result.Data.Result != null && result.Data.Result.Any())
+ {
+ foreach (QueryResultMatrixRangeResponse item in result.Data.Result)
+ {
+ if (item.Values == null || !item.Values.Any())
+ continue;
+ var array = item.Values.ToArray();
+ int i = 0, max = array.Length - 1;
+ do
+ {
+ array[i] = ConvertJsonToObjValue(array[i]);
+ i++;
+ }
+ while (max - i >= 0);
+ item.Values = array;
+ }
+ }
+ return result as T ?? default!;
+ }
+ case ResultTypes.Vector:
+ {
+ var temp = JsonSerializer.Serialize(result.Data.Result, _jsonSerializerOptions);
+ result.Data.Result = JsonSerializer.Deserialize(temp, _jsonSerializerOptions);
+ if (result.Data.Result != null && result.Data.Result.Any())
+ {
+ foreach (QueryResultInstantVectorResponse item in result.Data.Result)
+ {
+ item.Value = ConvertJsonToObjValue(item.Value);
+ }
+ }
+ return result as T ?? default!;
+ }
+ default:
+ {
+ if (result.Data.Result != null && result.Data.Result.Any())
+ {
+ result.Data.Result = ConvertJsonToObjValue(result.Data.Result);
+ }
+ }
+ break;
+ }
+ }
+
+ return baseResult;
+ }
+
+ private static object[] ConvertJsonToObjValue(object[]? values)
+ {
+ if (values == null || values.Length - 2 < 0)
+ return default!;
+
+ return new object[] { ((JsonElement)values[0]).GetDouble(), ((JsonElement)values[1]).GetString() ?? default! };
+ }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarDataModel.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarDataModel.cs
new file mode 100644
index 0000000..2777b07
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarDataModel.cs
@@ -0,0 +1,13 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class ExemplarModel
+{
+ public IDictionary? Labels { get; set; }
+
+ public string? Value { get; set; }
+
+ public float TimeStamp { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarModel.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarModel.cs
new file mode 100644
index 0000000..84ff5c6
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarModel.cs
@@ -0,0 +1,11 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class ExemplarDataModel
+{
+ public IDictionary? SeriesLabels { get; set; }
+
+ public IEnumerable? Exemplars { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarResultResponse.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarResultResponse.cs
new file mode 100644
index 0000000..c03e8ee
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Exemplar/ExemplarResultResponse.cs
@@ -0,0 +1,9 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class ExemplarResultResponse : ResultBaseResponse
+{
+ public IEnumerable? Data { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/LabelResultResponse.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/LabelResultResponse.cs
new file mode 100644
index 0000000..a20a25c
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/LabelResultResponse.cs
@@ -0,0 +1,9 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class LabelResultResponse : ResultBaseResponse
+{
+ public IEnumerable? Data { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/SeriesResultResponse.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/SeriesResultResponse.cs
new file mode 100644
index 0000000..6422449
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/MetaData/SeriesResultResponse.cs
@@ -0,0 +1,9 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class SeriesResultResponse : ResultBaseResponse
+{
+ public IEnumerable>? Data { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultCommonResponse.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultCommonResponse.cs
new file mode 100644
index 0000000..1859c35
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultCommonResponse.cs
@@ -0,0 +1,9 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class QueryResultCommonResponse: ResultBaseResponse
+{
+ public QueryResultDataResponse? Data { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultDataResponse.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultDataResponse.cs
new file mode 100644
index 0000000..209f6d5
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultDataResponse.cs
@@ -0,0 +1,11 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class QueryResultDataResponse
+{
+ public ResultTypes ResultType { get; set; }
+
+ public object[]? Result { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultInstantVectorResponse.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultInstantVectorResponse.cs
new file mode 100644
index 0000000..976986e
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultInstantVectorResponse.cs
@@ -0,0 +1,11 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class QueryResultInstantVectorResponse
+{
+ public IDictionary? Metric { get; set; }
+
+ public object[]? Value { get; set; }
+}
diff --git a/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultMatrixRangeResponse.cs b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultMatrixRangeResponse.cs
new file mode 100644
index 0000000..810473d
--- /dev/null
+++ b/src/Data/Masa.Utils.Data.Prometheus/Model/Reponse/Query/QueryResultMatrixRangeResponse.cs
@@ -0,0 +1,11 @@
+// Copyright (c) MASA Stack All rights reserved.
+// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
+
+namespace Masa.Utils.Data.Prometheus.Model;
+
+public class QueryResultMatrixRangeResponse
+{
+ public IDictionary? Metric { get; set; }
+
+ public IEnumerable