Merge branch 'master' into DataSourceSystem
This commit is contained in:
commit
1d40edb535
273
.editorconfig
Normal file
273
.editorconfig
Normal file
@ -0,0 +1,273 @@
|
||||
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||
root = true
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
|
||||
#### Core EditorConfig Options ####
|
||||
|
||||
# Indentation and spacing
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
tab_width = 4
|
||||
|
||||
# New line preferences
|
||||
end_of_line = crlf
|
||||
insert_final_newline = false
|
||||
|
||||
#### .NET Coding Conventions ####
|
||||
|
||||
# Organize usings
|
||||
dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = false
|
||||
file_header_template = unset
|
||||
|
||||
# this. and Me. preferences
|
||||
dotnet_style_qualification_for_event = false
|
||||
dotnet_style_qualification_for_field = false
|
||||
dotnet_style_qualification_for_method = false
|
||||
dotnet_style_qualification_for_property = false
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true
|
||||
dotnet_style_predefined_type_for_member_access = true
|
||||
|
||||
# Parentheses preferences
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
|
||||
|
||||
# Modifier preferences
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members
|
||||
|
||||
# Expression-level preferences
|
||||
dotnet_style_coalesce_expression = true
|
||||
dotnet_style_collection_initializer = true
|
||||
dotnet_style_explicit_tuple_names = true
|
||||
dotnet_style_namespace_match_folder = true
|
||||
dotnet_style_null_propagation = true
|
||||
dotnet_style_object_initializer = true
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
dotnet_style_prefer_auto_properties = true
|
||||
dotnet_style_prefer_collection_expression = when_types_loosely_match
|
||||
dotnet_style_prefer_compound_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_return = true
|
||||
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true
|
||||
dotnet_style_prefer_inferred_tuple_names = true
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true
|
||||
dotnet_style_prefer_simplified_interpolation = true
|
||||
|
||||
# Field preferences
|
||||
dotnet_style_readonly_field = true
|
||||
|
||||
# Parameter preferences
|
||||
dotnet_code_quality_unused_parameters = all
|
||||
|
||||
# Suppression preferences
|
||||
dotnet_remove_unnecessary_suppression_exclusions = none
|
||||
|
||||
# New line preferences
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = true
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = true
|
||||
|
||||
#### C# Coding Conventions ####
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_elsewhere = false:silent
|
||||
csharp_style_var_for_built_in_types = false:silent
|
||||
csharp_style_var_when_type_is_apparent = false:silent
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
csharp_style_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
|
||||
# Pattern matching preferences
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_prefer_extended_property_pattern = true:suggestion
|
||||
csharp_style_prefer_not_pattern = true:suggestion
|
||||
csharp_style_prefer_pattern_matching = true:silent
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
|
||||
# Null-checking preferences
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
csharp_prefer_static_local_function = true:suggestion
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
|
||||
csharp_style_prefer_readonly_struct = true:suggestion
|
||||
csharp_style_prefer_readonly_struct_member = true:suggestion
|
||||
|
||||
# Code-block preferences
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_prefer_simple_using_statement = true:suggestion
|
||||
csharp_style_namespace_declarations = file_scoped:silent
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
csharp_style_prefer_primary_constructors = false:none
|
||||
csharp_style_prefer_top_level_statements = true:silent
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_prefer_index_operator = true:suggestion
|
||||
csharp_style_prefer_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_prefer_null_check_over_type_check = true:suggestion
|
||||
csharp_style_prefer_range_operator = true:suggestion
|
||||
csharp_style_prefer_tuple_swap = true:suggestion
|
||||
csharp_style_prefer_utf8_string_literals = true:suggestion
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||
|
||||
# 'using' directive preferences
|
||||
csharp_using_directive_placement = outside_namespace:silent
|
||||
|
||||
# New line preferences
|
||||
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
|
||||
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
|
||||
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
|
||||
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
|
||||
|
||||
#### C# Formatting Rules ####
|
||||
|
||||
# New line preferences
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# Indentation preferences
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
||||
|
||||
#### Naming styles ####
|
||||
|
||||
# Naming rules
|
||||
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
|
||||
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
# Symbol specifications
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# Naming styles
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
|
||||
# Spell check
|
||||
|
||||
spelling_languages = en-us,ru-RU
|
||||
spelling_exclusion_path = exclusion.dic
|
||||
|
||||
[*.{cs,vb}]
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true:silent
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
|
||||
dotnet_style_namespace_match_folder = true:suggestion
|
||||
dotnet_code_quality_unused_parameters = all:suggestion
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
dotnet_style_predefined_type_for_member_access = true:silent
|
||||
dotnet_style_qualification_for_field = false:silent
|
||||
dotnet_style_qualification_for_property = false:silent
|
||||
dotnet_style_qualification_for_method = false:silent
|
||||
dotnet_style_qualification_for_event = false:silent
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
@ -12,7 +12,7 @@ namespace Persistence.API.Controllers;
|
||||
[Route("api/[controller]")]
|
||||
public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
{
|
||||
private IChangeLogRepository repository;
|
||||
private readonly IChangeLogRepository repository;
|
||||
|
||||
public ChangeLogController(IChangeLogRepository repository)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
using Persistence.Repositories;
|
||||
using Persistence.Repository.Data;
|
||||
|
||||
namespace Persistence.API.Controllers;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
using Persistence.Repositories;
|
||||
using System.Net;
|
||||
|
||||
namespace Persistence.API.Controllers;
|
||||
|
||||
@ -14,98 +14,98 @@ namespace Persistence.API.Controllers;
|
||||
[Route("api/[controller]")]
|
||||
public class SetpointController : ControllerBase, ISetpointApi
|
||||
{
|
||||
private readonly ISetpointRepository setpointRepository;
|
||||
private readonly ISetpointRepository setpointRepository;
|
||||
|
||||
public SetpointController(ISetpointRepository setpointRepository)
|
||||
{
|
||||
this.setpointRepository = setpointRepository;
|
||||
}
|
||||
public SetpointController(ISetpointRepository setpointRepository)
|
||||
{
|
||||
this.setpointRepository = setpointRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить актуальные значения уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("current")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetCurrent(setpointKeys, token);
|
||||
/// <summary>
|
||||
/// Получить актуальные значения уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("current")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetCurrent(setpointKeys, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="historyMoment"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("history")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory([FromQuery] IEnumerable<Guid> setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="historyMoment"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("history")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory([FromQuery] IEnumerable<Guid> setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить историю изменений значений уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("log")]
|
||||
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetLog(setpointKeys, token);
|
||||
/// <summary>
|
||||
/// Получить историю изменений значений уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("log")]
|
||||
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetLog(setpointKeys, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("range")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetDatesRangeAsync(token);
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("range")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetDatesRangeAsync(token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("part")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetPart(dateBegin, take, token);
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("part")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetPart(dateBegin, take, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить уставку
|
||||
/// </summary>
|
||||
/// <param name="setpointKey"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
await setpointRepository.Add(setpointKey, newValue, userId, token);
|
||||
/// <summary>
|
||||
/// Сохранить уставку
|
||||
/// </summary>
|
||||
/// <param name="setpointKey"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
await setpointRepository.Add(setpointKey, newValue, userId, token);
|
||||
|
||||
return CreatedAtAction(nameof(Add), true);
|
||||
}
|
||||
return CreatedAtAction(nameof(Add), true);
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,48 @@
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
using Persistence.Models.Requests;
|
||||
using Persistence.Repositories;
|
||||
using System.Net;
|
||||
|
||||
namespace Persistence.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Работа с состояниями систем автобурения (АБ)
|
||||
/// Работа с технологическими сообщениями систем автобурения (АБ)
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class TechMessagesController : ControllerBase
|
||||
{
|
||||
private readonly ITechMessagesRepository techMessagesRepository;
|
||||
private static readonly Dictionary<int, string> categories = new Dictionary<int, string>()
|
||||
{
|
||||
{ 0, "System" },
|
||||
{ 1, "Авария" },
|
||||
{ 2, "Предупреждение" },
|
||||
{ 3, "Инфо" },
|
||||
{ 4, "Прочее" }
|
||||
};
|
||||
private readonly ITechMessagesRepository techMessagesRepository;
|
||||
private static readonly Dictionary<int, string> categories = new()
|
||||
{
|
||||
{ 0, "System" },
|
||||
{ 1, "Авария" },
|
||||
{ 2, "Предупреждение" },
|
||||
{ 3, "Инфо" },
|
||||
{ 4, "Прочее" }
|
||||
};
|
||||
|
||||
public TechMessagesController(ITechMessagesRepository techMessagesRepository)
|
||||
{
|
||||
this.techMessagesRepository = techMessagesRepository;
|
||||
}
|
||||
public TechMessagesController(ITechMessagesRepository techMessagesRepository)
|
||||
{
|
||||
this.techMessagesRepository = techMessagesRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список технологических сообщений в виде страницы
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<PaginationContainer<TechMessageDto>>> GetPage([FromQuery] PaginationRequest request, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetPage(request, token);
|
||||
/// <summary>
|
||||
/// Получить список технологических сообщений в виде страницы
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<PaginationContainer<TechMessageDto>>> GetPage([FromQuery] PaginationRequest request, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetPage(request, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить статистику по системам
|
||||
@ -56,49 +56,49 @@ public class TechMessagesController : ControllerBase
|
||||
{
|
||||
var result = await techMessagesRepository.GetStatistics(autoDrillingSystem, categoryIds, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список всех систем
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("systems")]
|
||||
public async Task<ActionResult<Dictionary<string, int>>> GetSystems(CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetSystems(token);
|
||||
/// <summary>
|
||||
/// Получить список всех систем
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("systems")]
|
||||
public async Task<ActionResult<Dictionary<string, int>>> GetSystems(CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetSystems(token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("range")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetDatesRangeAsync(token);
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("range")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetDatesRangeAsync(token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("part")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetPart(dateBegin, take, token);
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("part")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetPart(dateBegin, take, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить новые технологические сообщения
|
||||
@ -115,16 +115,16 @@ public class TechMessagesController : ControllerBase
|
||||
|
||||
var result = await techMessagesRepository.AddRange(systemId, dtos, userId, token);
|
||||
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить словарь категорий
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("categories")]
|
||||
public ActionResult<Dictionary<int, string>> GetImportantCategories()
|
||||
{
|
||||
return Ok(categories);
|
||||
}
|
||||
/// <summary>
|
||||
/// Получить словарь категорий
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("categories")]
|
||||
public ActionResult<Dictionary<int, string>> GetImportantCategories()
|
||||
{
|
||||
return Ok(categories);
|
||||
}
|
||||
}
|
@ -11,20 +11,20 @@ namespace Persistence.API.Controllers;
|
||||
public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDto>
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
{
|
||||
private ITimeSeriesDataRepository<TDto> timeSeriesDataRepository;
|
||||
private readonly ITimeSeriesDataRepository<TDto> timeSeriesDataRepository;
|
||||
|
||||
public TimeSeriesController(ITimeSeriesDataRepository<TDto> timeSeriesDataRepository)
|
||||
{
|
||||
this.timeSeriesDataRepository = timeSeriesDataRepository;
|
||||
public TimeSeriesController(ITimeSeriesDataRepository<TDto> timeSeriesDataRepository)
|
||||
{
|
||||
this.timeSeriesDataRepository = timeSeriesDataRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список объектов, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
/// <summary>
|
||||
/// Получить список объектов, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get(DateTimeOffset dateBegin, CancellationToken token)
|
||||
{
|
||||
@ -32,40 +32,40 @@ public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDt
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозиторие
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("datesRange")]
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("datesRange")]
|
||||
public async Task<IActionResult> GetDatesRange(CancellationToken token)
|
||||
{
|
||||
var result = await timeSeriesDataRepository.GetDatesRange(token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="intervalSec"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("resampled")]
|
||||
/// <summary>
|
||||
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="intervalSec"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("resampled")]
|
||||
public async Task<IActionResult> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
|
||||
{
|
||||
var result = await timeSeriesDataRepository.GetResampledData(dateBegin, intervalSec, approxPointsCount, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить записи
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
/// <summary>
|
||||
/// Добавить записи
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await timeSeriesDataRepository.AddRange(dtos, token);
|
||||
|
@ -13,7 +13,7 @@ namespace Persistence.API.Controllers;
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]/{idDiscriminator}")]
|
||||
public class TimestampedSetController : ControllerBase
|
||||
public class TimestampedSetController : ControllerBase
|
||||
{
|
||||
private readonly ITimestampedSetRepository repository;
|
||||
|
||||
@ -32,7 +32,7 @@ public class TimestampedSetController : ControllerBase
|
||||
/// <returns>кол-во затронутых записей</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> AddRange([FromRoute]Guid idDiscriminator, [FromBody]IEnumerable<TimestampedSetDto> sets, CancellationToken token)
|
||||
public async Task<IActionResult> AddRange([FromRoute] Guid idDiscriminator, [FromBody] IEnumerable<TimestampedSetDto> sets, CancellationToken token)
|
||||
{
|
||||
var result = await repository.AddRange(idDiscriminator, sets, token);
|
||||
return Ok(result);
|
||||
@ -50,7 +50,7 @@ public class TimestampedSetController : ControllerBase
|
||||
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, [FromQuery]IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||
public async Task<IActionResult> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, [FromQuery] IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||
{
|
||||
var result = await repository.Get(idDiscriminator, geTimestamp, columnNames, skip, take, token);
|
||||
return Ok(result);
|
||||
@ -66,7 +66,7 @@ public class TimestampedSetController : ControllerBase
|
||||
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||
[HttpGet("last")]
|
||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetLast(Guid idDiscriminator, [FromQuery]IEnumerable<string>? columnNames, int take, CancellationToken token)
|
||||
public async Task<IActionResult> GetLast(Guid idDiscriminator, [FromQuery] IEnumerable<string>? columnNames, int take, CancellationToken token)
|
||||
{
|
||||
var result = await repository.GetLast(idDiscriminator, columnNames, take, token);
|
||||
return Ok(result);
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
using Persistence.Services.Interfaces;
|
||||
using System.Net;
|
||||
|
||||
namespace Persistence.API.Controllers;
|
||||
|
||||
@ -14,73 +14,73 @@ namespace Persistence.API.Controllers;
|
||||
[Route("api/[controller]")]
|
||||
public class WitsDataController : ControllerBase, IWitsDataApi
|
||||
{
|
||||
private readonly IWitsDataService witsDataService;
|
||||
private readonly IWitsDataService witsDataService;
|
||||
|
||||
public WitsDataController(IWitsDataService witsDataService)
|
||||
{
|
||||
this.witsDataService = witsDataService;
|
||||
}
|
||||
public WitsDataController(IWitsDataService witsDataService)
|
||||
{
|
||||
this.witsDataService = witsDataService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/datesRange")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync([FromRoute] Guid discriminatorId, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetDatesRangeAsync(discriminatorId, token);
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/datesRange")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync([FromRoute] Guid discriminatorId, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetDatesRangeAsync(discriminatorId, token);
|
||||
|
||||
return result == null ? NoContent() : Ok(result);
|
||||
}
|
||||
return result == null ? NoContent() : Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/part")]
|
||||
public async Task<ActionResult<IEnumerable<WitsDataDto>>> GetPart([FromRoute] Guid discriminatorId, [FromQuery] DateTimeOffset dateBegin, [FromQuery] int take, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetPart(discriminatorId, dateBegin, take, token);
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/part")]
|
||||
public async Task<ActionResult<IEnumerable<WitsDataDto>>> GetPart([FromRoute] Guid discriminatorId, [FromQuery] DateTimeOffset dateBegin, [FromQuery] int take, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetPart(discriminatorId, dateBegin, take, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId">Дискриминатор системы</param>
|
||||
/// <param name="dateFrom">Начало временного интервала</param>
|
||||
/// <param name="dateTo">Конец временного интервала</param>
|
||||
/// <param name="approxPointsCount">Количество точек</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/graph")]
|
||||
public async Task<ActionResult<IEnumerable<WitsDataDto>>> GetValuesForGraph([FromRoute] Guid discriminatorId,
|
||||
[FromQuery] DateTimeOffset dateFrom, [FromQuery] DateTimeOffset dateTo, [FromQuery] int approxPointsCount, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointsCount, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId">Дискриминатор системы</param>
|
||||
/// <param name="dateFrom">Начало временного интервала</param>
|
||||
/// <param name="dateTo">Конец временного интервала</param>
|
||||
/// <param name="approxPointsCount">Количество точек</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/graph")]
|
||||
public async Task<ActionResult<IEnumerable<WitsDataDto>>> GetValuesForGraph([FromRoute] Guid discriminatorId,
|
||||
[FromQuery] DateTimeOffset dateFrom, [FromQuery] DateTimeOffset dateTo, [FromQuery] int approxPointsCount, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointsCount, token);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> AddRange([FromBody] IEnumerable<WitsDataDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.AddRange(dtos, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> AddRange([FromBody] IEnumerable<WitsDataDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.AddRange(dtos, token);
|
||||
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
}
|
||||
|
@ -30,12 +30,11 @@ public static class DependencyInjection
|
||||
c.MapType<DateOnly>(() => new OpenApiSchema { Type = "string", Format = "date" });
|
||||
c.MapType<JsonValue>(() => new OpenApiSchema
|
||||
{
|
||||
AnyOf = new OpenApiSchema[]
|
||||
{
|
||||
AnyOf = [
|
||||
new OpenApiSchema {Type = "string", Format = "string" },
|
||||
new OpenApiSchema {Type = "number", Format = "int32" },
|
||||
new OpenApiSchema {Type = "number", Format = "float" },
|
||||
}
|
||||
new OpenApiSchema {Type = "number", Format = "float" }
|
||||
]
|
||||
});
|
||||
|
||||
c.CustomOperationIds(e =>
|
||||
@ -47,8 +46,8 @@ public static class DependencyInjection
|
||||
|
||||
var needUseKeyCloak = configuration.GetSection("NeedUseKeyCloak").Get<bool>();
|
||||
if (needUseKeyCloak)
|
||||
c.AddKeycloackSecurity(configuration);
|
||||
else c.AddDefaultSecurity(configuration);
|
||||
c.AddKeycloakSecurity(configuration);
|
||||
else c.AddDefaultSecurity();
|
||||
|
||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
@ -57,13 +56,13 @@ public static class DependencyInjection
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IWitsDataService, WitsDataService>();
|
||||
}
|
||||
public static void AddServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IWitsDataService, WitsDataService>();
|
||||
}
|
||||
|
||||
#region Authentication
|
||||
public static void AddJWTAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||
#region Authentication
|
||||
public static void AddJWTAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var needUseKeyCloak = configuration
|
||||
.GetSection("NeedUseKeyCloak")
|
||||
@ -108,7 +107,7 @@ public static class DependencyInjection
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
var accessToken = context.Request.Headers["Authorization"]
|
||||
var accessToken = context.Request.Headers.Authorization
|
||||
.ToString()
|
||||
.Replace(JwtBearerDefaults.AuthenticationScheme, string.Empty)
|
||||
.Trim();
|
||||
@ -141,12 +140,12 @@ public static class DependencyInjection
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Security (Swagger)
|
||||
private static void AddKeycloackSecurity(this SwaggerGenOptions options, IConfiguration configuration)
|
||||
#region Keycloak
|
||||
private static void AddKeycloakSecurity(this SwaggerGenOptions options, IConfiguration configuration)
|
||||
{
|
||||
options.AddSecurityDefinition("Keycloack", new OpenApiSecurityScheme
|
||||
options.AddSecurityDefinition("Keycloak", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'",
|
||||
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345token'",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.OAuth2,
|
||||
@ -167,7 +166,7 @@ public static class DependencyInjection
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Keycloack"
|
||||
Id = "Keycloak"
|
||||
},
|
||||
Scheme = "Bearer",
|
||||
Name = "Bearer",
|
||||
@ -178,11 +177,11 @@ public static class DependencyInjection
|
||||
});
|
||||
}
|
||||
|
||||
private static void AddDefaultSecurity(this SwaggerGenOptions options, IConfiguration configuration)
|
||||
private static void AddDefaultSecurity(this SwaggerGenOptions options)
|
||||
{
|
||||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'",
|
||||
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345token'",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
|
@ -7,18 +7,15 @@ public static class Extensions
|
||||
{
|
||||
public static T GetUserId<T>(this ClaimsPrincipal principal)
|
||||
{
|
||||
if (principal == null)
|
||||
throw new ArgumentNullException(nameof(principal));
|
||||
ArgumentNullException.ThrowIfNull(principal, nameof(principal));
|
||||
|
||||
var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
|
||||
if (String.IsNullOrEmpty(loggedInUserId))
|
||||
throw new ArgumentNullException(nameof(loggedInUserId));
|
||||
ArgumentNullException.ThrowIfNullOrEmpty(loggedInUserId, nameof(loggedInUserId));
|
||||
|
||||
var result = TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(loggedInUserId);
|
||||
|
||||
if (result is null)
|
||||
throw new ArgumentNullException(nameof(result));
|
||||
ArgumentNullException.ThrowIfNull(result, nameof(result));
|
||||
|
||||
return (T)result;
|
||||
|
||||
|
@ -9,6 +9,11 @@
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
|
||||
<AssemblyVersion>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.2.1" />
|
||||
|
@ -1,6 +0,0 @@
|
||||
@Persistence.API_HostAddress = http://localhost:5032
|
||||
|
||||
GET {{Persistence.API_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
@ -1,6 +1,3 @@
|
||||
|
||||
using Persistence.Models;
|
||||
|
||||
namespace Persistence.API;
|
||||
|
||||
public class Program
|
||||
@ -18,5 +15,5 @@ public class Program
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using Persistence.Repository;
|
||||
using Persistence.Database.Model;
|
||||
using Persistence.Database.Model;
|
||||
using Persistence.Database.Postgres;
|
||||
using Persistence.Repository;
|
||||
|
||||
namespace Persistence.API;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Persistence.Models;
|
||||
using Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
@ -1,31 +1,31 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Persistence.Models.Configurations;
|
||||
using RestSharp;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Persistence.Client.Helpers;
|
||||
public static class ApiTokenHelper
|
||||
{
|
||||
public static void Authorize(this HttpClient httpClient, IConfiguration configuration)
|
||||
{
|
||||
var authUser = configuration
|
||||
.GetSection(nameof(AuthUser))
|
||||
.Get<AuthUser>()!;
|
||||
var needUseKeyCloak = configuration
|
||||
.GetSection("NeedUseKeyCloak")
|
||||
.Get<bool>()!;
|
||||
var keycloakGetTokenUrl = configuration.GetSection("KeycloakGetTokenUrl").Get<string>() ?? string.Empty;
|
||||
public static void Authorize(this HttpClient httpClient, IConfiguration configuration)
|
||||
{
|
||||
var authUser = configuration
|
||||
.GetSection(nameof(AuthUser))
|
||||
.Get<AuthUser>()!;
|
||||
var needUseKeyCloak = configuration
|
||||
.GetSection("NeedUseKeyCloak")
|
||||
.Get<bool>()!;
|
||||
var keycloakGetTokenUrl = configuration.GetSection("KeycloakGetTokenUrl").Get<string>() ?? string.Empty;
|
||||
|
||||
var jwtToken = needUseKeyCloak
|
||||
? authUser.CreateKeyCloakJwtToken(keycloakGetTokenUrl)
|
||||
: authUser.CreateDefaultJwtToken();
|
||||
var jwtToken = needUseKeyCloak
|
||||
? authUser.CreateKeyCloakJwtToken(keycloakGetTokenUrl)
|
||||
: authUser.CreateDefaultJwtToken();
|
||||
|
||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
|
||||
}
|
||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
|
||||
}
|
||||
|
||||
public static void Authorize(this HttpClient httpClient, string jwtToken)
|
||||
{
|
||||
@ -45,36 +45,36 @@ public static class ApiTokenHelper
|
||||
new(ClaimTypes.NameIdentifier.ToString(), Guid.NewGuid().ToString())
|
||||
};
|
||||
|
||||
var tokenDescriptor = new SecurityTokenDescriptor
|
||||
{
|
||||
Issuer = JwtParams.Issuer,
|
||||
Audience = JwtParams.Audience,
|
||||
Subject = new ClaimsIdentity(claims),
|
||||
Expires = DateTime.UtcNow.AddHours(1),
|
||||
SigningCredentials = new SigningCredentials(JwtParams.SecurityKey, SecurityAlgorithms.HmacSha256Signature)
|
||||
};
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
var tokenDescriptor = new SecurityTokenDescriptor
|
||||
{
|
||||
Issuer = JwtParams.Issuer,
|
||||
Audience = JwtParams.Audience,
|
||||
Subject = new ClaimsIdentity(claims),
|
||||
Expires = DateTime.UtcNow.AddHours(1),
|
||||
SigningCredentials = new SigningCredentials(JwtParams.SecurityKey, SecurityAlgorithms.HmacSha256Signature)
|
||||
};
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
private static string CreateKeyCloakJwtToken(this AuthUser authUser, string keycloakGetTokenUrl)
|
||||
{
|
||||
var restClient = new RestClient();
|
||||
private static string CreateKeyCloakJwtToken(this AuthUser authUser, string keycloakGetTokenUrl)
|
||||
{
|
||||
var restClient = new RestClient();
|
||||
|
||||
var request = new RestRequest(keycloakGetTokenUrl, Method.Post);
|
||||
request.AddParameter("username", authUser.Username);
|
||||
request.AddParameter("password", authUser.Password);
|
||||
request.AddParameter("client_id", authUser.ClientId);
|
||||
request.AddParameter("grant_type", authUser.GrantType);
|
||||
var request = new RestRequest(keycloakGetTokenUrl, Method.Post);
|
||||
request.AddParameter("username", authUser.Username);
|
||||
request.AddParameter("password", authUser.Password);
|
||||
request.AddParameter("client_id", authUser.ClientId);
|
||||
request.AddParameter("grant_type", authUser.GrantType);
|
||||
|
||||
var keyCloackResponse = restClient.Post(request);
|
||||
if (keyCloackResponse.IsSuccessful && !String.IsNullOrEmpty(keyCloackResponse.Content))
|
||||
{
|
||||
var token = JsonSerializer.Deserialize<JwtToken>(keyCloackResponse.Content)!;
|
||||
return token.AccessToken;
|
||||
}
|
||||
var keycloakResponse = restClient.Post(request);
|
||||
if (keycloakResponse.IsSuccessful && !String.IsNullOrEmpty(keycloakResponse.Content))
|
||||
{
|
||||
var token = JsonSerializer.Deserialize<JwtToken>(keycloakResponse.Content)!;
|
||||
return token.AccessToken;
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
@ -38,6 +38,11 @@
|
||||
<PackageReadmeFile>Readme.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
|
||||
<AssemblyVersion>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Readme.md" Pack="true" PackagePath="\"/>
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,3 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Persistence.Client.Clients.Interfaces;
|
||||
using Persistence.Client.Clients;
|
||||
@ -8,6 +7,7 @@ using Persistence.Factories;
|
||||
using Persistence.Client.Clients.Interfaces.Refit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Persistence.Client
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Npgsql;
|
||||
|
||||
namespace Persistence.Database.Model;
|
||||
|
||||
|
@ -12,12 +12,14 @@ public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<Persistenc
|
||||
{
|
||||
public PersistencePostgresContext CreateDbContext(string[] args)
|
||||
{
|
||||
var connectionStringBuilder = new NpgsqlConnectionStringBuilder();
|
||||
connectionStringBuilder.Host = "localhost";
|
||||
connectionStringBuilder.Database = "persistence";
|
||||
connectionStringBuilder.Username = "postgres";
|
||||
connectionStringBuilder.Password = "q";
|
||||
connectionStringBuilder.PersistSecurityInfo = true;
|
||||
var connectionStringBuilder = new NpgsqlConnectionStringBuilder
|
||||
{
|
||||
Host = "localhost",
|
||||
Database = "persistence",
|
||||
Username = "postgres",
|
||||
Password = "q",
|
||||
PersistSecurityInfo = true
|
||||
};
|
||||
var connectionString = connectionStringBuilder.ToString();
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<PersistencePostgresContext>();
|
||||
|
@ -1,11 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Persistence.Database.Postgres;
|
||||
public static class EFExtensionsInitialization
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
|
||||
|
||||
namespace Persistence.Database.Model;
|
||||
|
||||
@ -10,7 +9,7 @@ public partial class PersistencePostgresContext : PersistenceDbContext
|
||||
{
|
||||
public PersistencePostgresContext(DbContextOptions options)
|
||||
: base(options)
|
||||
{}
|
||||
{ }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Persistence.Database;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Persistence.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Persistence.Database.Model;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Persistence.Database.Model;
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Persistence.Database.Entity;
|
||||
public class DataSourceSystem
|
||||
|
@ -1,21 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Persistence.Database.Entity;
|
||||
|
||||
[PrimaryKey(nameof(DiscriminatorId), nameof(ParameterId), nameof(Timestamp))]
|
||||
public class ParameterData
|
||||
{
|
||||
[Required, Comment("Дискриминатор системы")]
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
[Required, Comment("Дискриминатор системы")]
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
|
||||
[Comment("Id параметра")]
|
||||
public int ParameterId { get; set; }
|
||||
[Comment("Id параметра")]
|
||||
public int ParameterId { get; set; }
|
||||
|
||||
[Column(TypeName = "varchar(256)"), Comment("Значение параметра в виде строки")]
|
||||
public required string Value { get; set; }
|
||||
[Column(TypeName = "varchar(256)"), Comment("Значение параметра в виде строки")]
|
||||
public required string Value { get; set; }
|
||||
|
||||
[Comment("Временная отметка")]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
[Comment("Временная отметка")]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Persistence.Database.Model
|
||||
{
|
||||
[PrimaryKey(nameof(Key), nameof(Created))]
|
||||
public class Setpoint
|
||||
{
|
||||
[Comment("Ключ")]
|
||||
public Guid Key { get; set; }
|
||||
[PrimaryKey(nameof(Key), nameof(Created))]
|
||||
public class Setpoint
|
||||
{
|
||||
[Comment("Ключ")]
|
||||
public Guid Key { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
|
||||
public required object Value { get; set; }
|
||||
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
|
||||
public required object Value { get; set; }
|
||||
|
||||
[Comment("Дата создания уставки")]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
[Comment("Дата создания уставки")]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
|
||||
[Comment("Id автора последнего изменения")]
|
||||
public Guid IdUser { get; set; }
|
||||
}
|
||||
[Comment("Id автора последнего изменения")]
|
||||
public Guid IdUser { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Persistence.Database.Entity
|
||||
{
|
||||
public class TechMessage
|
||||
{
|
||||
[Key, Comment("Id события")]
|
||||
public Guid EventId { get; set; }
|
||||
public class TechMessage
|
||||
{
|
||||
[Key, Comment("Id события")]
|
||||
public Guid EventId { get; set; }
|
||||
|
||||
[Comment("Id Категории важности")]
|
||||
public int CategoryId { get; set; }
|
||||
[Comment("Id Категории важности")]
|
||||
public int CategoryId { get; set; }
|
||||
|
||||
[Comment("Дата возникновения")]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
[Comment("Дата возникновения")]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
|
||||
public required string Text { get; set; }
|
||||
|
@ -6,6 +6,6 @@ namespace Persistence.Database.Entity;
|
||||
[Comment("Общая таблица данных временных рядов")]
|
||||
[PrimaryKey(nameof(IdDiscriminator), nameof(Timestamp))]
|
||||
public record TimestampedSet(
|
||||
[property: Comment("Дискриминатор ссылка на тип сохраняемых данных")] Guid IdDiscriminator,
|
||||
[property: Comment("Отметка времени, строго в UTC")] DateTimeOffset Timestamp,
|
||||
[property: Comment("Дискриминатор ссылка на тип сохраняемых данных")] Guid IdDiscriminator,
|
||||
[property: Comment("Отметка времени, строго в UTC")] DateTimeOffset Timestamp,
|
||||
[property: Column(TypeName = "jsonb"), Comment("Набор сохраняемых данных")] IDictionary<string, object> Set);
|
||||
|
@ -17,9 +17,9 @@ public class PersistenceDbContext : DbContext
|
||||
|
||||
public DbSet<ChangeLog> ChangeLog => Set<ChangeLog>();
|
||||
|
||||
public DbSet<TechMessage> TechMessage => Set<TechMessage>();
|
||||
public DbSet<TechMessage> TechMessage => Set<TechMessage>();
|
||||
|
||||
public DbSet<ParameterData> ParameterData => Set<ParameterData>();
|
||||
public DbSet<ParameterData> ParameterData => Set<ParameterData>();
|
||||
|
||||
public DbSet<DataSourceSystem> DataSourceSystem => Set<DataSourceSystem>();
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Persistence.Database;
|
||||
using Persistence.Database.Model;
|
||||
using Xunit;
|
||||
|
||||
namespace Persistence.IntegrationTests;
|
||||
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>,
|
||||
IDisposable
|
||||
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>, IDisposable
|
||||
{
|
||||
protected readonly IServiceScope scope;
|
||||
|
||||
@ -23,5 +21,6 @@ public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>,
|
||||
{
|
||||
scope.Dispose();
|
||||
dbContext.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace Persistence.IntegrationTests.Controllers;
|
||||
public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private readonly IChangeLogClient client;
|
||||
private static Random generatorRandomDigits = new Random();
|
||||
private static readonly Random generatorRandomDigits = new();
|
||||
|
||||
public ChangeLogControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
@ -26,11 +26,11 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
[Fact]
|
||||
public async Task ClearAndInsertRange_InEmptyDb()
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(2, DateTimeOffset.UtcNow);
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(2);
|
||||
|
||||
// act
|
||||
var result = await client.ClearAndAddRange(idDiscriminator, dtos, new CancellationToken());
|
||||
@ -61,7 +61,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
// arrange
|
||||
var count = 1;
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(count, DateTimeOffset.UtcNow);
|
||||
var dtos = Generate(count);
|
||||
var dto = dtos.FirstOrDefault()!;
|
||||
|
||||
// act
|
||||
@ -77,7 +77,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
// arrange
|
||||
var count = 3;
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(count, DateTimeOffset.UtcNow);
|
||||
var dtos = Generate(count);
|
||||
|
||||
// act
|
||||
var result = await client.AddRange(idDiscriminator, dtos, new CancellationToken());
|
||||
@ -89,11 +89,11 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
[Fact]
|
||||
public async Task Update_returns_success()
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(1, DateTimeOffset.UtcNow);
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(1);
|
||||
var dto = dtos.FirstOrDefault()!;
|
||||
var result = await client.Add(idDiscriminator, dto, new CancellationToken());
|
||||
|
||||
@ -101,7 +101,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
.Where(x => x.IdDiscriminator == idDiscriminator)
|
||||
.FirstOrDefault();
|
||||
dto = entity.Adapt<DataWithWellDepthAndSectionDto>();
|
||||
dto.DepthEnd = dto.DepthEnd + 10;
|
||||
dto.DepthEnd += 10;
|
||||
|
||||
// act
|
||||
result = await client.Update(dto, new CancellationToken());
|
||||
@ -138,7 +138,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
{
|
||||
// arrange
|
||||
var count = 2;
|
||||
var dtos = Generate(count, DateTimeOffset.UtcNow);
|
||||
var dtos = Generate(count);
|
||||
var entities = dtos.Select(d => d.Adapt<ChangeLog>()).ToArray();
|
||||
dbContext.ChangeLog.AddRange(entities);
|
||||
dbContext.SaveChanges();
|
||||
@ -163,7 +163,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
public async Task Delete_returns_success()
|
||||
{
|
||||
// arrange
|
||||
var dtos = Generate(1, DateTimeOffset.UtcNow);
|
||||
var dtos = Generate(1);
|
||||
var dto = dtos.FirstOrDefault()!;
|
||||
var entity = dto.Adapt<ChangeLog>();
|
||||
dbContext.ChangeLog.Add(entity);
|
||||
@ -181,7 +181,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
{
|
||||
// arrange
|
||||
var count = 10;
|
||||
var dtos = Generate(count, DateTimeOffset.UtcNow);
|
||||
var dtos = Generate(count);
|
||||
var entities = dtos.Select(d => d.Adapt<ChangeLog>()).ToArray();
|
||||
dbContext.ChangeLog.AddRange(entities);
|
||||
dbContext.SaveChanges();
|
||||
@ -223,11 +223,11 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
[Fact]
|
||||
public async Task GetByDate_returns_success()
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
//создаем записи
|
||||
var count = 5;
|
||||
//создаем записи
|
||||
var count = 5;
|
||||
var changeLogItems = CreateChangeLogItems(count, (-15, 15));
|
||||
var idDiscriminator = changeLogItems.Item1;
|
||||
var entities = changeLogItems.Item2;
|
||||
@ -241,8 +241,8 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
|
||||
var filterRequest = new SectionPartRequest()
|
||||
{
|
||||
DepthStart = 0,
|
||||
DepthEnd = 1000,
|
||||
DepthStart = 0,
|
||||
DepthEnd = 1000,
|
||||
};
|
||||
|
||||
var paginationRequest = new PaginationRequest()
|
||||
@ -276,11 +276,11 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
int daysAfterNowFilter,
|
||||
int changeLogCount)
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
//создаем записи
|
||||
var count = insertedCount;
|
||||
//создаем записи
|
||||
var count = insertedCount;
|
||||
var daysRange = (daysBeforeNowChangeLog, daysAfterNowChangeLog);
|
||||
var changeLogItems = CreateChangeLogItems(count, daysRange);
|
||||
var idDiscriminator = changeLogItems.Item1;
|
||||
@ -288,7 +288,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
entity.DepthEnd = entity.DepthEnd + 10;
|
||||
entity.DepthEnd += 10;
|
||||
}
|
||||
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>()).ToArray();
|
||||
await client.UpdateRange(dtos, new CancellationToken());
|
||||
@ -304,7 +304,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
}
|
||||
|
||||
|
||||
private static IEnumerable<DataWithWellDepthAndSectionDto> Generate(int count, DateTimeOffset from)
|
||||
private static IEnumerable<DataWithWellDepthAndSectionDto> Generate(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
yield return new DataWithWellDepthAndSectionDto()
|
||||
@ -326,8 +326,8 @@ public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
var minDayCount = daysRange.Item1;
|
||||
var maxDayCount = daysRange.Item2;
|
||||
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(count, DateTimeOffset.UtcNow);
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(count);
|
||||
var entities = dtos.Select(d =>
|
||||
{
|
||||
var entity = d.Adapt<ChangeLog>();
|
||||
|
@ -1,12 +1,11 @@
|
||||
using Persistence.Client;
|
||||
using Persistence.Database.Model;
|
||||
using Persistence.Repository.Data;
|
||||
using Persistence.Database.Model;
|
||||
using Persistence.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace Persistence.IntegrationTests.Controllers;
|
||||
public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaub, DataSaubDto>
|
||||
{
|
||||
private readonly DataSaubDto dto = new DataSaubDto()
|
||||
private readonly DataSaubDto dto = new()
|
||||
{
|
||||
AxialLoad = 1,
|
||||
BitDepth = 2,
|
||||
@ -29,7 +28,7 @@ public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaub, Dat
|
||||
WellDepth = 18,
|
||||
};
|
||||
|
||||
private readonly DataSaub entity = new DataSaub()
|
||||
private readonly DataSaub entity = new()
|
||||
{
|
||||
AxialLoad = 1,
|
||||
BitDepth = 2,
|
||||
@ -76,7 +75,7 @@ public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaub, Dat
|
||||
await GetDatesRangeSuccess(entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task GetResampledData_returns_success()
|
||||
|
@ -1,37 +1,38 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Persistence.Client;
|
||||
using Persistence.Client.Clients.Interfaces;
|
||||
using Persistence.Database.Model;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace Persistence.IntegrationTests.Controllers
|
||||
{
|
||||
public class SetpointControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private ISetpointClient setpointClient;
|
||||
private class TestObject
|
||||
{
|
||||
public string? value1 { get; set; }
|
||||
public int? value2 { get; set; }
|
||||
}
|
||||
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var scope = factory.Services.CreateScope();
|
||||
var persistenceClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<PersistenceClientFactory>();
|
||||
public class SetpointControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private readonly ISetpointClient setpointClient;
|
||||
private class TestObject
|
||||
{
|
||||
public string? Value1 { get; set; }
|
||||
public int? Value2 { get; set; }
|
||||
}
|
||||
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var scope = factory.Services.CreateScope();
|
||||
var persistenceClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<PersistenceClientFactory>();
|
||||
|
||||
setpointClient = persistenceClientFactory.GetSetpointClient();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetCurrent_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
[Fact]
|
||||
public async Task GetCurrent_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetCurrent(setpointKeys, new CancellationToken());
|
||||
@ -41,11 +42,11 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetCurrent_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
[Fact]
|
||||
public async Task GetCurrent_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetCurrent([setpointKey], new CancellationToken());
|
||||
@ -56,16 +57,16 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Equal(setpointKey, response.FirstOrDefault()?.Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetHistory_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
var historyMoment = DateTimeOffset.UtcNow;
|
||||
[Fact]
|
||||
public async Task GetHistory_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
var historyMoment = DateTimeOffset.UtcNow;
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetHistory(setpointKeys, historyMoment, new CancellationToken());
|
||||
@ -75,13 +76,13 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetHistory_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
var historyMoment = DateTimeOffset.UtcNow;
|
||||
historyMoment = historyMoment.AddDays(1);
|
||||
[Fact]
|
||||
public async Task GetHistory_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
var historyMoment = DateTimeOffset.UtcNow;
|
||||
historyMoment = historyMoment.AddDays(1);
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetHistory([setpointKey], historyMoment, new CancellationToken());
|
||||
@ -92,15 +93,15 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Equal(setpointKey, response.FirstOrDefault()?.Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetLog_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
[Fact]
|
||||
public async Task GetLog_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetLog(setpointKeys, new CancellationToken());
|
||||
@ -110,11 +111,11 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetLog_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
[Fact]
|
||||
public async Task GetLog_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetLog([setpointKey], new CancellationToken());
|
||||
@ -125,11 +126,11 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Equal(setpointKey, response.FirstOrDefault().Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<Setpoint>();
|
||||
[Fact]
|
||||
public async Task GetDatesRange_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<Setpoint>();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetDatesRangeAsync(CancellationToken.None);
|
||||
@ -140,13 +141,13 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Equal(DateTimeOffset.MaxValue, response!.To);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<Setpoint>();
|
||||
|
||||
await Add();
|
||||
[Fact]
|
||||
public async Task GetDatesRange_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<Setpoint>();
|
||||
|
||||
await Add();
|
||||
|
||||
var dateBegin = DateTimeOffset.MinValue;
|
||||
var take = 1;
|
||||
@ -170,12 +171,12 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Equal(expectedValue, actualValueTo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 2;
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 2;
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
@ -185,13 +186,13 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 1;
|
||||
await Add();
|
||||
[Fact]
|
||||
public async Task GetPart_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 1;
|
||||
await Add();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
@ -201,21 +202,21 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.NotEmpty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Save_returns_success()
|
||||
{
|
||||
await Add();
|
||||
}
|
||||
[Fact]
|
||||
public async Task Save_returns_success()
|
||||
{
|
||||
await Add();
|
||||
}
|
||||
|
||||
private async Task<Guid> Add()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = Guid.NewGuid();
|
||||
var setpointValue = new TestObject()
|
||||
{
|
||||
value1 = "1",
|
||||
value2 = 2
|
||||
};
|
||||
private async Task<Guid> Add()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = Guid.NewGuid();
|
||||
var setpointValue = new TestObject()
|
||||
{
|
||||
Value1 = "1",
|
||||
Value2 = 2
|
||||
};
|
||||
|
||||
//act
|
||||
await setpointClient.Add(setpointKey, setpointValue, new CancellationToken());
|
||||
|
@ -6,6 +6,7 @@ using Persistence.Database.Entity;
|
||||
using Persistence.Models;
|
||||
using Persistence.Models.Enumerations;
|
||||
using Persistence.Models.Requests;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace Persistence.IntegrationTests.Controllers
|
||||
@ -33,15 +34,15 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
dbContext.CleanupDbSet<TechMessage>();
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
var requestDto = new PaginationRequest()
|
||||
{
|
||||
Skip = 1,
|
||||
Take = 2,
|
||||
SortSettings = nameof(TechMessage.CategoryId)
|
||||
};
|
||||
var requestDto = new PaginationRequest()
|
||||
{
|
||||
Skip = 1,
|
||||
Take = 2,
|
||||
SortSettings = nameof(TechMessage.CategoryId)
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetPage(requestDto, CancellationToken.None);
|
||||
//act
|
||||
var response = await techMessagesClient.GetPage(requestDto, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -63,8 +64,8 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
SortSettings = nameof(TechMessage.CategoryId)
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetPage(requestDto, CancellationToken.None);
|
||||
//act
|
||||
var response = await techMessagesClient.GetPage(requestDto, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -115,8 +116,8 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
dbContext.CleanupDbSet<TechMessage>();
|
||||
dbContext.CleanupDbSet<Database.Entity.DataSourceSystem>();
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetSystems(CancellationToken.None);
|
||||
//act
|
||||
var response = await techMessagesClient.GetSystems(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -129,8 +130,8 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
//arrange
|
||||
var dtos = await InsertRange(Guid.NewGuid());
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetSystems(CancellationToken.None);
|
||||
//act
|
||||
var response = await techMessagesClient.GetSystems(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -201,8 +202,8 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
//arrange
|
||||
await InsertRange(Guid.NewGuid());
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetDatesRangeAsync(CancellationToken.None);
|
||||
//act
|
||||
var response = await techMessagesClient.GetDatesRangeAsync(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -210,15 +211,15 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
Assert.NotNull(response?.To);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 2;
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 2;
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
//act
|
||||
var response = await techMessagesClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -233,8 +234,8 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
var take = 1;
|
||||
await InsertRange(Guid.NewGuid());
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
//act
|
||||
var response = await techMessagesClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -275,7 +276,7 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
//assert
|
||||
Assert.Equal(dtos.Count, response);
|
||||
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,26 @@
|
||||
using System.Net;
|
||||
using Mapster;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Persistence.Client;
|
||||
using Persistence.Client.Clients.Interfaces;
|
||||
using Persistence.Database.Model;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace Persistence.IntegrationTests.Controllers;
|
||||
|
||||
public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrationTest
|
||||
where TEntity : class, ITimestampedData, new()
|
||||
where TDto : class, new()
|
||||
{
|
||||
private ITimeSeriesClient<TDto> timeSeriesClient;
|
||||
private readonly ITimeSeriesClient<TDto> timeSeriesClient;
|
||||
|
||||
public TimeSeriesBaseControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
dbContext.CleanupDbSet<TEntity>();
|
||||
|
||||
var scope = factory.Services.CreateScope();
|
||||
var persistenceClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<PersistenceClientFactory>();
|
||||
var scope = factory.Services.CreateScope();
|
||||
var persistenceClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<PersistenceClientFactory>();
|
||||
|
||||
timeSeriesClient = persistenceClientFactory.GetTimeSeriesClient<TDto>();
|
||||
}
|
||||
@ -100,7 +101,7 @@ public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrat
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
|
||||
var ratio = entities.Count() / approxPointsCount;
|
||||
var ratio = entities.Count / approxPointsCount;
|
||||
if (ratio > 1)
|
||||
{
|
||||
var expectedResampledCount = entities
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Persistence.Client;
|
||||
using Persistence.Client.Clients.Interfaces;
|
||||
using Persistence.Models;
|
||||
@ -25,7 +25,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(10, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
|
||||
// act
|
||||
var response = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
var response = await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.Equal(testSets.Count(), response);
|
||||
@ -38,10 +38,10 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue, new CancellationToken());
|
||||
var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
@ -55,7 +55,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
string[] props = ["A"];
|
||||
|
||||
// act
|
||||
@ -64,13 +64,13 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(count, response.Count());
|
||||
foreach ( var item in response )
|
||||
{
|
||||
Assert.Single(item.Set);
|
||||
var kv = item.Set.First();
|
||||
Assert.Equal("A", kv.Key);
|
||||
}
|
||||
}
|
||||
foreach (var item in response)
|
||||
{
|
||||
Assert.Single(item.Set);
|
||||
var kv = item.Set.First();
|
||||
Assert.Equal("A", kv.Key);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_geDate()
|
||||
@ -80,15 +80,15 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
int count = 10;
|
||||
var dateMin = DateTimeOffset.Now;
|
||||
var dateMax = DateTimeOffset.Now.AddSeconds(count);
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var tail = testSets.OrderBy(t => t.Timestamp).Skip(count / 2).Take(int.MaxValue);
|
||||
var geDate = tail.First().Timestamp;
|
||||
var tolerance = TimeSpan.FromSeconds(1);
|
||||
var expectedCount = tail.Count();
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, geDate, null, 0, int.MaxValue, new CancellationToken());
|
||||
var response = await client.Get(idDiscriminator, geDate, null, 0, int.MaxValue, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
@ -104,7 +104,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var expectedCount = count / 2;
|
||||
|
||||
// act
|
||||
@ -124,7 +124,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
var expectedCount = 1;
|
||||
int count = 10 + expectedCount;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, null, null, count - expectedCount, count, new CancellationToken());
|
||||
@ -141,7 +141,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var expectedCount = 8;
|
||||
|
||||
// act
|
||||
@ -159,9 +159,9 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
var dateMin = DateTimeOffset.Now;
|
||||
var dateMax = DateTimeOffset.Now.AddSeconds(count-1);
|
||||
var dateMax = DateTimeOffset.Now.AddSeconds(count - 1);
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var tolerance = TimeSpan.FromSeconds(1);
|
||||
|
||||
// act
|
||||
@ -180,7 +180,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 144;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken());
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// act
|
||||
var response = await client.Count(idDiscriminator, new CancellationToken());
|
||||
|
@ -1,98 +1,99 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Persistence.Client;
|
||||
using Persistence.Client.Clients;
|
||||
using Persistence.Client.Clients.Interfaces;
|
||||
using Persistence.Database.Entity;
|
||||
using Persistence.Models;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace Persistence.IntegrationTests.Controllers;
|
||||
public class WitsDataControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private IWitsDataClient witsDataClient;
|
||||
private IWitsDataClient witsDataClient;
|
||||
|
||||
public WitsDataControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var scope = factory.Services.CreateScope();
|
||||
var persistenceClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<PersistenceClientFactory>();
|
||||
public WitsDataControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var scope = factory.Services.CreateScope();
|
||||
var persistenceClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<PersistenceClientFactory>();
|
||||
|
||||
witsDataClient = persistenceClientFactory.GetWitsDataClient();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRangeAsync_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
[Fact]
|
||||
public async Task GetDatesRangeAsync_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None);
|
||||
//act
|
||||
var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 1;
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 1;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None);
|
||||
//act
|
||||
var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
//act
|
||||
await AddRange();
|
||||
}
|
||||
//act
|
||||
await AddRange();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetValuesForGraph_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
[Fact]
|
||||
public async Task GetValuesForGraph_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var dateFrom = DateTimeOffset.UtcNow;
|
||||
var dateTo = DateTimeOffset.UtcNow;
|
||||
var approxPointCount = 12;
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var dateFrom = DateTimeOffset.UtcNow;
|
||||
var dateTo = DateTimeOffset.UtcNow;
|
||||
var approxPointCount = 12;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None);
|
||||
//act
|
||||
var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRangeAsync_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
[Fact]
|
||||
public async Task GetDatesRangeAsync_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var dtos = await AddRange();
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
var dtos = await AddRange();
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None);
|
||||
//act
|
||||
var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -114,19 +115,19 @@ public class WitsDataControllerTest : BaseIntegrationTest
|
||||
Assert.Equal(expectedDateTo, actualDateTo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
[Fact]
|
||||
public async Task GetPart_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var dtos = await AddRange();
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
var dateBegin = dtos.FirstOrDefault()!.Timestamped;
|
||||
var take = 1;
|
||||
var dtos = await AddRange();
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
var dateBegin = dtos.FirstOrDefault()!.Timestamped;
|
||||
var take = 1;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None);
|
||||
//act
|
||||
var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -137,26 +138,26 @@ public class WitsDataControllerTest : BaseIntegrationTest
|
||||
var actualDto = response.FirstOrDefault();
|
||||
Assert.Equal(expectedDto?.DiscriminatorId, actualDto?.DiscriminatorId);
|
||||
|
||||
var expectedValueDto = expectedDto?.Values.FirstOrDefault();
|
||||
var actualValueDto = actualDto?.Values.FirstOrDefault();
|
||||
Assert.Equal(expectedValueDto?.ItemId, actualValueDto?.ItemId);
|
||||
Assert.Equal(expectedValueDto?.RecordId, actualValueDto?.RecordId);
|
||||
}
|
||||
var expectedValueDto = expectedDto?.Values.FirstOrDefault();
|
||||
var actualValueDto = actualDto?.Values.FirstOrDefault();
|
||||
Assert.Equal(expectedValueDto?.ItemId, actualValueDto?.ItemId);
|
||||
Assert.Equal(expectedValueDto?.RecordId, actualValueDto?.RecordId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetValuesForGraph_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
[Fact]
|
||||
public async Task GetValuesForGraph_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var dtos = await AddRange(37);
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
var dateFrom = dtos.Select(e => e.Timestamped).Min();
|
||||
var dateTo = dtos.Select(e => e.Timestamped).Max();
|
||||
var approxPointCount = 12;
|
||||
var dtos = await AddRange(37);
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
var dateFrom = dtos.Select(e => e.Timestamped).Min();
|
||||
var dateTo = dtos.Select(e => e.Timestamped).Max();
|
||||
var approxPointCount = 12;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None);
|
||||
//act
|
||||
var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
@ -181,10 +182,10 @@ public class WitsDataControllerTest : BaseIntegrationTest
|
||||
RecordId = -1, // < 0
|
||||
ItemId = 101, // > 100
|
||||
Value = string.Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
@ -198,37 +199,37 @@ public class WitsDataControllerTest : BaseIntegrationTest
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<WitsDataDto>> AddRange(int countToCreate = 10)
|
||||
{
|
||||
var dtos = new List<WitsDataDto>();
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var timestamped = DateTimeOffset.UtcNow;
|
||||
for (var i = 0; i < countToCreate; i++)
|
||||
{
|
||||
var random = new Random();
|
||||
dtos.Add(new WitsDataDto()
|
||||
{
|
||||
DiscriminatorId = discriminatorId,
|
||||
Timestamped = timestamped.AddSeconds(i),
|
||||
Values = new List<WitsValueDto>()
|
||||
{
|
||||
new WitsValueDto()
|
||||
{
|
||||
RecordId = i + 1,
|
||||
ItemId = i + 1,
|
||||
Value = random.Next(1, 100)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private async Task<IEnumerable<WitsDataDto>> AddRange(int countToCreate = 10)
|
||||
{
|
||||
var dtos = new List<WitsDataDto>();
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var timestamped = DateTimeOffset.UtcNow;
|
||||
for (var i = 0; i < countToCreate; i++)
|
||||
{
|
||||
var random = new Random();
|
||||
dtos.Add(new WitsDataDto()
|
||||
{
|
||||
DiscriminatorId = discriminatorId,
|
||||
Timestamped = timestamped.AddSeconds(i),
|
||||
Values = new List<WitsValueDto>()
|
||||
{
|
||||
new WitsValueDto()
|
||||
{
|
||||
RecordId = i + 1,
|
||||
ItemId = i + 1,
|
||||
Value = random.Next(1, 100)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.AddRange(dtos, CancellationToken.None);
|
||||
//act
|
||||
var response = await witsDataClient.AddRange(dtos, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
var count = dtos.SelectMany(e => e.Values).Count();
|
||||
Assert.Equal(count, response);
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Persistence.IntegrationTests;
|
||||
namespace Persistence.IntegrationTests;
|
||||
public class DbConnection
|
||||
{
|
||||
public string Host { get; set; } = null!;
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Persistence.Database.Model;
|
||||
|
||||
namespace Persistence.IntegrationTests;
|
||||
public static class EFCoreExtensions
|
||||
|
@ -1,15 +0,0 @@
|
||||
using Persistence.Database;
|
||||
using Persistence.Database.Model;
|
||||
|
||||
namespace Persistence.IntegrationTests.Extensions;
|
||||
|
||||
public static class EFCoreExtensions
|
||||
{
|
||||
public static void CleanupDbSet<T>(this PersistenceDbContext dbContext)
|
||||
where T : class
|
||||
{
|
||||
var dbset = dbContext.Set<T>();
|
||||
dbset.RemoveRange(dbset);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
namespace Persistence.IntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Фабрика HTTP клиентов для интеграционных тестов
|
||||
/// </summary>
|
||||
public class TestHttpClientFactory : IHttpClientFactory
|
||||
{
|
||||
private readonly WebAppFactoryFixture factory;
|
||||
/// <summary>
|
||||
/// Фабрика HTTP клиентов для интеграционных тестов
|
||||
/// </summary>
|
||||
public class TestHttpClientFactory : IHttpClientFactory
|
||||
{
|
||||
private readonly WebAppFactoryFixture factory;
|
||||
|
||||
public TestHttpClientFactory(WebAppFactoryFixture factory)
|
||||
{
|
||||
this.factory = factory;
|
||||
}
|
||||
public HttpClient CreateClient(string name)
|
||||
{
|
||||
return factory.CreateClient();
|
||||
}
|
||||
}
|
||||
public TestHttpClientFactory(WebAppFactoryFixture factory)
|
||||
{
|
||||
this.factory = factory;
|
||||
}
|
||||
public HttpClient CreateClient(string name)
|
||||
{
|
||||
return factory.CreateClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,16 +17,16 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
||||
private string connectionString = string.Empty;
|
||||
|
||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||
{
|
||||
{
|
||||
builder.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config.AddJsonFile("appsettings.Tests.json");
|
||||
|
||||
var dbConnection = config.Build().GetSection("DbConnection").Get<DbConnection>()!;
|
||||
connectionString = dbConnection.GetConnectionString();
|
||||
});
|
||||
var dbConnection = config.Build().GetSection("DbConnection").Get<DbConnection>()!;
|
||||
connectionString = dbConnection.GetConnectionString();
|
||||
});
|
||||
|
||||
builder.ConfigureServices(services =>
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<PersistencePostgresContext>));
|
||||
if (descriptor != null)
|
||||
@ -45,7 +45,7 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
||||
|
||||
services.AddSingleton<PersistenceClientFactory>();
|
||||
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
var scopedServices = scope.ServiceProvider;
|
||||
@ -53,7 +53,7 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
||||
var dbContext = scopedServices.GetRequiredService<PersistencePostgresContext>();
|
||||
dbContext.Database.EnsureCreatedAndMigrated();
|
||||
dbContext.SaveChanges();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override async ValueTask DisposeAsync()
|
||||
@ -64,5 +64,7 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
||||
.Options);
|
||||
|
||||
await dbContext.Database.EnsureDeletedAsync();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections;
|
||||
|
||||
namespace Persistence.Repository;
|
||||
/// <summary>
|
||||
@ -134,20 +129,20 @@ public class CyclicArray<T> : IEnumerable<T>
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
=> new CyclycListEnumerator<T>(array, current, used);
|
||||
=> new CyclicListEnumerator<T>(array, current, used);
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
||||
class CyclycListEnumerator<Te> : IEnumerator<Te>
|
||||
class CyclicListEnumerator<Te> : IEnumerator<Te>
|
||||
{
|
||||
private readonly Te[] array;
|
||||
private readonly int used;
|
||||
private readonly int first;
|
||||
private int current = -1;
|
||||
|
||||
public CyclycListEnumerator(Te[] array, int first, int used)
|
||||
public CyclicListEnumerator(Te[] array, int first, int used)
|
||||
{
|
||||
this.array = new Te[array.Length];
|
||||
array.CopyTo(this.array, 0);
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Persistence.Database.Model;
|
||||
using Persistence.Models;
|
||||
using Persistence.Repositories;
|
||||
using Persistence.Repository.Data;
|
||||
using Persistence.Repository.Repositories;
|
||||
|
||||
namespace Persistence.Repository;
|
||||
@ -33,7 +32,7 @@ public static class DependencyInjection
|
||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
||||
services.AddTransient<IChangeLogRepository, ChangeLogRepository>();
|
||||
services.AddTransient<ITimestampedSetRepository, TimestampedSetRepository>();
|
||||
services.AddTransient<ITechMessagesRepository, TechMessagesRepository>();
|
||||
services.AddTransient<ITechMessagesRepository, TechMessagesRepository>();
|
||||
services.AddTransient<IParameterRepository, ParameterRepository>();
|
||||
services.AddTransient<IDataSourceSystemRepository, DataSourceSystemRepository>();
|
||||
|
||||
|
@ -44,7 +44,7 @@ public static class EFExtensionsSortBy
|
||||
var name = propertyInfo.Name.ToLower();
|
||||
ParameterExpression arg = Expression.Parameter(type, "x");
|
||||
MemberExpression property = Expression.Property(arg, propertyInfo.Name);
|
||||
var selector = Expression.Lambda(property, new ParameterExpression[] { arg });
|
||||
var selector = Expression.Lambda(property, [arg]);
|
||||
var typeAccessor = new TypeAccessor
|
||||
{
|
||||
KeySelector = selector,
|
||||
@ -200,7 +200,7 @@ public static class EFExtensionsSortBy
|
||||
: orderByAscending;
|
||||
|
||||
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
||||
.Invoke(genericMethod, new object[] { query, lambdaExpression })!;
|
||||
.Invoke(genericMethod, [query, lambdaExpression])!;
|
||||
return newQuery;
|
||||
}
|
||||
|
||||
@ -226,7 +226,6 @@ public static class EFExtensionsSortBy
|
||||
|
||||
LambdaExpression? lambdaExpression = null;
|
||||
|
||||
// TODO: Устранить дублирование кода
|
||||
if (propertyName.Contains('.'))
|
||||
{
|
||||
Type type = rootType;
|
||||
@ -261,7 +260,7 @@ public static class EFExtensionsSortBy
|
||||
: orderByAscending;
|
||||
|
||||
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
||||
.Invoke(genericMethod, new object[] { query, lambdaExpression })!;
|
||||
.Invoke(genericMethod, [query, lambdaExpression])!;
|
||||
return newQuery;
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ public static class QueryBuilders
|
||||
return query;
|
||||
}
|
||||
|
||||
public static IQueryable<TEntity> Apply<TEntity>(this IQueryable<TEntity> query,DateTimeOffset momentUtc)
|
||||
public static IQueryable<TEntity> Apply<TEntity>(this IQueryable<TEntity> query, DateTimeOffset momentUtc)
|
||||
where TEntity : class, IChangeLog
|
||||
{
|
||||
momentUtc = momentUtc.ToUniversalTime();
|
||||
@ -40,7 +40,7 @@ public static class QueryBuilders
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static async Task<PaginationContainer<TDto>> ApplyPagination<TEntity, TDto>(
|
||||
this IQueryable<TEntity> query,
|
||||
|
@ -9,7 +9,7 @@ using UuidExtensions;
|
||||
namespace Persistence.Repository.Repositories;
|
||||
public class ChangeLogRepository : IChangeLogRepository
|
||||
{
|
||||
private DbContext db;
|
||||
private readonly DbContext db;
|
||||
|
||||
public ChangeLogRepository(DbContext db)
|
||||
{
|
||||
@ -123,11 +123,11 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
|
||||
return result;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<PaginationContainer<DataWithWellDepthAndSectionDto>> GetByDate(
|
||||
Guid idDiscriminator,
|
||||
Guid idDiscriminator,
|
||||
DateTimeOffset momentUtc,
|
||||
SectionPartRequest filterRequest,
|
||||
PaginationRequest paginationRequest,
|
||||
@ -195,7 +195,7 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
return datesOnly;
|
||||
}
|
||||
|
||||
private ChangeLog CreateEntityFromDto(Guid idAuthor, Guid idDiscriminator, DataWithWellDepthAndSectionDto dto)
|
||||
private static ChangeLog CreateEntityFromDto(Guid idAuthor, Guid idDiscriminator, DataWithWellDepthAndSectionDto dto)
|
||||
{
|
||||
var entity = new ChangeLog()
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Persistence.Database.Entity;
|
||||
using Persistence.Models;
|
||||
using Persistence.Repositories;
|
||||
@ -8,80 +7,80 @@ using Persistence.Repositories;
|
||||
namespace Persistence.Repository.Repositories;
|
||||
public class ParameterRepository : IParameterRepository
|
||||
{
|
||||
private DbContext db;
|
||||
private DbContext db;
|
||||
|
||||
public ParameterRepository(DbContext db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
public ParameterRepository(DbContext db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<ParameterData> GetQueryReadOnly() => db.Set<ParameterData>();
|
||||
protected virtual IQueryable<ParameterData> GetQueryReadOnly() => db.Set<ParameterData>();
|
||||
|
||||
public async Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.Where(e => e.DiscriminatorId == idDiscriminator)
|
||||
.GroupBy(e => 1)
|
||||
.Select(group => new
|
||||
{
|
||||
Min = group.Min(e => e.Timestamp),
|
||||
Max = group.Max(e => e.Timestamp),
|
||||
});
|
||||
var values = await query.FirstOrDefaultAsync(token);
|
||||
var result = new DatesRangeDto()
|
||||
{
|
||||
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||
};
|
||||
public async Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.Where(e => e.DiscriminatorId == idDiscriminator)
|
||||
.GroupBy(e => 1)
|
||||
.Select(group => new
|
||||
{
|
||||
Min = group.Min(e => e.Timestamp),
|
||||
Max = group.Max(e => e.Timestamp),
|
||||
});
|
||||
var values = await query.FirstOrDefaultAsync(token);
|
||||
var result = new DatesRangeDto()
|
||||
{
|
||||
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ParameterDto>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var universalDate = dateBegin.ToUniversalTime();
|
||||
var entities = await query
|
||||
.Where(e => e.DiscriminatorId == idDiscriminator && e.Timestamp >= universalDate)
|
||||
.Take(take)
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities.Select(e => e.Adapt<ParameterDto>());
|
||||
public async Task<IEnumerable<ParameterDto>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var universalDate = dateBegin.ToUniversalTime();
|
||||
var entities = await query
|
||||
.Where(e => e.DiscriminatorId == idDiscriminator && e.Timestamp >= universalDate)
|
||||
.Take(take)
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities.Select(e => e.Adapt<ParameterDto>());
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ParameterDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, int? ratio, CancellationToken token)
|
||||
{
|
||||
var query = db.Set<ParameterData>().AsNoTracking();
|
||||
var universalDateFrom = dateFrom.ToUniversalTime();
|
||||
var universalDateTo = dateTo.ToUniversalTime();
|
||||
public async Task<IEnumerable<ParameterDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, int? ratio, CancellationToken token)
|
||||
{
|
||||
var query = db.Set<ParameterData>().AsNoTracking();
|
||||
var universalDateFrom = dateFrom.ToUniversalTime();
|
||||
var universalDateTo = dateTo.ToUniversalTime();
|
||||
|
||||
query = query
|
||||
.Where(e => e.DiscriminatorId == discriminatorId)
|
||||
.Where(e => e.Timestamp >= universalDateFrom && e.Timestamp <= universalDateTo)
|
||||
.OrderBy(e => e.Timestamp);
|
||||
if (ratio != null)
|
||||
{
|
||||
query = query.Where(e => ((int) (e.Timestamp - dateFrom).TotalSeconds) % ratio == 0);
|
||||
}
|
||||
query = query
|
||||
.Where(e => e.DiscriminatorId == discriminatorId)
|
||||
.Where(e => e.Timestamp >= universalDateFrom && e.Timestamp <= universalDateTo)
|
||||
.OrderBy(e => e.Timestamp);
|
||||
if (ratio != null)
|
||||
{
|
||||
query = query.Where(e => ((int)(e.Timestamp - dateFrom).TotalSeconds) % ratio == 0);
|
||||
}
|
||||
|
||||
var entities = await query
|
||||
.Take((int)(2.5 * approxPointsCount))
|
||||
.ToArrayAsync(token);
|
||||
var entities = await query
|
||||
.Take((int)(2.5 * approxPointsCount))
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var dtos = entities.Select(e => e.Adapt<ParameterDto>());
|
||||
var dtos = entities.Select(e => e.Adapt<ParameterDto>());
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(IEnumerable<ParameterDto> dtos, CancellationToken token)
|
||||
{
|
||||
var entities = dtos.Select(e => e.Adapt<ParameterData>());
|
||||
public async Task<int> AddRange(IEnumerable<ParameterDto> dtos, CancellationToken token)
|
||||
{
|
||||
var entities = dtos.Select(e => e.Adapt<ParameterData>());
|
||||
|
||||
await db.Set<ParameterData>().AddRangeAsync(entities, token);
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
await db.Set<ParameterData>().AddRangeAsync(entities, token);
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -6,100 +6,100 @@ using Persistence.Repositories;
|
||||
|
||||
namespace Persistence.Repository.Repositories
|
||||
{
|
||||
public class SetpointRepository : ISetpointRepository
|
||||
{
|
||||
private DbContext db;
|
||||
public SetpointRepository(DbContext db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
public class SetpointRepository : ISetpointRepository
|
||||
{
|
||||
private readonly DbContext db;
|
||||
public SetpointRepository(DbContext db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<Setpoint> GetQueryReadOnly() => db.Set<Setpoint>();
|
||||
protected virtual IQueryable<Setpoint> GetQueryReadOnly() => db.Set<Setpoint>();
|
||||
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => setpointKeys.Contains(e.Key))
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities.Select(e => e.Adapt<SetpointValueDto>());
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => setpointKeys.Contains(e.Key))
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities.Select(e => e.Adapt<SetpointValueDto>());
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => setpointKeys.Contains(e.Key))
|
||||
.ToArrayAsync(token);
|
||||
var filteredEntities = entities
|
||||
.GroupBy(e => e.Key)
|
||||
.Select(e => e.OrderBy(o => o.Created))
|
||||
.Select(e => e.Where(e => e.Created <= historyMoment).Last());
|
||||
var dtos = filteredEntities
|
||||
.Select(e => e.Adapt<SetpointValueDto>());
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => setpointKeys.Contains(e.Key))
|
||||
.ToArrayAsync(token);
|
||||
var filteredEntities = entities
|
||||
.GroupBy(e => e.Key)
|
||||
.Select(e => e.OrderBy(o => o.Created))
|
||||
.Select(e => e.Where(e => e.Created <= historyMoment).Last());
|
||||
var dtos = filteredEntities
|
||||
.Select(e => e.Adapt<SetpointValueDto>());
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => e.Created >= dateBegin)
|
||||
.Take(take)
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities
|
||||
.Select(e => e.Adapt<SetpointLogDto>());
|
||||
public async Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => e.Created >= dateBegin)
|
||||
.Take(take)
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities
|
||||
.Select(e => e.Adapt<SetpointLogDto>());
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.GroupBy(e => 1)
|
||||
.Select(group => new
|
||||
{
|
||||
Min = group.Min(e => e.Created),
|
||||
Max = group.Max(e => e.Created),
|
||||
});
|
||||
var values = await query.FirstOrDefaultAsync(token);
|
||||
var result = new DatesRangeDto()
|
||||
{
|
||||
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||
};
|
||||
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly()
|
||||
.GroupBy(e => 1)
|
||||
.Select(group => new
|
||||
{
|
||||
Min = group.Min(e => e.Created),
|
||||
Max = group.Max(e => e.Created),
|
||||
});
|
||||
var values = await query.FirstOrDefaultAsync(token);
|
||||
var result = new DatesRangeDto()
|
||||
{
|
||||
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => setpointKeys.Contains(e.Key))
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities
|
||||
.GroupBy(e => e.Key)
|
||||
.ToDictionary(e => e.Key, v => v.Select(z => z.Adapt<SetpointLogDto>()));
|
||||
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => setpointKeys.Contains(e.Key))
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities
|
||||
.GroupBy(e => e.Key)
|
||||
.ToDictionary(e => e.Key, v => v.Select(z => z.Adapt<SetpointLogDto>()));
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task Add(Guid setpointKey, object newValue, Guid idUser, CancellationToken token)
|
||||
{
|
||||
var entity = new Setpoint()
|
||||
{
|
||||
Key = setpointKey,
|
||||
Value = newValue,
|
||||
IdUser = idUser,
|
||||
Created = DateTimeOffset.UtcNow
|
||||
};
|
||||
public async Task Add(Guid setpointKey, object newValue, Guid idUser, CancellationToken token)
|
||||
{
|
||||
var entity = new Setpoint()
|
||||
{
|
||||
Key = setpointKey,
|
||||
Value = newValue,
|
||||
IdUser = idUser,
|
||||
Created = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
await db.Set<Setpoint>().AddAsync(entity, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
}
|
||||
}
|
||||
await db.Set<Setpoint>().AddAsync(entity, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Mapster;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@ -6,7 +6,7 @@ using Persistence.Database.Entity;
|
||||
using Persistence.Models;
|
||||
using Persistence.Models.Requests;
|
||||
using Persistence.Repositories;
|
||||
using Persistence.Repository.Extensions;
|
||||
using UuidExtensions;
|
||||
|
||||
namespace Persistence.Repository.Repositories
|
||||
{
|
||||
@ -17,39 +17,39 @@ namespace Persistence.Repository.Repositories
|
||||
private readonly IMemoryCache memoryCache;
|
||||
private DbContext db;
|
||||
|
||||
public TechMessagesRepository(DbContext db, IMemoryCache memoryCache)
|
||||
{
|
||||
this.memoryCache = memoryCache;
|
||||
this.db = db;
|
||||
}
|
||||
public TechMessagesRepository(DbContext db, IMemoryCache memoryCache)
|
||||
{
|
||||
this.memoryCache = memoryCache;
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<TechMessage> GetQueryReadOnly() => db.Set<TechMessage>()
|
||||
.Include(e => e.System);
|
||||
protected virtual IQueryable<TechMessage> GetQueryReadOnly() => db.Set<TechMessage>()
|
||||
.Include(e => e.System);
|
||||
|
||||
public async Task<PaginationContainer<TechMessageDto>> GetPage(PaginationRequest request, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var count = await query.CountAsync(token);
|
||||
public async Task<PaginationContainer<TechMessageDto>> GetPage(PaginationRequest request, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var count = await query.CountAsync(token);
|
||||
|
||||
var sort = request.SortSettings != string.Empty
|
||||
? request.SortSettings
|
||||
: nameof(TechMessage.Timestamp);
|
||||
var entities = await query
|
||||
.SortBy(request.SortSettings!)
|
||||
.Skip(request.Skip)
|
||||
.Take(request.Take)
|
||||
.ToArrayAsync(token);
|
||||
var sort = request.SortSettings != string.Empty
|
||||
? request.SortSettings!
|
||||
: nameof(TechMessage.Timestamp);
|
||||
var entities = await query
|
||||
.SortBy(sort)
|
||||
.Skip(request.Skip)
|
||||
.Take(request.Take)
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var dto = new PaginationContainer<TechMessageDto>()
|
||||
{
|
||||
Skip = request.Skip,
|
||||
Take = request.Take,
|
||||
Count = count,
|
||||
Items = entities.Select(e => e.Adapt<TechMessageDto>())
|
||||
};
|
||||
var dto = new PaginationContainer<TechMessageDto>()
|
||||
{
|
||||
Skip = request.Skip,
|
||||
Take = request.Take,
|
||||
Count = count,
|
||||
Items = entities.Select(e => e.Adapt<TechMessageDto>())
|
||||
};
|
||||
|
||||
return dto;
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<Guid> systems, IEnumerable<int> categoryIds, CancellationToken token)
|
||||
{
|
||||
@ -64,22 +64,22 @@ namespace Persistence.Repository.Repositories
|
||||
})
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var entities = new List<MessagesStatisticDto>();
|
||||
foreach (var e in result)
|
||||
{
|
||||
var categories = e.Categories
|
||||
.GroupBy(g => g.CategoryId)
|
||||
.ToDictionary(c => c.Key, v => v.Count());
|
||||
var entity = new MessagesStatisticDto()
|
||||
{
|
||||
System = e.System,
|
||||
Categories = categories
|
||||
};
|
||||
entities.Add(entity);
|
||||
}
|
||||
var entities = new List<MessagesStatisticDto>();
|
||||
foreach (var e in result)
|
||||
{
|
||||
var categories = e.Categories
|
||||
.GroupBy(g => g.CategoryId)
|
||||
.ToDictionary(c => c.Key, v => v.Count());
|
||||
var entity = new MessagesStatisticDto()
|
||||
{
|
||||
System = e.System,
|
||||
Categories = categories
|
||||
};
|
||||
entities.Add(entity);
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(Guid systemId, IEnumerable<TechMessageDto> dtos, Guid userId, CancellationToken token)
|
||||
{
|
||||
@ -92,27 +92,27 @@ namespace Persistence.Repository.Repositories
|
||||
await CreateSystemIfNotExist(systemId, token);
|
||||
entity.SystemId = systemId;
|
||||
|
||||
entities.Add(entity);
|
||||
}
|
||||
entities.Add(entity);
|
||||
}
|
||||
|
||||
await db.Set<TechMessage>().AddRangeAsync(entities, token);
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
await db.Set<TechMessage>().AddRangeAsync(entities, token);
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => e.Timestamp >= dateBegin)
|
||||
.Take(take)
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities
|
||||
.Select(e => e.Adapt<TechMessageDto>());
|
||||
public async Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => e.Timestamp >= dateBegin)
|
||||
.Take(take)
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities
|
||||
.Select(e => e.Adapt<TechMessageDto>());
|
||||
|
||||
return dtos;
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DataSourceSystemDto>> GetSystems(CancellationToken token)
|
||||
{
|
||||
@ -146,8 +146,8 @@ namespace Persistence.Repository.Repositories
|
||||
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task CreateSystemIfNotExist(Guid systemId, CancellationToken token)
|
||||
{
|
||||
|
@ -1,6 +1,4 @@
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Persistence.Database.Model;
|
||||
using Persistence.Models;
|
||||
|
||||
@ -24,19 +22,19 @@ public class TimeSeriesDataCachedRepository<TEntity, TDto> : TimeSeriesDataRepos
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FirstByDate = firstDateItem;
|
||||
|
||||
var dtos = await base.GetLastAsync(CacheItemsCount, CancellationToken.None);
|
||||
dtos = dtos.OrderBy(d => d.Date);
|
||||
LastData.AddRange(dtos);
|
||||
dtos = dtos.OrderBy(d => d.Date);
|
||||
LastData.AddRange(dtos);
|
||||
}).Wait();
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset dateBegin, CancellationToken token)
|
||||
{
|
||||
|
||||
if (LastData.Count() == 0 || LastData[0].Date > dateBegin)
|
||||
if (LastData.Count == 0 || LastData[0].Date > dateBegin)
|
||||
{
|
||||
var dtos = await base.GetGtDate(dateBegin, token);
|
||||
return dtos;
|
||||
@ -53,7 +51,7 @@ public class TimeSeriesDataCachedRepository<TEntity, TDto> : TimeSeriesDataRepos
|
||||
var result = await base.AddRange(dtos, token);
|
||||
if (result > 0)
|
||||
{
|
||||
|
||||
|
||||
dtos = dtos.OrderBy(x => x.Date);
|
||||
|
||||
FirstByDate = dtos.First();
|
||||
@ -75,12 +73,12 @@ public class TimeSeriesDataCachedRepository<TEntity, TDto> : TimeSeriesDataRepos
|
||||
From = FirstByDate.Date,
|
||||
To = LastData[^1].Date
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<TDto>> GetResampledData(
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
int approxPointsCount = 1024,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ public class TimeSeriesDataRepository<TEntity, TDto> : ITimeSeriesDataRepository
|
||||
where TEntity : class, ITimestampedData, new()
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
{
|
||||
private DbContext db;
|
||||
private readonly DbContext db;
|
||||
|
||||
public TimeSeriesDataRepository(DbContext db)
|
||||
{
|
||||
@ -78,8 +78,8 @@ public class TimeSeriesDataRepository<TEntity, TDto> : ITimeSeriesDataRepository
|
||||
}
|
||||
|
||||
public async virtual Task<IEnumerable<TDto>> GetResampledData(
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
int approxPointsCount = 1024,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
|
@ -77,12 +77,12 @@ public class TimestampedSetRepository : ITimestampedSetRepository
|
||||
{
|
||||
var query = db.Set<TimestampedSet>()
|
||||
.GroupBy(entity => entity.IdDiscriminator)
|
||||
.Select(group => new
|
||||
{
|
||||
.Select(group => new
|
||||
{
|
||||
Min = group.Min(entity => entity.Timestamp),
|
||||
Max = group.Max(entity => entity.Timestamp),
|
||||
});
|
||||
|
||||
|
||||
var item = await query.FirstOrDefaultAsync(token);
|
||||
if (item is null)
|
||||
return null;
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
using Persistence.Models.Requests;
|
||||
|
||||
@ -50,13 +49,13 @@ public interface IChangeLogApi : ISyncWithDiscriminatorApi<DataWithWellDepthAndS
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> GetChangeLogForDate(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавить одну запись
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
/// <summary>
|
||||
/// Добавить одну запись
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,45 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Persistence.API;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для API, предназначенного для работы с элементами справочников
|
||||
/// </summary>
|
||||
public interface IDictionaryElementApi<TDto> where TDto : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить все данные справочника
|
||||
/// </summary>
|
||||
/// <param name="dictionaryKey">ключ справочника</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<IEnumerable<TDto>>> Get(Guid dictionaryKey, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавить элемент в справочник
|
||||
/// </summary>
|
||||
/// <param name="dictionaryKey">ключ справочника</param>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<Guid>> Add(Guid dictionaryKey, TDto dto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Изменить одну запись
|
||||
/// </summary>
|
||||
/// <param name="dictionaryKey">ключ справочника</param>
|
||||
/// <param name="dictionaryElementKey">ключ элемента в справочнике</param>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<Guid>> Update(Guid dictionaryKey, Guid dictionaryElementKey, TDto dto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить одну запись
|
||||
/// </summary>
|
||||
/// <param name="dictionaryKey">ключ справочника</param>
|
||||
/// <param name="dictionaryElementKey">ключ элемента в справочнике</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<int>> Delete(Guid dictionaryKey, Guid dictionaryElementKey, CancellationToken token);
|
||||
}
|
@ -33,12 +33,12 @@ public interface ISetpointApi : ISyncApi<SetpointLogDto>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Метод сохранения уставки
|
||||
/// </summary>
|
||||
/// <param name="setpointKey">ключ уставки</param>
|
||||
/// <param name="newValue">значение</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Метод сохранения уставки
|
||||
/// </summary>
|
||||
/// <param name="setpointKey">ключ уставки</param>
|
||||
/// <param name="newValue">значение</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token);
|
||||
}
|
||||
|
@ -8,21 +8,21 @@ namespace Persistence.API;
|
||||
/// </summary>
|
||||
public interface ISyncWithDiscriminatorApi<TDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take">количество записей</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<IEnumerable<TDto>>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take = 24 * 60 * 60, CancellationToken token = default);
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take">количество записей</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<IEnumerable<TDto>>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take = 24 * 60 * 60, CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token);
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
using Persistence.Models.Requests;
|
||||
|
||||
namespace Persistence.API;
|
||||
|
||||
/// Интерфейс для API, предназначенного для работы с табличными данными
|
||||
public interface ITableDataApi<TDto, TRequest>
|
||||
where TDto : class, new()
|
||||
where TRequest : PaginationRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить страницу списка объектов
|
||||
/// </summary>
|
||||
/// <param name="request">параметры фильтрации</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<PaginationContainer<TDto>>> GetPage(TRequest request, CancellationToken token);
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
|
||||
namespace Persistence.API;
|
||||
|
||||
@ -16,9 +15,9 @@ public interface ITimeSeriesBaseDataApi<TDto>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> GetResampledData(
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
int approxPointsCount = 1024,
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
int approxPointsCount = 1024,
|
||||
CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,10 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Persistence.API;
|
||||
|
||||
|
@ -8,23 +8,23 @@ namespace Persistence.API;
|
||||
/// </summary>
|
||||
public interface IWitsDataApi : ISyncWithDiscriminatorApi<WitsDataDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateFrom"></param>
|
||||
/// <param name="dateTo"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<IEnumerable<WitsDataDto>>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateFrom"></param>
|
||||
/// <param name="dateTo"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<IEnumerable<WitsDataDto>>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token);
|
||||
}
|
||||
|
@ -1,16 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Persistence;
|
||||
public static class EFExtensions
|
||||
{
|
||||
struct TypeAcessor
|
||||
struct TypeAccessor
|
||||
{
|
||||
public LambdaExpression KeySelector { get; set; }
|
||||
public MethodInfo OrderBy { get; set; }
|
||||
@ -25,7 +20,7 @@ public static class EFExtensions
|
||||
private static readonly MethodInfo methodThenBy = GetExtOrderMethod("ThenBy");
|
||||
|
||||
private static readonly MethodInfo methodThenByDescending = GetExtOrderMethod("ThenByDescending");
|
||||
private static ConcurrentDictionary<Type, Dictionary<string, TypeAcessor>> TypePropSelectors { get; set; } = new();
|
||||
private static ConcurrentDictionary<Type, Dictionary<string, TypeAccessor>> TypePropSelectors { get; set; } = new();
|
||||
|
||||
private static MethodInfo GetExtOrderMethod(string methodName)
|
||||
=> typeof(System.Linq.Queryable)
|
||||
@ -35,17 +30,17 @@ public static class EFExtensions
|
||||
m.GetParameters().Length == 2 &&
|
||||
m.GetParameters()[1].ParameterType.IsAssignableTo(typeof(LambdaExpression)))
|
||||
.Single();
|
||||
private static Dictionary<string, TypeAcessor> MakeTypeAcessors(Type type)
|
||||
private static Dictionary<string, TypeAccessor> MakeTypeAccessors(Type type)
|
||||
{
|
||||
var propContainer = new Dictionary<string, TypeAcessor>();
|
||||
var propContainer = new Dictionary<string, TypeAccessor>();
|
||||
var properties = type.GetProperties();
|
||||
foreach (var propertyInfo in properties)
|
||||
{
|
||||
var name = propertyInfo.Name.ToLower();
|
||||
ParameterExpression arg = Expression.Parameter(type, "x");
|
||||
MemberExpression property = Expression.Property(arg, propertyInfo.Name);
|
||||
var selector = Expression.Lambda(property, new ParameterExpression[] { arg });
|
||||
var typeAccessor = new TypeAcessor
|
||||
var selector = Expression.Lambda(property, [arg]);
|
||||
var typeAccessor = new TypeAccessor
|
||||
{
|
||||
KeySelector = selector,
|
||||
OrderBy = methodOrderBy.MakeGenericMethod(type, propertyInfo.PropertyType),
|
||||
@ -99,16 +94,16 @@ public static class EFExtensions
|
||||
string propertyName,
|
||||
bool isDesc)
|
||||
{
|
||||
var typePropSelector = TypePropSelectors.GetOrAdd(typeof(TSource), MakeTypeAcessors);
|
||||
var propertyNamelower = propertyName.ToLower();
|
||||
var typeAccessor = typePropSelector[propertyNamelower];
|
||||
var typePropSelector = TypePropSelectors.GetOrAdd(typeof(TSource), MakeTypeAccessors);
|
||||
var propertyNameLower = propertyName.ToLower();
|
||||
var typeAccessor = typePropSelector[propertyNameLower];
|
||||
|
||||
var genericMethod = isDesc
|
||||
? typeAccessor.OrderByDescending
|
||||
: typeAccessor.OrderBy;
|
||||
|
||||
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
||||
.Invoke(genericMethod, new object[] { query, typeAccessor.KeySelector })!;
|
||||
.Invoke(genericMethod, [query, typeAccessor.KeySelector])!;
|
||||
return newQuery;
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
/// </summary>
|
||||
public class AuthUser
|
||||
{
|
||||
public required string Username { get; set; }
|
||||
public required string Password { get; set; }
|
||||
public required string ClientId { get; set; }
|
||||
public required string GrantType { get; set; }
|
||||
public required string Username { get; set; }
|
||||
public required string Password { get; set; }
|
||||
public required string ClientId { get; set; }
|
||||
public required string GrantType { get; set; }
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
using System.Text;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Text;
|
||||
|
||||
namespace Persistence.Models.Configurations
|
||||
{
|
||||
public static class JwtParams
|
||||
{
|
||||
private static readonly string KeyValue = "супер секретный ключ для шифрования";
|
||||
public static SymmetricSecurityKey SecurityKey
|
||||
{
|
||||
get { return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(KeyValue)); }
|
||||
}
|
||||
public static class JwtParams
|
||||
{
|
||||
private static readonly string KeyValue = "супер секретный ключ для шифрования";
|
||||
public static SymmetricSecurityKey SecurityKey
|
||||
{
|
||||
get { return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(KeyValue)); }
|
||||
}
|
||||
|
||||
public static readonly string Issuer = "a";
|
||||
public static readonly string Issuer = "a";
|
||||
|
||||
public static readonly string Audience = "a";
|
||||
}
|
||||
public static readonly string Audience = "a";
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace Persistence.Models.Configurations
|
||||
{
|
||||
public class JwtToken
|
||||
{
|
||||
[JsonPropertyName("access_token")]
|
||||
public required string AccessToken { get; set; }
|
||||
}
|
||||
public class JwtToken
|
||||
{
|
||||
[JsonPropertyName("access_token")]
|
||||
public required string AccessToken { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ namespace Persistence.Models.Configurations;
|
||||
/// </summary>
|
||||
public class WitsInfo
|
||||
{
|
||||
public int RecordId { get; set; }
|
||||
public int RecordId { get; set; }
|
||||
|
||||
public int ItemId { get; set; }
|
||||
public int ItemId { get; set; }
|
||||
|
||||
public WitsType ValueType { get; set; }
|
||||
public WitsType ValueType { get; set; }
|
||||
}
|
@ -1,7 +1,4 @@
|
||||
using Persistence.Models;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Persistence.Repository.Data;
|
||||
namespace Persistence.Models;
|
||||
public class DataSaubDto : ITimeSeriesAbstractDto
|
||||
{
|
||||
public DateTimeOffset Date { get; set; } = DateTimeOffset.UtcNow;
|
@ -1,22 +1,22 @@
|
||||
namespace Persistence.Models;
|
||||
namespace Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Модель системы
|
||||
/// </summary>
|
||||
public class DataSourceSystemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Ключ
|
||||
/// </summary>
|
||||
public Guid SystemId { get; set; }
|
||||
/// <summary>
|
||||
/// Ключ
|
||||
/// </summary>
|
||||
public Guid SystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Наименование
|
||||
/// </summary>
|
||||
public required string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Описание
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
/// <summary>
|
||||
/// Описание
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
}
|
||||
|
@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Persistence.Models;
|
||||
namespace Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Dto для хранения записей, содержащих начальную и конечную глубину забоя, а также секцию
|
||||
|
@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Persistence.Models;
|
||||
namespace Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Диапазон дат
|
||||
|
@ -5,13 +5,13 @@
|
||||
/// </summary>
|
||||
public class MessagesStatisticDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Система бурения
|
||||
/// </summary>
|
||||
public required string System { get; set; }
|
||||
/// <summary>
|
||||
/// Система бурения
|
||||
/// </summary>
|
||||
public required string System { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Количество сообщений в соответствии с категориями важности
|
||||
/// </summary>
|
||||
public required Dictionary<int, int> Categories { get; set; }
|
||||
/// <summary>
|
||||
/// Количество сообщений в соответствии с категориями важности
|
||||
/// </summary>
|
||||
public required Dictionary<int, int> Categories { get; set; }
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public class PaginationContainer<T>
|
||||
/// </summary>
|
||||
public PaginationContainer()
|
||||
{
|
||||
Items = Enumerable.Empty<T>();
|
||||
Items = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -7,25 +7,25 @@ namespace Persistence.Models;
|
||||
/// </summary>
|
||||
public class ParameterDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Дискриминатор системы
|
||||
/// </summary>
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
/// <summary>
|
||||
/// Дискриминатор системы
|
||||
/// </summary>
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id параметра
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue, ErrorMessage = "Id параметра не может быть меньше 0")]
|
||||
public int ParameterId { get; set; }
|
||||
/// <summary>
|
||||
/// Id параметра
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue, ErrorMessage = "Id параметра не может быть меньше 0")]
|
||||
public int ParameterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Значение параметра в виде строки
|
||||
/// </summary>
|
||||
[StringLength(256, MinimumLength = 1, ErrorMessage = "Допустимая длина значения параметра от 1 до 256 символов")]
|
||||
public required string Value { get; set; }
|
||||
/// <summary>
|
||||
/// Значение параметра в виде строки
|
||||
/// </summary>
|
||||
[StringLength(256, MinimumLength = 1, ErrorMessage = "Допустимая длина значения параметра от 1 до 256 символов")]
|
||||
public required string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Временная отметка
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
/// <summary>
|
||||
/// Временная отметка
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ public class SetpointLogDto : SetpointValueDto
|
||||
/// Дата сохранения уставки
|
||||
/// </summary>
|
||||
public DateTimeOffset Created { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ключ пользователя
|
||||
/// </summary>
|
||||
|
@ -9,7 +9,7 @@ public class SetpointValueDto
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public Guid Key { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Значение уставки
|
||||
/// </summary>
|
||||
|
@ -1,29 +1,29 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Persistence.Models.Enumerations;
|
||||
|
||||
namespace Persistence.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель технологического сообщения
|
||||
/// </summary>
|
||||
public class TechMessageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id события
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid EventId { get; set; }
|
||||
/// <summary>
|
||||
/// Модель технологического сообщения
|
||||
/// </summary>
|
||||
public class TechMessageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id события
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid EventId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id Категории важности
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue, ErrorMessage = "Id Категории важности не может быть меньше 0")]
|
||||
public int CategoryId { get; set; }
|
||||
/// <summary>
|
||||
/// Id Категории важности
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue, ErrorMessage = "Id Категории важности не может быть меньше 0")]
|
||||
public int CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата возникновения
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
/// <summary>
|
||||
/// Дата возникновения
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Текст сообщения
|
||||
|
@ -1,63 +0,0 @@
|
||||
namespace Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Модель, описывающая пользователя
|
||||
/// </summary>
|
||||
public class UserDto
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// логин
|
||||
/// </summary>
|
||||
public string Login { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Имя
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Фамилия
|
||||
/// </summary>
|
||||
public string? Surname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Отчество
|
||||
/// </summary>
|
||||
public string? Patronymic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Email
|
||||
/// </summary>
|
||||
public string Email { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Phone
|
||||
/// </summary>
|
||||
public string? Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Должность
|
||||
/// </summary>
|
||||
public string? Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id компании
|
||||
/// </summary>
|
||||
public int IdCompany { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id состояния пользователя
|
||||
/// 0 - не активен,
|
||||
/// 1 - активен,
|
||||
/// 2 - заблокирован
|
||||
/// </summary>
|
||||
public short IdState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Получение отображаемого имени
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
}
|
@ -1,24 +1,22 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Persistence.Models;
|
||||
namespace Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Группа параметров Wits
|
||||
/// </summary>
|
||||
public class WitsDataDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Временная отметка
|
||||
/// </summary>
|
||||
public required DateTimeOffset Timestamped { get; set; }
|
||||
/// <summary>
|
||||
/// Временная отметка
|
||||
/// </summary>
|
||||
public required DateTimeOffset Timestamped { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дискриминатор системы
|
||||
/// </summary>
|
||||
public required Guid DiscriminatorId { get; set; }
|
||||
/// <summary>
|
||||
/// Дискриминатор системы
|
||||
/// </summary>
|
||||
public required Guid DiscriminatorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Параметры
|
||||
/// </summary>
|
||||
public IEnumerable<WitsValueDto> Values { get; set; } = [];
|
||||
/// <summary>
|
||||
/// Параметры
|
||||
/// </summary>
|
||||
public IEnumerable<WitsValueDto> Values { get; set; } = [];
|
||||
}
|
||||
|
@ -7,20 +7,20 @@ namespace Persistence.Models;
|
||||
/// </summary>
|
||||
public class WitsValueDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Wits - Record Number
|
||||
/// </summary>
|
||||
[Range(1, 100, ErrorMessage = "Значение \"Record Number\" обязано находиться в диапозоне от 1 до 100")]
|
||||
public int RecordId { get; set; }
|
||||
/// <summary>
|
||||
/// Wits - Record Number
|
||||
/// </summary>
|
||||
[Range(1, 100, ErrorMessage = "Значение \"Record Number\" обязано находиться в диапозоне от 1 до 100")]
|
||||
public int RecordId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Wits - Record Item
|
||||
/// </summary>
|
||||
[Range(1, 100, ErrorMessage = "Значение \"Wits Record Item\" обязано находиться в диапозоне от 1 до 100")]
|
||||
public int ItemId { get; set; }
|
||||
/// <summary>
|
||||
/// Wits - Record Item
|
||||
/// </summary>
|
||||
[Range(1, 100, ErrorMessage = "Значение \"Wits Record Item\" обязано находиться в диапозоне от 1 до 100")]
|
||||
public int ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Значение параметра
|
||||
/// </summary>
|
||||
public required object Value { get; set; }
|
||||
/// <summary>
|
||||
/// Значение параметра
|
||||
/// </summary>
|
||||
public required object Value { get; set; }
|
||||
}
|
||||
|
@ -3,41 +3,41 @@
|
||||
namespace Persistence.Repositories;
|
||||
public interface IParameterRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ParameterDto>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ParameterDto>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateFrom"></param>
|
||||
/// <param name="dateTo"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="ratio"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ParameterDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, int? ratio, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateFrom"></param>
|
||||
/// <param name="dateTo"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="ratio"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ParameterDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, int? ratio, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="witsIds"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(IEnumerable<ParameterDto> dtos, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="witsIds"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(IEnumerable<ParameterDto> dtos, CancellationToken token);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Persistence.Models;
|
||||
|
||||
namespace Persistence.Repositories;
|
||||
@ -16,14 +15,14 @@ public interface ISetpointRepository
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить историю изменений значений уставок
|
||||
@ -33,31 +32,31 @@ public interface ISetpointRepository
|
||||
/// <returns></returns>
|
||||
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Метод сохранения уставки
|
||||
/// </summary>
|
||||
/// <param name="setpointKey">ключ операции</param>
|
||||
/// <param name="idUser">ключ пользователя</param>
|
||||
/// <param name="newValue">значение</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
/// to do
|
||||
/// id User учесть в соответствующем методе репозитория
|
||||
Task Add(Guid setpointKey, object newValue, Guid idUser, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Метод сохранения уставки
|
||||
/// </summary>
|
||||
/// <param name="setpointKey">ключ операции</param>
|
||||
/// <param name="idUser">ключ пользователя</param>
|
||||
/// <param name="newValue">значение</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
/// to do
|
||||
/// id User учесть в соответствующем методе репозитория
|
||||
Task Add(Guid setpointKey, object newValue, Guid idUser, CancellationToken token);
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
using Persistence.Models.Requests;
|
||||
|
||||
namespace Persistence.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс по работе с табличными данными
|
||||
/// </summary>
|
||||
public interface ITableDataRepository<TDto, TRequest>
|
||||
where TDto : class, new()
|
||||
where TRequest : PaginationRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить страницу списка объектов
|
||||
/// </summary>
|
||||
/// <param name="request">параметры фильтрации</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TDto>> Get(TRequest request, CancellationToken token);
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
using Persistence.Models;
|
||||
|
||||
namespace Persistence.Repositories;
|
||||
namespace Persistence.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс по работе с прореженными данными
|
||||
@ -15,8 +13,8 @@ public interface ITimeSeriesBaseRepository<TDto>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TDto>> GetResampledData(
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
int approxPointsCount = 1024,
|
||||
CancellationToken token = default);
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
namespace Persistence.Services.Interfaces;
|
||||
|
||||
public interface ITimeSeriesDataObserverService
|
||||
{
|
||||
}
|
@ -7,40 +7,40 @@ namespace Persistence.Services.Interfaces;
|
||||
/// </summary>
|
||||
public interface IWitsDataService
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить набор параметров для построения графика
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить набор параметров для построения графика
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WitsDataDto>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateFrom"></param>
|
||||
/// <param name="dateTo"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WitsDataDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo, int approxPointsCount, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateFrom"></param>
|
||||
/// <param name="dateTo"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WitsDataDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo, int approxPointsCount, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token);
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
namespace Persistence.Services.Interfaces;
|
||||
public abstract class TimeSeriesDataObserverService : ITimeSeriesDataObserverService
|
||||
{
|
||||
}
|
@ -1,174 +1,173 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Persistence.Models;
|
||||
using Persistence.Repositories;
|
||||
using Persistence.Services.Interfaces;
|
||||
using Persistence.Models;
|
||||
using Persistence.Models.Configurations;
|
||||
using Persistence.Models.Enumerations;
|
||||
using Persistence.Repositories;
|
||||
using Persistence.Services.Interfaces;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Persistence.Services;
|
||||
public class WitsDataService : IWitsDataService
|
||||
{
|
||||
private readonly IParameterRepository witsDataRepository;
|
||||
private readonly IParameterRepository witsDataRepository;
|
||||
|
||||
private readonly WitsInfo[] witsInfo;
|
||||
private readonly WitsInfo[] witsInfo;
|
||||
|
||||
private const int multiplier = 1000;
|
||||
private const string witsConfigPath = "Persistence.Services.Config.WitsConfig.json";
|
||||
private const int multiplier = 1000;
|
||||
private const string witsConfigPath = "Persistence.Services.Config.WitsConfig.json";
|
||||
|
||||
public WitsDataService(IParameterRepository witsDataRepository)
|
||||
{
|
||||
this.witsDataRepository = witsDataRepository;
|
||||
public WitsDataService(IParameterRepository witsDataRepository)
|
||||
{
|
||||
this.witsDataRepository = witsDataRepository;
|
||||
|
||||
this.witsInfo = GetWitsInfo();
|
||||
}
|
||||
this.witsInfo = GetWitsInfo();
|
||||
}
|
||||
|
||||
public Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = witsDataRepository.GetDatesRangeAsync(idDiscriminator, token);
|
||||
public Task<DatesRangeDto> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = witsDataRepository.GetDatesRangeAsync(idDiscriminator, token);
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WitsDataDto>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var dtos = await witsDataRepository.GetPart(idDiscriminator, dateBegin, take, token);
|
||||
|
||||
var result = AdaptToWitsData(dtos);
|
||||
public async Task<IEnumerable<WitsDataDto>> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var dtos = await witsDataRepository.GetPart(idDiscriminator, dateBegin, take, token);
|
||||
|
||||
return result;
|
||||
}
|
||||
var result = AdaptToWitsData(dtos);
|
||||
|
||||
public async Task<IEnumerable<WitsDataDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, CancellationToken token)
|
||||
{
|
||||
var intervalSec = (dateTo - dateFrom).TotalSeconds;
|
||||
return result;
|
||||
}
|
||||
|
||||
int? ratio = null;
|
||||
if (intervalSec > 2 * approxPointsCount)
|
||||
{
|
||||
ratio = (int) intervalSec / approxPointsCount;
|
||||
}
|
||||
public async Task<IEnumerable<WitsDataDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo,
|
||||
int approxPointsCount, CancellationToken token)
|
||||
{
|
||||
var intervalSec = (dateTo - dateFrom).TotalSeconds;
|
||||
|
||||
var dtos = await witsDataRepository.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointsCount, ratio, token);
|
||||
int? ratio = null;
|
||||
if (intervalSec > 2 * approxPointsCount)
|
||||
{
|
||||
ratio = (int)intervalSec / approxPointsCount;
|
||||
}
|
||||
|
||||
var result = AdaptToWitsData(dtos);
|
||||
var dtos = await witsDataRepository.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointsCount, ratio, token);
|
||||
|
||||
return result;
|
||||
}
|
||||
var result = AdaptToWitsData(dtos);
|
||||
|
||||
public async Task<int> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token)
|
||||
{
|
||||
var parameterDtos = dtos.SelectMany(e => e.Values.Select(t => new ParameterDto()
|
||||
{
|
||||
DiscriminatorId = e.DiscriminatorId,
|
||||
ParameterId = EncodeId(t.RecordId, t.ItemId),
|
||||
Value = t.Value.ToString()!,
|
||||
Timestamp = e.Timestamped
|
||||
}));
|
||||
var result = await witsDataRepository.AddRange(parameterDtos, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
public async Task<int> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token)
|
||||
{
|
||||
var parameterDtos = dtos.SelectMany(e => e.Values.Select(t => new ParameterDto()
|
||||
{
|
||||
DiscriminatorId = e.DiscriminatorId,
|
||||
ParameterId = EncodeId(t.RecordId, t.ItemId),
|
||||
Value = t.Value.ToString()!,
|
||||
Timestamp = e.Timestamped
|
||||
}));
|
||||
var result = await witsDataRepository.AddRange(parameterDtos, token);
|
||||
|
||||
private int EncodeId(int recordId, int itemId)
|
||||
{
|
||||
var resultId = multiplier * recordId + itemId;
|
||||
return resultId;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int DecodeRecordId(int id)
|
||||
{
|
||||
var resultId = id / multiplier;
|
||||
private int EncodeId(int recordId, int itemId)
|
||||
{
|
||||
var resultId = multiplier * recordId + itemId;
|
||||
return resultId;
|
||||
}
|
||||
|
||||
return resultId;
|
||||
}
|
||||
private int DecodeRecordId(int id)
|
||||
{
|
||||
var resultId = id / multiplier;
|
||||
|
||||
private int DecodeItemId(int id)
|
||||
{
|
||||
var resultId = id % multiplier;
|
||||
return resultId;
|
||||
}
|
||||
|
||||
return resultId;
|
||||
}
|
||||
private int DecodeItemId(int id)
|
||||
{
|
||||
var resultId = id % multiplier;
|
||||
|
||||
private IEnumerable<WitsDataDto> AdaptToWitsData(IEnumerable<ParameterDto> dtos)
|
||||
{
|
||||
var result = new List<WitsDataDto>();
|
||||
var witsGroup = dtos
|
||||
.GroupBy(e => new { e.DiscriminatorId, e.Timestamp });
|
||||
foreach (var witsInGroup in witsGroup)
|
||||
{
|
||||
var witsDataDto = new WitsDataDto()
|
||||
{
|
||||
DiscriminatorId = witsInGroup.Key.DiscriminatorId,
|
||||
Timestamped = witsInGroup.Key.Timestamp
|
||||
};
|
||||
return resultId;
|
||||
}
|
||||
|
||||
witsDataDto.Values = witsInGroup.Select(e =>
|
||||
{
|
||||
var recordId = DecodeRecordId(e.ParameterId);
|
||||
var itemId = DecodeItemId(e.ParameterId);
|
||||
private IEnumerable<WitsDataDto> AdaptToWitsData(IEnumerable<ParameterDto> dtos)
|
||||
{
|
||||
var result = new List<WitsDataDto>();
|
||||
var witsGroup = dtos
|
||||
.GroupBy(e => new { e.DiscriminatorId, e.Timestamp });
|
||||
foreach (var witsInGroup in witsGroup)
|
||||
{
|
||||
var witsDataDto = new WitsDataDto()
|
||||
{
|
||||
DiscriminatorId = witsInGroup.Key.DiscriminatorId,
|
||||
Timestamped = witsInGroup.Key.Timestamp
|
||||
};
|
||||
|
||||
return new WitsValueDto()
|
||||
{
|
||||
RecordId = recordId,
|
||||
ItemId = itemId,
|
||||
Value = ConvertValue(recordId, itemId, e.Value)
|
||||
};
|
||||
});
|
||||
witsDataDto.Values = witsInGroup.Select(e =>
|
||||
{
|
||||
var recordId = DecodeRecordId(e.ParameterId);
|
||||
var itemId = DecodeItemId(e.ParameterId);
|
||||
|
||||
result.Add(witsDataDto);
|
||||
}
|
||||
return new WitsValueDto()
|
||||
{
|
||||
RecordId = recordId,
|
||||
ItemId = itemId,
|
||||
Value = ConvertValue(recordId, itemId, e.Value)
|
||||
};
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
result.Add(witsDataDto);
|
||||
}
|
||||
|
||||
private object ConvertValue(int recordId, int itemId, string value)
|
||||
{
|
||||
var witsType = witsInfo.FirstOrDefault(e => e.ItemId == itemId
|
||||
&& e.RecordId == recordId)?.ValueType;
|
||||
return result;
|
||||
}
|
||||
|
||||
switch(witsType)
|
||||
{
|
||||
default:
|
||||
{
|
||||
return value;
|
||||
}
|
||||
case WitsType.S:
|
||||
{
|
||||
var result = Int16.Parse(value);
|
||||
private object ConvertValue(int recordId, int itemId, string value)
|
||||
{
|
||||
var witsType = witsInfo.FirstOrDefault(e => e.ItemId == itemId
|
||||
&& e.RecordId == recordId)?.ValueType;
|
||||
|
||||
return result;
|
||||
}
|
||||
case WitsType.L:
|
||||
{
|
||||
var result = Int32.Parse(value);
|
||||
switch (witsType)
|
||||
{
|
||||
default:
|
||||
{
|
||||
return value;
|
||||
}
|
||||
case WitsType.S:
|
||||
{
|
||||
var result = Int16.Parse(value);
|
||||
|
||||
return result;
|
||||
}
|
||||
case WitsType.F:
|
||||
{
|
||||
var result = float.Parse(value, CultureInfo.InvariantCulture);
|
||||
return result;
|
||||
}
|
||||
case WitsType.L:
|
||||
{
|
||||
var result = Int32.Parse(value);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case WitsType.F:
|
||||
{
|
||||
var result = float.Parse(value, CultureInfo.InvariantCulture);
|
||||
|
||||
private WitsInfo[] GetWitsInfo()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream(witsConfigPath);
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
|
||||
},
|
||||
};
|
||||
var records = JsonSerializer.Deserialize<WitsInfo[]>(stream!, options) ?? [];
|
||||
return records;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private WitsInfo[] GetWitsInfo()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream(witsConfigPath);
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
|
||||
},
|
||||
};
|
||||
var records = JsonSerializer.Deserialize<WitsInfo[]>(stream!, options) ?? [];
|
||||
return records;
|
||||
}
|
||||
}
|
||||
|
78
exclusion.dic
Normal file
78
exclusion.dic
Normal file
@ -0,0 +1,78 @@
|
||||
appsettings
|
||||
autohold
|
||||
Autostart
|
||||
dd
|
||||
dtos
|
||||
HH
|
||||
Impl
|
||||
MM
|
||||
mmss
|
||||
modbus
|
||||
noload
|
||||
Saub
|
||||
Toolface
|
||||
yyyy
|
||||
Автоудержание
|
||||
макрооперации
|
||||
Макрооперация
|
||||
расхаживаний
|
||||
расхаживания
|
||||
Соотв
|
||||
Noload
|
||||
updatables
|
||||
штропа
|
||||
страгивания
|
||||
updatables
|
||||
MM
|
||||
dd
|
||||
HH
|
||||
mmss
|
||||
sqlite
|
||||
Serializer
|
||||
Auth
|
||||
Saub
|
||||
lightgray
|
||||
appsettings
|
||||
AutoScale
|
||||
Hmmss
|
||||
pinger
|
||||
Desc
|
||||
qwertyuiopasdfghjklzxcvbnm
|
||||
Deserialize
|
||||
Deserializer
|
||||
Deserializers
|
||||
Impl
|
||||
Protobuf
|
||||
сериализацию
|
||||
param
|
||||
tcpclient
|
||||
tcpserver
|
||||
tcplistener
|
||||
serialport
|
||||
bigendianunicode
|
||||
Middlewares
|
||||
Referer
|
||||
бекапов
|
||||
Encoderless
|
||||
Безэнкодерный
|
||||
безэнкодерного
|
||||
энкодеру
|
||||
автоудержания
|
||||
дифф
|
||||
энкодера
|
||||
Коэфф
|
||||
Миним
|
||||
Проворот
|
||||
вспом
|
||||
Extrem
|
||||
выкл
|
||||
minidisplay
|
||||
oauth
|
||||
sbin
|
||||
прога
|
||||
yyyyMMdd_HHmmssfff
|
||||
Serializers
|
||||
keycloak
|
||||
Params
|
||||
Mapster
|
||||
dest
|
Loading…
Reference in New Issue
Block a user