Skip to content
This repository has been archived by the owner on Aug 1, 2022. It is now read-only.

Commit

Permalink
Feat: Add Prometheus http api query client sdk (#78)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Qinyouzeng committed Jun 30, 2022
1 parent 5582744 commit fe83cf2
Show file tree
Hide file tree
Showing 34 changed files with 1,118 additions and 1 deletion.
16 changes: 15 additions & 1 deletion Masa.Utils.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down
10 changes: 10 additions & 0 deletions src/Data/Masa.Utils.Data.Prometheus/Enums/ResultStatuses.cs
Original file line number Diff line number Diff line change
@@ -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
}
15 changes: 15 additions & 0 deletions src/Data/Masa.Utils.Data.Prometheus/Enums/ResultTypes.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// reference https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats
/// </summary>
public enum ResultTypes
{
Matrix = 1,
Vector,
Scalar,
String
}
Original file line number Diff line number Diff line change
@@ -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<string> 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();
}
}
142 changes: 142 additions & 0 deletions src/Data/Masa.Utils.Data.Prometheus/Extensions/ObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Currently supported types: class, struct and types implementing the IEnumerable interface,
/// struct and class use public get properties and fields by default,
/// The IEnumerable<KeyValuePair> 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
/// </summary>
/// <param name="obj"></param>
/// <param name="isEnumString"></param>
/// <param name="isCamelCase"></param>
/// <param name="isUrlEncode"></param>
/// <returns></returns>
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<string>();

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<string>();
foreach (var item in (IEnumerable)obj)
{
if (item is KeyValuePair<string, object> 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}";
}
}
20 changes: 20 additions & 0 deletions src/Data/Masa.Utils.Data.Prometheus/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -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<char>(str.ToArray());
var c = span[0];
if (c - 'A' >= 0 && c - 'Z' <= 0)
return $"{(char)(c + 32)}{span[1..]}";

return str;
}
}
19 changes: 19 additions & 0 deletions src/Data/Masa.Utils.Data.Prometheus/IMasaPrometheusClient.cs
Original file line number Diff line number Diff line change
@@ -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<QueryResultCommonResponse> QueryAsync(QueryRequest query);

Task<QueryResultCommonResponse> QueryRangeAsync(QueryRangeRequest query);

Task<SeriesResultResponse> SeriesQueryAsync(MetaDataQueryRequest query);

Task<LabelResultResponse> LabelsQueryAsync(MetaDataQueryRequest query);

Task<LabelResultResponse> LabelValuesQueryAsync(LableValueQueryRequest query);

Task<ExemplarResultResponse> ExemplarQueryAsync(QueryExemplarRequest query);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\Caller\Masa.Utils.Caller.Core\Masa.Utils.Caller.Core.csproj" />
<ProjectReference Include="..\..\Caller\Masa.Utils.Caller.HttpClient\Masa.Utils.Caller.HttpClient.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit fe83cf2

Please sign in to comment.