- Editorconfig
- Файл со словами-исключениями в spellchecker
This commit is contained in:
parent
6f93c331a2
commit
47820ba32a
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
|
@ -1,8 +1,8 @@
|
|||||||
using System.Net;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Repositories;
|
using Persistence.Repositories;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace Persistence.API.Controllers;
|
namespace Persistence.API.Controllers;
|
||||||
|
|
||||||
@ -14,99 +14,98 @@ namespace Persistence.API.Controllers;
|
|||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class SetpointController : ControllerBase, ISetpointApi
|
public class SetpointController : ControllerBase, ISetpointApi
|
||||||
{
|
{
|
||||||
private readonly ISetpointRepository setpointRepository;
|
private readonly ISetpointRepository setpointRepository;
|
||||||
|
|
||||||
public SetpointController(ISetpointRepository setpointRepository)
|
public SetpointController(ISetpointRepository setpointRepository)
|
||||||
{
|
{
|
||||||
this.setpointRepository = setpointRepository;
|
this.setpointRepository = setpointRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить актуальные значения уставок
|
/// Получить актуальные значения уставок
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKeys"></param>
|
/// <param name="setpointKeys"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("current")]
|
[HttpGet("current")]
|
||||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await setpointRepository.GetCurrent(setpointKeys, token);
|
var result = await setpointRepository.GetCurrent(setpointKeys, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить значения уставок за определенный момент времени
|
/// Получить значения уставок за определенный момент времени
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKeys"></param>
|
/// <param name="setpointKeys"></param>
|
||||||
/// <param name="historyMoment"></param>
|
/// <param name="historyMoment"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("history")]
|
[HttpGet("history")]
|
||||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory([FromQuery] IEnumerable<Guid> setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory([FromQuery] IEnumerable<Guid> setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
|
var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить историю изменений значений уставок
|
/// Получить историю изменений значений уставок
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKeys"></param>
|
/// <param name="setpointKeys"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("log")]
|
[HttpGet("log")]
|
||||||
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await setpointRepository.GetLog(setpointKeys, token);
|
var result = await setpointRepository.GetLog(setpointKeys, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("range")]
|
[HttpGet("range")]
|
||||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await setpointRepository.GetDatesRangeAsync(token);
|
var result = await setpointRepository.GetDatesRangeAsync(token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("part")]
|
[HttpGet("part")]
|
||||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await setpointRepository.GetPart(dateBegin, take, token);
|
var result = await setpointRepository.GetPart(dateBegin, take, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сохранить уставку
|
/// Сохранить уставку
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKey"></param>
|
/// <param name="setpointKey"></param>
|
||||||
/// <param name="newValue"></param>
|
/// <param name="newValue"></param>
|
||||||
/// <param name="idUser"></param>
|
/// <param name="token"></param>
|
||||||
/// <param name="token"></param>
|
/// <returns></returns>
|
||||||
/// <returns></returns>
|
[HttpPost]
|
||||||
[HttpPost]
|
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
public async Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token)
|
||||||
public async Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token)
|
{
|
||||||
{
|
var userId = User.GetUserId<Guid>();
|
||||||
var userId = User.GetUserId<Guid>();
|
await setpointRepository.Add(setpointKey, newValue, userId, token);
|
||||||
await setpointRepository.Add(setpointKey, newValue, userId, token);
|
|
||||||
|
|
||||||
return CreatedAtAction(nameof(Add), true);
|
return CreatedAtAction(nameof(Add), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
using System.Net;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Repositories;
|
using Persistence.Repositories;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace Persistence.API.Controllers;
|
namespace Persistence.API.Controllers;
|
||||||
|
|
||||||
@ -14,115 +14,115 @@ namespace Persistence.API.Controllers;
|
|||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class TechMessagesController : ControllerBase
|
public class TechMessagesController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ITechMessagesRepository techMessagesRepository;
|
private readonly ITechMessagesRepository techMessagesRepository;
|
||||||
private static readonly Dictionary<int, string> categories = new Dictionary<int, string>()
|
private static readonly Dictionary<int, string> categories = new Dictionary<int, string>()
|
||||||
{
|
{
|
||||||
{ 0, "System" },
|
{ 0, "System" },
|
||||||
{ 1, "Авария" },
|
{ 1, "Авария" },
|
||||||
{ 2, "Предупреждение" },
|
{ 2, "Предупреждение" },
|
||||||
{ 3, "Инфо" },
|
{ 3, "Инфо" },
|
||||||
{ 4, "Прочее" }
|
{ 4, "Прочее" }
|
||||||
};
|
};
|
||||||
|
|
||||||
public TechMessagesController(ITechMessagesRepository techMessagesRepository)
|
public TechMessagesController(ITechMessagesRepository techMessagesRepository)
|
||||||
{
|
{
|
||||||
this.techMessagesRepository = techMessagesRepository;
|
this.techMessagesRepository = techMessagesRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить список технологических сообщений в виде страницы
|
/// Получить список технологических сообщений в виде страницы
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ActionResult<PaginationContainer<TechMessageDto>>> GetPage([FromQuery] RequestDto request, CancellationToken token)
|
public async Task<ActionResult<PaginationContainer<TechMessageDto>>> GetPage([FromQuery] RequestDto request, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.GetPage(request, token);
|
var result = await techMessagesRepository.GetPage(request, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить статистику по системам
|
/// Получить статистику по системам
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="autoDrillingSystem"></param>
|
/// <param name="autoDrillingSystem"></param>
|
||||||
/// <param name="categoryIds"></param>
|
/// <param name="categoryIds"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("statistics")]
|
[HttpGet("statistics")]
|
||||||
public async Task<ActionResult<IEnumerable<MessagesStatisticDto>>> GetStatistics([FromQuery] IEnumerable<string> autoDrillingSystem, [FromQuery] IEnumerable<int> categoryIds, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<MessagesStatisticDto>>> GetStatistics([FromQuery] IEnumerable<string> autoDrillingSystem, [FromQuery] IEnumerable<int> categoryIds, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.GetStatistics(autoDrillingSystem, categoryIds, token);
|
var result = await techMessagesRepository.GetStatistics(autoDrillingSystem, categoryIds, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить список всех систем
|
/// Получить список всех систем
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("systems")]
|
[HttpGet("systems")]
|
||||||
public async Task<ActionResult<Dictionary<string, int>>> GetSystems(CancellationToken token)
|
public async Task<ActionResult<Dictionary<string, int>>> GetSystems(CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.GetSystems(token);
|
var result = await techMessagesRepository.GetSystems(token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("range")]
|
[HttpGet("range")]
|
||||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.GetDatesRangeAsync(token);
|
var result = await techMessagesRepository.GetDatesRangeAsync(token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("part")]
|
[HttpGet("part")]
|
||||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await techMessagesRepository.GetPart(dateBegin, take, token);
|
var result = await techMessagesRepository.GetPart(dateBegin, take, token);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавить новые технологические сообщения
|
/// Добавить новые технологические сообщения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||||
public async Task<IActionResult> AddRange([FromBody] IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
public async Task<IActionResult> AddRange([FromBody] IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
||||||
{
|
{
|
||||||
var userId = User.GetUserId<Guid>();
|
var userId = User.GetUserId<Guid>();
|
||||||
|
|
||||||
var result = await techMessagesRepository.AddRange(dtos, userId, token);
|
var result = await techMessagesRepository.AddRange(dtos, userId, token);
|
||||||
|
|
||||||
return CreatedAtAction(nameof(AddRange), result);
|
return CreatedAtAction(nameof(AddRange), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить словарь категорий
|
/// Получить словарь категорий
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("categories")]
|
[HttpGet("categories")]
|
||||||
public ActionResult<Dictionary<int, string>> GetImportantCategories()
|
public ActionResult<Dictionary<int, string>> GetImportantCategories()
|
||||||
{
|
{
|
||||||
return Ok(categories);
|
return Ok(categories);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,20 +11,20 @@ namespace Persistence.API.Controllers;
|
|||||||
public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDto>
|
public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDto>
|
||||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||||
{
|
{
|
||||||
private ITimeSeriesDataRepository<TDto> timeSeriesDataRepository;
|
private readonly ITimeSeriesDataRepository<TDto> timeSeriesDataRepository;
|
||||||
|
|
||||||
public TimeSeriesController(ITimeSeriesDataRepository<TDto> timeSeriesDataRepository)
|
public TimeSeriesController(ITimeSeriesDataRepository<TDto> timeSeriesDataRepository)
|
||||||
{
|
{
|
||||||
this.timeSeriesDataRepository = timeSeriesDataRepository;
|
this.timeSeriesDataRepository = timeSeriesDataRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить список объектов, удовлетворяющий диапазону дат
|
/// Получить список объектов, удовлетворяющий диапазону дат
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<IActionResult> Get(DateTimeOffset dateBegin, CancellationToken token)
|
public async Task<IActionResult> Get(DateTimeOffset dateBegin, CancellationToken token)
|
||||||
{
|
{
|
||||||
@ -32,40 +32,40 @@ public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDt
|
|||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить диапазон дат, для которых есть данные в репозиторие
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("datesRange")]
|
[HttpGet("datesRange")]
|
||||||
public async Task<IActionResult> GetDatesRange(CancellationToken token)
|
public async Task<IActionResult> GetDatesRange(CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await timeSeriesDataRepository.GetDatesRange(token);
|
var result = await timeSeriesDataRepository.GetDatesRange(token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
|
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="intervalSec"></param>
|
/// <param name="intervalSec"></param>
|
||||||
/// <param name="approxPointsCount"></param>
|
/// <param name="approxPointsCount"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("resampled")]
|
[HttpGet("resampled")]
|
||||||
public async Task<IActionResult> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
|
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);
|
var result = await timeSeriesDataRepository.GetResampledData(dateBegin, intervalSec, approxPointsCount, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавить записи
|
/// Добавить записи
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
public async Task<IActionResult> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await timeSeriesDataRepository.AddRange(dtos, token);
|
var result = await timeSeriesDataRepository.AddRange(dtos, token);
|
||||||
|
@ -13,7 +13,7 @@ namespace Persistence.API.Controllers;
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/[controller]/{idDiscriminator}")]
|
[Route("api/[controller]/{idDiscriminator}")]
|
||||||
public class TimestampedSetController : ControllerBase
|
public class TimestampedSetController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ITimestampedSetRepository repository;
|
private readonly ITimestampedSetRepository repository;
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ public class TimestampedSetController : ControllerBase
|
|||||||
/// <returns>кол-во затронутых записей</returns>
|
/// <returns>кол-во затронутых записей</returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
[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);
|
var result = await repository.AddRange(idDiscriminator, sets, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@ -50,7 +50,7 @@ public class TimestampedSetController : ControllerBase
|
|||||||
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
[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);
|
var result = await repository.Get(idDiscriminator, geTimestamp, columnNames, skip, take, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@ -66,7 +66,7 @@ public class TimestampedSetController : ControllerBase
|
|||||||
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||||
[HttpGet("last")]
|
[HttpGet("last")]
|
||||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
[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);
|
var result = await repository.GetLast(idDiscriminator, columnNames, take, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
using System.Reflection;
|
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
@ -9,17 +7,19 @@ using Persistence.Database.Entity;
|
|||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Models.Configurations;
|
using Persistence.Models.Configurations;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
public static class DependencyInjection
|
public static class DependencyInjection
|
||||||
{
|
{
|
||||||
public static void MapsterSetup()
|
public static void MapsterSetup()
|
||||||
{
|
{
|
||||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||||
.ForType<TechMessageDto, TechMessage>()
|
.ForType<TechMessageDto, TechMessage>()
|
||||||
.Ignore(dest => dest.System, dest => dest.SystemId);
|
.Ignore(dest => dest.System, dest => dest.SystemId);
|
||||||
}
|
}
|
||||||
public static void AddSwagger(this IServiceCollection services, IConfiguration configuration)
|
public static void AddSwagger(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddSwaggerGen(c =>
|
services.AddSwaggerGen(c =>
|
||||||
@ -28,12 +28,12 @@ public static class DependencyInjection
|
|||||||
c.MapType<DateOnly>(() => new OpenApiSchema { Type = "string", Format = "date" });
|
c.MapType<DateOnly>(() => new OpenApiSchema { Type = "string", Format = "date" });
|
||||||
c.MapType<JsonValue>(() => new OpenApiSchema
|
c.MapType<JsonValue>(() => new OpenApiSchema
|
||||||
{
|
{
|
||||||
AnyOf = new OpenApiSchema[]
|
AnyOf =
|
||||||
{
|
[
|
||||||
new OpenApiSchema {Type = "string", Format = "string" },
|
new() {Type = "string", Format = "string" },
|
||||||
new OpenApiSchema {Type = "number", Format = "int32" },
|
new() {Type = "number", Format = "int32" },
|
||||||
new OpenApiSchema {Type = "number", Format = "float" },
|
new() {Type = "number", Format = "float" },
|
||||||
}
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
c.CustomOperationIds(e =>
|
c.CustomOperationIds(e =>
|
||||||
@ -43,162 +43,163 @@ public static class DependencyInjection
|
|||||||
|
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Persistence web api", Version = "v1" });
|
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Persistence web api", Version = "v1" });
|
||||||
|
|
||||||
var needUseKeyCloak = configuration.GetSection("NeedUseKeyCloak").Get<bool>();
|
var needUseKeyCloak = configuration.GetSection("NeedUseKeyCloak").Get<bool>();
|
||||||
if (needUseKeyCloak)
|
if (needUseKeyCloak)
|
||||||
c.AddKeycloackSecurity(configuration);
|
c.AddKeycloakSecurity(configuration);
|
||||||
else c.AddDefaultSecurity(configuration);
|
else c.AddDefaultSecurity();
|
||||||
|
|
||||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||||
var includeControllerXmlComment = true;
|
var includeControllerXmlComment = true;
|
||||||
c.IncludeXmlComments(xmlPath, includeControllerXmlComment);
|
c.IncludeXmlComments(xmlPath, includeControllerXmlComment);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Authentication
|
#region Authentication
|
||||||
public static void AddJWTAuthentication(this IServiceCollection services, IConfiguration configuration)
|
public static void AddJWTAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
var needUseKeyCloak = configuration
|
var needUseKeyCloak = configuration
|
||||||
.GetSection("NeedUseKeyCloak")
|
.GetSection("NeedUseKeyCloak")
|
||||||
.Get<bool>();
|
.Get<bool>();
|
||||||
if (needUseKeyCloak)
|
if (needUseKeyCloak)
|
||||||
services.AddKeyCloakAuthentication(configuration);
|
services.AddKeyCloakAuthentication(configuration);
|
||||||
else services.AddDefaultAuthentication(configuration);
|
else services.AddDefaultAuthentication(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddKeyCloakAuthentication(this IServiceCollection services, IConfiguration configuration)
|
private static void AddKeyCloakAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||||
.AddJwtBearer(options =>
|
.AddJwtBearer(options =>
|
||||||
{
|
{
|
||||||
options.RequireHttpsMetadata = false;
|
options.RequireHttpsMetadata = false;
|
||||||
options.Audience = configuration["Authentication:Audience"];
|
options.Audience = configuration["Authentication:Audience"];
|
||||||
options.MetadataAddress = configuration["Authentication:MetadataAddress"]!;
|
options.MetadataAddress = configuration["Authentication:MetadataAddress"]!;
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
options.TokenValidationParameters = new TokenValidationParameters
|
||||||
{
|
{
|
||||||
ValidIssuer = configuration["Authentication:ValidIssuer"],
|
ValidIssuer = configuration["Authentication:ValidIssuer"],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration)
|
private static void AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||||
.AddJwtBearer(options =>
|
.AddJwtBearer(options =>
|
||||||
{
|
{
|
||||||
options.RequireHttpsMetadata = false;
|
options.RequireHttpsMetadata = false;
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
options.TokenValidationParameters = new TokenValidationParameters
|
||||||
{
|
{
|
||||||
ValidateIssuer = true,
|
ValidateIssuer = true,
|
||||||
ValidIssuer = JwtParams.Issuer,
|
ValidIssuer = JwtParams.Issuer,
|
||||||
ValidateAudience = true,
|
ValidateAudience = true,
|
||||||
ValidAudience = JwtParams.Audience,
|
ValidAudience = JwtParams.Audience,
|
||||||
ValidateLifetime = true,
|
ValidateLifetime = true,
|
||||||
IssuerSigningKey = JwtParams.SecurityKey,
|
IssuerSigningKey = JwtParams.SecurityKey,
|
||||||
ValidateIssuerSigningKey = false
|
ValidateIssuerSigningKey = false
|
||||||
};
|
};
|
||||||
options.Events = new JwtBearerEvents
|
options.Events = new JwtBearerEvents
|
||||||
{
|
{
|
||||||
OnMessageReceived = context =>
|
OnMessageReceived = context =>
|
||||||
{
|
{
|
||||||
var accessToken = context.Request.Headers["Authorization"]
|
var accessToken = context.Request.Headers["Authorization"]
|
||||||
.ToString()
|
.ToString()
|
||||||
.Replace(JwtBearerDefaults.AuthenticationScheme, string.Empty)
|
.Replace(JwtBearerDefaults.AuthenticationScheme, string.Empty)
|
||||||
.Trim();
|
.Trim();
|
||||||
|
|
||||||
context.Token = accessToken;
|
context.Token = accessToken;
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
},
|
},
|
||||||
OnTokenValidated = context =>
|
OnTokenValidated = context =>
|
||||||
{
|
{
|
||||||
var username = context.Principal?.Claims
|
var username = context.Principal?.Claims
|
||||||
.FirstOrDefault(e => e.Type == "username")?.Value;
|
.FirstOrDefault(e => e.Type == "username")?.Value;
|
||||||
|
|
||||||
var password = context.Principal?.Claims
|
var password = context.Principal?.Claims
|
||||||
.FirstOrDefault(e => e.Type == "password")?.Value;
|
.FirstOrDefault(e => e.Type == "password")?.Value;
|
||||||
|
|
||||||
var keyCloakUser = configuration
|
var keyCloakUser = configuration
|
||||||
.GetSection(nameof(AuthUser))
|
.GetSection(nameof(AuthUser))
|
||||||
.Get<AuthUser>()!;
|
.Get<AuthUser>()!;
|
||||||
|
|
||||||
if (username != keyCloakUser.Username || password != keyCloakUser.Password)
|
if (username != keyCloakUser.Username || password != keyCloakUser.Password)
|
||||||
{
|
{
|
||||||
context.Fail("username or password did not match");
|
context.Fail("username or password did not match");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Security (Swagger)
|
#region Security (Swagger)
|
||||||
private static void AddKeycloackSecurity(this SwaggerGenOptions options, IConfiguration configuration)
|
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 12345abcdef'",
|
||||||
Name = "Authorization",
|
Name = "Authorization",
|
||||||
In = ParameterLocation.Header,
|
In = ParameterLocation.Header,
|
||||||
Type = SecuritySchemeType.OAuth2,
|
Type = SecuritySchemeType.OAuth2,
|
||||||
Flows = new OpenApiOAuthFlows
|
Flows = new OpenApiOAuthFlows
|
||||||
{
|
{
|
||||||
Implicit = new OpenApiOAuthFlow
|
Implicit = new OpenApiOAuthFlow
|
||||||
{
|
{
|
||||||
AuthorizationUrl = new Uri(configuration["Authentication:AuthorizationUrl"]),
|
|
||||||
}
|
AuthorizationUrl = new Uri(configuration["Authentication:AuthorizationUrl"]!),
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
new OpenApiSecurityScheme
|
new OpenApiSecurityScheme
|
||||||
{
|
{
|
||||||
Reference = new OpenApiReference
|
Reference = new OpenApiReference
|
||||||
{
|
{
|
||||||
Type = ReferenceType.SecurityScheme,
|
Type = ReferenceType.SecurityScheme,
|
||||||
Id = "Keycloack"
|
Id = "Keycloak"
|
||||||
},
|
},
|
||||||
Scheme = "Bearer",
|
Scheme = "Bearer",
|
||||||
Name = "Bearer",
|
Name = "Bearer",
|
||||||
In = ParameterLocation.Header,
|
In = ParameterLocation.Header,
|
||||||
},
|
},
|
||||||
new List<string>()
|
new List<string>()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddDefaultSecurity(this SwaggerGenOptions options, IConfiguration configuration)
|
private static void AddDefaultSecurity(this SwaggerGenOptions options)
|
||||||
{
|
{
|
||||||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
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 12345abcdef'",
|
||||||
Name = "Authorization",
|
Name = "Authorization",
|
||||||
In = ParameterLocation.Header,
|
In = ParameterLocation.Header,
|
||||||
Type = SecuritySchemeType.ApiKey,
|
Type = SecuritySchemeType.ApiKey,
|
||||||
Scheme = "Bearer",
|
Scheme = "Bearer",
|
||||||
});
|
});
|
||||||
|
|
||||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
new OpenApiSecurityScheme
|
new OpenApiSecurityScheme
|
||||||
{
|
{
|
||||||
Reference = new OpenApiReference
|
Reference = new OpenApiReference
|
||||||
{
|
{
|
||||||
Type = ReferenceType.SecurityScheme,
|
Type = ReferenceType.SecurityScheme,
|
||||||
Id = "Bearer"
|
Id = "Bearer"
|
||||||
},
|
},
|
||||||
Scheme = "oauth2",
|
Scheme = "oauth2",
|
||||||
Name = "Bearer",
|
Name = "Bearer",
|
||||||
In = ParameterLocation.Header,
|
In = ParameterLocation.Header,
|
||||||
},
|
},
|
||||||
new List<string>()
|
new List<string>()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
|
|
||||||
using Persistence.Models;
|
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
@ -18,5 +15,5 @@ public class Program
|
|||||||
.ConfigureWebHostDefaults(webBuilder =>
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Persistence.Repository;
|
using Persistence.Database.Model;
|
||||||
using Persistence.Database.Model;
|
|
||||||
using Persistence.Database.Postgres;
|
using Persistence.Database.Postgres;
|
||||||
|
using Persistence.Repository;
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
|
@ -8,23 +8,23 @@ namespace Persistence.Client.Clients;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISetpointClient
|
public interface ISetpointClient
|
||||||
{
|
{
|
||||||
private const string BaseRoute = "/api/setpoint";
|
private const string BaseRoute = "/api/setpoint";
|
||||||
|
|
||||||
[Get($"{BaseRoute}/current")]
|
[Get($"{BaseRoute}/current")]
|
||||||
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetCurrent([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetCurrent([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/history")]
|
|
||||||
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetHistory([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys, [Query] DateTimeOffset historyMoment);
|
|
||||||
|
|
||||||
[Get($"{BaseRoute}/log")]
|
[Get($"{BaseRoute}/history")]
|
||||||
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetHistory([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys, [Query] DateTimeOffset historyMoment);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/range")]
|
[Get($"{BaseRoute}/log")]
|
||||||
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/part")]
|
[Get($"{BaseRoute}/range")]
|
||||||
Task<IApiResponse<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
||||||
|
|
||||||
[Post($"{BaseRoute}/")]
|
[Get($"{BaseRoute}/part")]
|
||||||
Task<IApiResponse> Add(Guid setpointKey, object newValue);
|
Task<IApiResponse<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
|
|
||||||
|
[Post($"{BaseRoute}/")]
|
||||||
|
Task<IApiResponse> Add(Guid setpointKey, object newValue);
|
||||||
}
|
}
|
||||||
|
@ -3,29 +3,29 @@ using Refit;
|
|||||||
|
|
||||||
namespace Persistence.Client.Clients
|
namespace Persistence.Client.Clients
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс клиента для хранения технологических сообщений
|
/// Интерфейс клиента для хранения технологических сообщений
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITechMessagesClient
|
public interface ITechMessagesClient
|
||||||
{
|
{
|
||||||
private const string BaseRoute = "/api/techMessages";
|
private const string BaseRoute = "/api/techMessages";
|
||||||
|
|
||||||
[Get($"{BaseRoute}")]
|
[Get($"{BaseRoute}")]
|
||||||
Task<IApiResponse<PaginationContainer<TechMessageDto>>> GetPage([Query] RequestDto request, CancellationToken token);
|
Task<IApiResponse<PaginationContainer<TechMessageDto>>> GetPage([Query] RequestDto request, CancellationToken token);
|
||||||
|
|
||||||
[Post($"{BaseRoute}")]
|
[Post($"{BaseRoute}")]
|
||||||
Task<IApiResponse<int>> AddRange([Body] IEnumerable<TechMessageDto> dtos, CancellationToken token);
|
Task<IApiResponse<int>> AddRange([Body] IEnumerable<TechMessageDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/systems")]
|
[Get($"{BaseRoute}/systems")]
|
||||||
Task<IApiResponse<IEnumerable<string>>> GetSystems(CancellationToken token);
|
Task<IApiResponse<IEnumerable<string>>> GetSystems(CancellationToken token);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/range")]
|
[Get($"{BaseRoute}/range")]
|
||||||
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/part")]
|
[Get($"{BaseRoute}/part")]
|
||||||
Task<IApiResponse<IEnumerable<TechMessageDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
Task<IApiResponse<IEnumerable<TechMessageDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/statistics")]
|
[Get($"{BaseRoute}/statistics")]
|
||||||
Task<IApiResponse<IEnumerable<MessagesStatisticDto>>> GetStatistics([Query] string autoDrillingSystem, [Query] int categoryId, CancellationToken token);
|
Task<IApiResponse<IEnumerable<MessagesStatisticDto>>> GetStatistics([Query] string autoDrillingSystem, [Query] int categoryId, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public interface ITimeSeriesClient<TDto>
|
|||||||
|
|
||||||
[Get($"{BaseRoute}/resampled")]
|
[Get($"{BaseRoute}/resampled")]
|
||||||
Task<IApiResponse<IEnumerable<TDto>>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024);
|
Task<IApiResponse<IEnumerable<TDto>>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024);
|
||||||
|
|
||||||
[Get($"{BaseRoute}/datesRange")]
|
[Get($"{BaseRoute}/datesRange")]
|
||||||
Task<IApiResponse<DatesRangeDto?>> GetDatesRange();
|
Task<IApiResponse<DatesRangeDto?>> GetDatesRange();
|
||||||
}
|
}
|
||||||
|
@ -1,74 +1,74 @@
|
|||||||
using System.IdentityModel.Tokens.Jwt;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Text.Json;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Persistence.Models.Configurations;
|
using Persistence.Models.Configurations;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Persistence.Client.Helpers;
|
namespace Persistence.Client.Helpers;
|
||||||
public static class ApiTokenHelper
|
public static class ApiTokenHelper
|
||||||
{
|
{
|
||||||
public static void Authorize(this HttpClient httpClient, IConfiguration configuration)
|
public static void Authorize(this HttpClient httpClient, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
var authUser = configuration
|
var authUser = configuration
|
||||||
.GetSection(nameof(AuthUser))
|
.GetSection(nameof(AuthUser))
|
||||||
.Get<AuthUser>()!;
|
.Get<AuthUser>()!;
|
||||||
var needUseKeyCloak = configuration
|
var needUseKeyCloak = configuration
|
||||||
.GetSection("NeedUseKeyCloak")
|
.GetSection("NeedUseKeyCloak")
|
||||||
.Get<bool>()!;
|
.Get<bool>()!;
|
||||||
var keycloakGetTokenUrl = configuration.GetSection("KeycloakGetTokenUrl").Get<string>() ?? string.Empty;
|
var keycloakGetTokenUrl = configuration.GetSection("KeycloakGetTokenUrl").Get<string>() ?? string.Empty;
|
||||||
|
|
||||||
var jwtToken = needUseKeyCloak
|
var jwtToken = needUseKeyCloak
|
||||||
? authUser.CreateKeyCloakJwtToken(keycloakGetTokenUrl)
|
? authUser.CreateKeyCloakJwtToken(keycloakGetTokenUrl)
|
||||||
: authUser.CreateDefaultJwtToken();
|
: authUser.CreateDefaultJwtToken();
|
||||||
|
|
||||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateDefaultJwtToken(this AuthUser authUser)
|
private static string CreateDefaultJwtToken(this AuthUser authUser)
|
||||||
{
|
{
|
||||||
var nameIdetifier = Guid.NewGuid().ToString();
|
var nameIdentifier = Guid.NewGuid().ToString();
|
||||||
var claims = new List<Claim>()
|
var claims = new List<Claim>()
|
||||||
{
|
{
|
||||||
new(ClaimTypes.NameIdentifier, nameIdetifier),
|
new(ClaimTypes.NameIdentifier, nameIdentifier),
|
||||||
new("client_id", authUser.ClientId),
|
new("client_id", authUser.ClientId),
|
||||||
new("username", authUser.Username),
|
new("username", authUser.Username),
|
||||||
new("password", authUser.Password),
|
new("password", authUser.Password),
|
||||||
new("grant_type", authUser.GrantType)
|
new("grant_type", authUser.GrantType)
|
||||||
};
|
};
|
||||||
|
|
||||||
var tokenDescriptor = new SecurityTokenDescriptor
|
var tokenDescriptor = new SecurityTokenDescriptor
|
||||||
{
|
{
|
||||||
Issuer = JwtParams.Issuer,
|
Issuer = JwtParams.Issuer,
|
||||||
Audience = JwtParams.Audience,
|
Audience = JwtParams.Audience,
|
||||||
Subject = new ClaimsIdentity(claims),
|
Subject = new ClaimsIdentity(claims),
|
||||||
Expires = DateTime.UtcNow.AddHours(1),
|
Expires = DateTime.UtcNow.AddHours(1),
|
||||||
SigningCredentials = new SigningCredentials(JwtParams.SecurityKey, SecurityAlgorithms.HmacSha256Signature)
|
SigningCredentials = new SigningCredentials(JwtParams.SecurityKey, SecurityAlgorithms.HmacSha256Signature)
|
||||||
};
|
};
|
||||||
var tokenHandler = new JwtSecurityTokenHandler();
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||||
return tokenHandler.WriteToken(token);
|
return tokenHandler.WriteToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateKeyCloakJwtToken(this AuthUser authUser, string keycloakGetTokenUrl)
|
private static string CreateKeyCloakJwtToken(this AuthUser authUser, string keycloakGetTokenUrl)
|
||||||
{
|
{
|
||||||
var restClient = new RestClient();
|
var restClient = new RestClient();
|
||||||
|
|
||||||
var request = new RestRequest(keycloakGetTokenUrl, Method.Post);
|
var request = new RestRequest(keycloakGetTokenUrl, Method.Post);
|
||||||
request.AddParameter("username", authUser.Username);
|
request.AddParameter("username", authUser.Username);
|
||||||
request.AddParameter("password", authUser.Password);
|
request.AddParameter("password", authUser.Password);
|
||||||
request.AddParameter("client_id", authUser.ClientId);
|
request.AddParameter("client_id", authUser.ClientId);
|
||||||
request.AddParameter("grant_type", authUser.GrantType);
|
request.AddParameter("grant_type", authUser.GrantType);
|
||||||
|
|
||||||
var keyCloackResponse = restClient.Post(request);
|
var keycloakResponse = restClient.Post(request);
|
||||||
if (keyCloackResponse.IsSuccessful && !String.IsNullOrEmpty(keyCloackResponse.Content))
|
if (keycloakResponse.IsSuccessful && !String.IsNullOrEmpty(keycloakResponse.Content))
|
||||||
{
|
{
|
||||||
var token = JsonSerializer.Deserialize<JwtToken>(keyCloackResponse.Content)!;
|
var token = JsonSerializer.Deserialize<JwtToken>(keycloakResponse.Content)!;
|
||||||
return token.AccessToken;
|
return token.AccessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
return String.Empty;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
using System.Text.Json;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Persistence.Client.Helpers;
|
using Persistence.Client.Helpers;
|
||||||
using Refit;
|
using Refit;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Persistence.Client
|
namespace Persistence.Client
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Фабрика клиентов для доступа к Persistence - сервису
|
/// Фабрика клиентов для доступа к Persistence - сервису
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PersistenceClientFactory
|
public class PersistenceClientFactory
|
||||||
{
|
{
|
||||||
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
|
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
|
||||||
{
|
{
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
PropertyNameCaseInsensitive = true
|
PropertyNameCaseInsensitive = true
|
||||||
};
|
};
|
||||||
private static readonly RefitSettings RefitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions));
|
private static readonly RefitSettings RefitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions));
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IConfiguration configuration)
|
public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
this.httpClient = httpClientFactory.CreateClient();
|
this.httpClient = httpClientFactory.CreateClient();
|
||||||
|
|
||||||
httpClient.Authorize(configuration);
|
httpClient.Authorize(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetClient<T>()
|
public T GetClient<T>()
|
||||||
{
|
{
|
||||||
return RestService.For<T>(httpClient, RefitSettings);
|
return RestService.For<T>(httpClient, RefitSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Postgres;
|
namespace Persistence.Database.Postgres;
|
||||||
public static class EFExtensionsInitialization
|
public static class EFExtensionsInitialization
|
||||||
|
@ -1,23 +1,21 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Npgsql;
|
|
||||||
using Persistence.Database.Entity;
|
using Persistence.Database.Entity;
|
||||||
using System.Data.Common;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Model;
|
namespace Persistence.Database.Model;
|
||||||
public partial class PersistenceDbContext : DbContext
|
public partial class PersistenceDbContext : DbContext
|
||||||
{
|
{
|
||||||
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
||||||
|
|
||||||
public DbSet<Setpoint> Setpoint => Set<Setpoint>();
|
public DbSet<Setpoint> Setpoint => Set<Setpoint>();
|
||||||
|
|
||||||
public DbSet<TechMessage> TechMessage => Set<TechMessage>();
|
public DbSet<TechMessage> TechMessage => Set<TechMessage>();
|
||||||
|
|
||||||
public DbSet<TimestampedSet> TimestampedSets => Set<TimestampedSet>();
|
public DbSet<TimestampedSet> TimestampedSets => Set<TimestampedSet>();
|
||||||
|
|
||||||
public PersistenceDbContext()
|
public PersistenceDbContext()
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PersistenceDbContext(DbContextOptions<PersistenceDbContext> options)
|
public PersistenceDbContext(DbContextOptions<PersistenceDbContext> options)
|
||||||
@ -49,7 +47,7 @@ public partial class PersistenceDbContext : DbContext
|
|||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey(t => t.SystemId)
|
.HasForeignKey(t => t.SystemId)
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Persistence.Database;
|
namespace Persistence.Database;
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Persistence.Database.Model;
|
namespace Persistence.Database.Model;
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Entity;
|
namespace Persistence.Database.Entity;
|
||||||
public class DrillingSystem
|
public class DrillingSystem
|
||||||
{
|
{
|
||||||
[Key, Comment("Id системы автобурения")]
|
[Key, Comment("Id системы автобурения")]
|
||||||
public Guid SystemId { get; set; }
|
public Guid SystemId { get; set; }
|
||||||
|
|
||||||
[Required, Column(TypeName = "varchar(256)"), Comment("Наименование системы автобурения")]
|
[Required, Column(TypeName = "varchar(256)"), Comment("Наименование системы автобурения")]
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
|
|
||||||
[Comment("Описание системы автобурения")]
|
[Comment("Описание системы автобурения")]
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace Persistence.Database.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Model;
|
|
||||||
public interface ITimestampedData
|
public interface ITimestampedData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Persistence.Database.Model
|
namespace Persistence.Database.Model
|
||||||
{
|
{
|
||||||
[PrimaryKey(nameof(Key), nameof(Created))]
|
[PrimaryKey(nameof(Key), nameof(Created))]
|
||||||
public class Setpoint
|
public class Setpoint
|
||||||
{
|
{
|
||||||
[Comment("Ключ")]
|
[Comment("Ключ")]
|
||||||
public Guid Key { get; set; }
|
public Guid Key { get; set; }
|
||||||
|
|
||||||
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
|
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
|
||||||
public required object Value { get; set; }
|
public required object Value { get; set; }
|
||||||
|
|
||||||
[Comment("Дата создания уставки")]
|
[Comment("Дата создания уставки")]
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
|
|
||||||
[Comment("Id автора последнего изменения")]
|
[Comment("Id автора последнего изменения")]
|
||||||
public Guid IdUser { get; set; }
|
public Guid IdUser { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Entity
|
namespace Persistence.Database.Entity
|
||||||
{
|
{
|
||||||
public class TechMessage
|
public class TechMessage
|
||||||
{
|
{
|
||||||
[Key, Comment("Id события")]
|
[Key, Comment("Id события")]
|
||||||
public Guid EventId { get; set; }
|
public Guid EventId { get; set; }
|
||||||
|
|
||||||
[Comment("Id Категории важности")]
|
[Comment("Id Категории важности")]
|
||||||
public int CategoryId { get; set; }
|
public int CategoryId { get; set; }
|
||||||
|
|
||||||
[Comment("Дата возникновения")]
|
[Comment("Дата возникновения")]
|
||||||
public DateTimeOffset Timestamp { get; set; }
|
public DateTimeOffset Timestamp { get; set; }
|
||||||
|
|
||||||
[Comment("Глубина забоя")]
|
[Comment("Глубина забоя")]
|
||||||
public double? Depth { get; set; }
|
public double? Depth { get; set; }
|
||||||
|
|
||||||
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
|
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
|
||||||
public required string MessageText { get; set; }
|
public required string MessageText { get; set; }
|
||||||
|
|
||||||
[Required, Comment("Id системы автобурения, к которой относится сообщение")]
|
[Required, Comment("Id системы автобурения, к которой относится сообщение")]
|
||||||
public required Guid SystemId { get; set; }
|
public required Guid SystemId { get; set; }
|
||||||
|
|
||||||
[Required, ForeignKey(nameof(SystemId)), Comment("Система автобурения, к которой относится сообщение")]
|
[Required, ForeignKey(nameof(SystemId)), Comment("Система автобурения, к которой относится сообщение")]
|
||||||
public virtual required DrillingSystem System { get; set; }
|
public virtual required DrillingSystem System { get; set; }
|
||||||
|
|
||||||
[Comment("Id пользователя за пультом бурильщика")]
|
[Comment("Id пользователя за пультом бурильщика")]
|
||||||
public Guid UserId { get; set; }
|
public Guid UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,6 @@ namespace Persistence.Database.Entity;
|
|||||||
[Comment("Общая таблица данных временных рядов")]
|
[Comment("Общая таблица данных временных рядов")]
|
||||||
[PrimaryKey(nameof(IdDiscriminator), nameof(Timestamp))]
|
[PrimaryKey(nameof(IdDiscriminator), nameof(Timestamp))]
|
||||||
public record TimestampedSet(
|
public record TimestampedSet(
|
||||||
[property: Comment("Дискриминатор ссылка на тип сохраняемых данных")] Guid IdDiscriminator,
|
[property: Comment("Дискриминатор ссылка на тип сохраняемых данных")] Guid IdDiscriminator,
|
||||||
[property: Comment("Отметка времени, строго в UTC")] DateTimeOffset Timestamp,
|
[property: Comment("Отметка времени, строго в UTC")] DateTimeOffset Timestamp,
|
||||||
[property: Column(TypeName = "jsonb"), Comment("Набор сохраняемых данных")] IDictionary<string, object> Set);
|
[property: Column(TypeName = "jsonb"), Comment("Набор сохраняемых данных")] IDictionary<string, object> Set);
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Persistence.Database.Model;
|
using Persistence.Database.Model;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests;
|
namespace Persistence.IntegrationTests;
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
using Persistence.Client;
|
using Persistence.Database.Model;
|
||||||
using Persistence.Database.Model;
|
|
||||||
using Persistence.Repository.Data;
|
using Persistence.Repository.Data;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests.Controllers;
|
namespace Persistence.IntegrationTests.Controllers;
|
||||||
public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaub, DataSaubDto>
|
public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaub, DataSaubDto>
|
||||||
{
|
{
|
||||||
private readonly DataSaubDto dto = new DataSaubDto()
|
private readonly DataSaubDto dto = new()
|
||||||
{
|
{
|
||||||
AxialLoad = 1,
|
AxialLoad = 1,
|
||||||
BitDepth = 2,
|
BitDepth = 2,
|
||||||
@ -76,7 +75,7 @@ public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaub, Dat
|
|||||||
await GetDatesRangeSuccess(entity);
|
await GetDatesRangeSuccess(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetResampledData_returns_success()
|
public async Task GetResampledData_returns_success()
|
||||||
|
@ -1,241 +1,240 @@
|
|||||||
using System.Net;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Cache;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Persistence.Client;
|
using Persistence.Client;
|
||||||
using Persistence.Client.Clients;
|
using Persistence.Client.Clients;
|
||||||
using Persistence.Database.Model;
|
using Persistence.Database.Model;
|
||||||
|
using System.Net;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests.Controllers
|
namespace Persistence.IntegrationTests.Controllers
|
||||||
{
|
{
|
||||||
public class SetpointControllerTest : BaseIntegrationTest
|
public class SetpointControllerTest : BaseIntegrationTest
|
||||||
{
|
{
|
||||||
private ISetpointClient setpointClient;
|
private ISetpointClient setpointClient;
|
||||||
private class TestObject
|
private class TestObject
|
||||||
{
|
{
|
||||||
public string? value1 { get; set; }
|
public string? value1 { get; set; }
|
||||||
public int? value2 { get; set; }
|
public int? value2 { get; set; }
|
||||||
}
|
}
|
||||||
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
|
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||||
{
|
{
|
||||||
var scope = factory.Services.CreateScope();
|
var scope = factory.Services.CreateScope();
|
||||||
var persistenceClientFactory = scope.ServiceProvider
|
var persistenceClientFactory = scope.ServiceProvider
|
||||||
.GetRequiredService<PersistenceClientFactory>();
|
.GetRequiredService<PersistenceClientFactory>();
|
||||||
|
|
||||||
setpointClient = persistenceClientFactory.GetClient<ISetpointClient>();
|
setpointClient = persistenceClientFactory.GetClient<ISetpointClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetCurrent_returns_success()
|
public async Task GetCurrent_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var setpointKeys = new List<Guid>()
|
var setpointKeys = new List<Guid>()
|
||||||
{
|
{
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
Guid.NewGuid()
|
Guid.NewGuid()
|
||||||
};
|
};
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await setpointClient.GetCurrent(setpointKeys);
|
var response = await setpointClient.GetCurrent(setpointKeys);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Empty(response.Content);
|
Assert.Empty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetCurrent_AfterSave_returns_success()
|
public async Task GetCurrent_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var setpointKey = await Add();
|
var setpointKey = await Add();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await setpointClient.GetCurrent([setpointKey]);
|
var response = await setpointClient.GetCurrent([setpointKey]);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.NotEmpty(response.Content);
|
Assert.NotEmpty(response.Content);
|
||||||
Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
|
Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetHistory_returns_success()
|
public async Task GetHistory_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var setpointKeys = new List<Guid>()
|
var setpointKeys = new List<Guid>()
|
||||||
{
|
{
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
Guid.NewGuid()
|
Guid.NewGuid()
|
||||||
};
|
};
|
||||||
var historyMoment = DateTimeOffset.UtcNow;
|
var historyMoment = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await setpointClient.GetHistory(setpointKeys, historyMoment);
|
var response = await setpointClient.GetHistory(setpointKeys, historyMoment);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Empty(response.Content);
|
Assert.Empty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetHistory_AfterSave_returns_success()
|
public async Task GetHistory_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var setpointKey = await Add();
|
var setpointKey = await Add();
|
||||||
var historyMoment = DateTimeOffset.UtcNow;
|
var historyMoment = DateTimeOffset.UtcNow;
|
||||||
historyMoment = historyMoment.AddDays(1);
|
historyMoment = historyMoment.AddDays(1);
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await setpointClient.GetHistory([setpointKey], historyMoment);
|
var response = await setpointClient.GetHistory([setpointKey], historyMoment);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.NotEmpty(response.Content);
|
Assert.NotEmpty(response.Content);
|
||||||
Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
|
Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetLog_returns_success()
|
public async Task GetLog_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var setpointKeys = new List<Guid>()
|
var setpointKeys = new List<Guid>()
|
||||||
{
|
{
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
Guid.NewGuid()
|
Guid.NewGuid()
|
||||||
};
|
};
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await setpointClient.GetLog(setpointKeys);
|
var response = await setpointClient.GetLog(setpointKeys);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Empty(response.Content);
|
Assert.Empty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetLog_AfterSave_returns_success()
|
public async Task GetLog_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var setpointKey = await Add();
|
var setpointKey = await Add();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await setpointClient.GetLog([setpointKey]);
|
var response = await setpointClient.GetLog([setpointKey]);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.NotEmpty(response.Content);
|
Assert.NotEmpty(response.Content);
|
||||||
Assert.Equal(setpointKey, response.Content.FirstOrDefault().Key);
|
Assert.Equal(setpointKey, response.Content.FirstOrDefault().Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetDatesRange_returns_success()
|
public async Task GetDatesRange_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
dbContext.CleanupDbSet<Setpoint>();
|
dbContext.CleanupDbSet<Setpoint>();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await setpointClient.GetDatesRangeAsync(new CancellationToken());
|
var response = await setpointClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Equal(DateTimeOffset.MinValue, response.Content!.From);
|
Assert.Equal(DateTimeOffset.MinValue, response.Content!.From);
|
||||||
Assert.Equal(DateTimeOffset.MaxValue, response.Content!.To);
|
Assert.Equal(DateTimeOffset.MaxValue, response.Content!.To);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetDatesRange_AfterSave_returns_success()
|
public async Task GetDatesRange_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
dbContext.CleanupDbSet<Setpoint>();
|
dbContext.CleanupDbSet<Setpoint>();
|
||||||
|
|
||||||
await Add();
|
|
||||||
|
|
||||||
var dateBegin = DateTimeOffset.MinValue;
|
await Add();
|
||||||
var take = 1;
|
|
||||||
var part = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
|
||||||
|
|
||||||
//act
|
var dateBegin = DateTimeOffset.MinValue;
|
||||||
var response = await setpointClient.GetDatesRangeAsync(new CancellationToken());
|
var take = 1;
|
||||||
|
var part = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//act
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
var response = await setpointClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
Assert.NotNull(response.Content);
|
|
||||||
|
|
||||||
var expectedValue = part.Content!
|
//assert
|
||||||
.FirstOrDefault()!.Created
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
Assert.NotNull(response.Content);
|
||||||
var actualValueFrom = response.Content.From
|
|
||||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
|
||||||
Assert.Equal(expectedValue, actualValueFrom);
|
|
||||||
|
|
||||||
var actualValueTo = response.Content.To
|
var expectedValue = part.Content!
|
||||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
.FirstOrDefault()!.Created
|
||||||
Assert.Equal(expectedValue, actualValueTo);
|
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||||
}
|
var actualValueFrom = response.Content.From
|
||||||
|
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||||
|
Assert.Equal(expectedValue, actualValueFrom);
|
||||||
|
|
||||||
[Fact]
|
var actualValueTo = response.Content.To
|
||||||
public async Task GetPart_returns_success()
|
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||||
{
|
Assert.Equal(expectedValue, actualValueTo);
|
||||||
//arrange
|
}
|
||||||
var dateBegin = DateTimeOffset.UtcNow;
|
|
||||||
var take = 2;
|
|
||||||
|
|
||||||
//act
|
[Fact]
|
||||||
var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
public async Task GetPart_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
|
var take = 2;
|
||||||
|
|
||||||
//assert
|
//act
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
Assert.NotNull(response.Content);
|
|
||||||
Assert.Empty(response.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
//assert
|
||||||
public async Task GetPart_AfterSave_returns_success()
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
{
|
Assert.NotNull(response.Content);
|
||||||
//arrange
|
Assert.Empty(response.Content);
|
||||||
var dateBegin = DateTimeOffset.UtcNow;
|
}
|
||||||
var take = 1;
|
|
||||||
await Add();
|
|
||||||
|
|
||||||
//act
|
[Fact]
|
||||||
var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
public async Task GetPart_AfterSave_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
|
var take = 1;
|
||||||
|
await Add();
|
||||||
|
|
||||||
//assert
|
//act
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
Assert.NotNull(response.Content);
|
|
||||||
Assert.NotEmpty(response.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
//assert
|
||||||
public async Task Save_returns_success()
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
{
|
Assert.NotNull(response.Content);
|
||||||
await Add();
|
Assert.NotEmpty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Guid> Add()
|
[Fact]
|
||||||
{
|
public async Task Save_returns_success()
|
||||||
//arrange
|
{
|
||||||
var setpointKey = Guid.NewGuid();
|
await Add();
|
||||||
var setpointValue = new TestObject()
|
}
|
||||||
{
|
|
||||||
value1 = "1",
|
|
||||||
value2 = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
//act
|
private async Task<Guid> Add()
|
||||||
var response = await setpointClient.Add(setpointKey, setpointValue);
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKey = Guid.NewGuid();
|
||||||
|
var setpointValue = new TestObject()
|
||||||
|
{
|
||||||
|
value1 = "1",
|
||||||
|
value2 = 2
|
||||||
|
};
|
||||||
|
|
||||||
//assert
|
//act
|
||||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
var response = await setpointClient.Add(setpointKey, setpointValue);
|
||||||
|
|
||||||
return setpointKey;
|
//assert
|
||||||
}
|
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||||
}
|
|
||||||
|
return setpointKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,288 +1,288 @@
|
|||||||
using System.Net;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Persistence.Client;
|
using Persistence.Client;
|
||||||
using Persistence.Client.Clients;
|
using Persistence.Client.Clients;
|
||||||
using Persistence.Database.Entity;
|
using Persistence.Database.Entity;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
|
using System.Net;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests.Controllers
|
namespace Persistence.IntegrationTests.Controllers
|
||||||
{
|
{
|
||||||
public class TechMessagesControllerTest : BaseIntegrationTest
|
public class TechMessagesControllerTest : BaseIntegrationTest
|
||||||
{
|
{
|
||||||
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DrillingSystem).FullName}CacheKey";
|
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DrillingSystem).FullName}CacheKey";
|
||||||
private readonly ITechMessagesClient techMessagesClient;
|
private readonly ITechMessagesClient techMessagesClient;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
public TechMessagesControllerTest(WebAppFactoryFixture factory) : base(factory)
|
public TechMessagesControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||||
{
|
{
|
||||||
var scope = factory.Services.CreateScope();
|
var scope = factory.Services.CreateScope();
|
||||||
var persistenceClientFactory = scope.ServiceProvider
|
var persistenceClientFactory = scope.ServiceProvider
|
||||||
.GetRequiredService<PersistenceClientFactory>();
|
.GetRequiredService<PersistenceClientFactory>();
|
||||||
|
|
||||||
techMessagesClient = persistenceClientFactory.GetClient<ITechMessagesClient>();
|
techMessagesClient = persistenceClientFactory.GetClient<ITechMessagesClient>();
|
||||||
memoryCache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
|
memoryCache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetPage_returns_success()
|
public async Task GetPage_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
memoryCache.Remove(SystemCacheKey);
|
memoryCache.Remove(SystemCacheKey);
|
||||||
dbContext.CleanupDbSet<TechMessage>();
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
||||||
|
|
||||||
var requestDto = new RequestDto()
|
var requestDto = new RequestDto()
|
||||||
{
|
{
|
||||||
Skip = 1,
|
Skip = 1,
|
||||||
Take = 2,
|
Take = 2,
|
||||||
SortSettings = nameof(TechMessage.CategoryId)
|
SortSettings = nameof(TechMessage.CategoryId)
|
||||||
};
|
};
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetPage(requestDto, new CancellationToken());
|
var response = await techMessagesClient.GetPage(requestDto, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Empty(response.Content.Items);
|
Assert.Empty(response.Content.Items);
|
||||||
Assert.Equal(requestDto.Skip, response.Content.Skip);
|
Assert.Equal(requestDto.Skip, response.Content.Skip);
|
||||||
Assert.Equal(requestDto.Take, response.Content.Take);
|
Assert.Equal(requestDto.Take, response.Content.Take);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetPage_AfterSave_returns_success()
|
public async Task GetPage_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var dtos = await InsertRange();
|
var dtos = await InsertRange();
|
||||||
var dtosCount = dtos.Count();
|
var dtosCount = dtos.Count();
|
||||||
var requestDto = new RequestDto()
|
var requestDto = new RequestDto()
|
||||||
{
|
{
|
||||||
Skip = 0,
|
Skip = 0,
|
||||||
Take = 2,
|
Take = 2,
|
||||||
SortSettings = nameof(TechMessage.CategoryId)
|
SortSettings = nameof(TechMessage.CategoryId)
|
||||||
};
|
};
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetPage(requestDto, new CancellationToken());
|
var response = await techMessagesClient.GetPage(requestDto, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Equal(dtosCount, response.Content.Count);
|
Assert.Equal(dtosCount, response.Content.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task InsertRange_returns_success()
|
public async Task InsertRange_returns_success()
|
||||||
{
|
{
|
||||||
await InsertRange();
|
await InsertRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task InsertRange_returns_BadRequest()
|
public async Task InsertRange_returns_BadRequest()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var dtos = new List<TechMessageDto>()
|
var dtos = new List<TechMessageDto>()
|
||||||
{
|
{
|
||||||
new TechMessageDto()
|
new()
|
||||||
{
|
{
|
||||||
EventId = Guid.NewGuid(),
|
EventId = Guid.NewGuid(),
|
||||||
CategoryId = -1, // < 0
|
CategoryId = -1, // < 0
|
||||||
Timestamp = DateTimeOffset.UtcNow,
|
Timestamp = DateTimeOffset.UtcNow,
|
||||||
Depth = -1, // < 0
|
Depth = -1, // < 0
|
||||||
MessageText = string.Empty, // length < 0
|
MessageText = string.Empty, // length < 0
|
||||||
System = string.Concat(Enumerable.Repeat(nameof(TechMessageDto.System), 100)), // length > 256
|
System = string.Concat(Enumerable.Repeat(nameof(TechMessageDto.System), 100)), // length > 256
|
||||||
UserId = Guid.NewGuid()
|
UserId = Guid.NewGuid()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.AddRange(dtos, new CancellationToken());
|
var response = await techMessagesClient.AddRange(dtos, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetSystems_returns_success()
|
public async Task GetSystems_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
memoryCache.Remove(SystemCacheKey);
|
memoryCache.Remove(SystemCacheKey);
|
||||||
dbContext.CleanupDbSet<TechMessage>();
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetSystems(new CancellationToken());
|
var response = await techMessagesClient.GetSystems(new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Empty(response.Content);
|
Assert.Empty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetSystems_AfterSave_returns_success()
|
public async Task GetSystems_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var dtos = await InsertRange();
|
var dtos = await InsertRange();
|
||||||
var systems = dtos
|
var systems = dtos
|
||||||
.Select(e => e.System)
|
.Select(e => e.System)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetSystems(new CancellationToken());
|
var response = await techMessagesClient.GetSystems(new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
string?[]? content = response.Content?.ToArray();
|
string?[]? content = response.Content?.ToArray();
|
||||||
Assert.Equal(systems, content);
|
Assert.Equal(systems, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetStatistics_returns_success()
|
public async Task GetStatistics_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
memoryCache.Remove(SystemCacheKey);
|
memoryCache.Remove(SystemCacheKey);
|
||||||
dbContext.CleanupDbSet<TechMessage>();
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
|
||||||
|
|
||||||
var imortantId = 1;
|
var imortantId = 1;
|
||||||
var autoDrillingSystem = nameof(TechMessageDto.System);
|
var autoDrillingSystem = nameof(TechMessageDto.System);
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
|
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Empty(response.Content);
|
Assert.Empty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetStatistics_AfterSave_returns_success()
|
public async Task GetStatistics_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var imortantId = 0;
|
var imortantId = 0;
|
||||||
var autoDrillingSystem = nameof(TechMessageDto.System);
|
var autoDrillingSystem = nameof(TechMessageDto.System);
|
||||||
var dtos = await InsertRange();
|
var dtos = await InsertRange();
|
||||||
var filteredDtos = dtos.Where(e => e.CategoryId == imortantId && e.System == autoDrillingSystem);
|
var filteredDtos = dtos.Where(e => e.CategoryId == imortantId && e.System == autoDrillingSystem);
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
|
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
var categories = response.Content
|
var categories = response.Content
|
||||||
.FirstOrDefault()?.Categories
|
.FirstOrDefault()?.Categories
|
||||||
.FirstOrDefault(e => e.Key == 0).Value;
|
.FirstOrDefault(e => e.Key == 0).Value;
|
||||||
Assert.Equal(filteredDtos.Count(), categories);
|
Assert.Equal(filteredDtos.Count(), categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetDatesRange_returns_success()
|
public async Task GetDatesRange_returns_success()
|
||||||
{
|
{
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken());
|
var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
//Assert.Equal(DateTimeOffset.MinValue, response.Content?.From);
|
//Assert.Equal(DateTimeOffset.MinValue, response.Content?.From);
|
||||||
//Assert.Equal(DateTimeOffset.MaxValue, response.Content?.To);
|
//Assert.Equal(DateTimeOffset.MaxValue, response.Content?.To);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetDatesRange_AfterSave_returns_success()
|
public async Task GetDatesRange_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
await InsertRange();
|
await InsertRange();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken());
|
var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.NotNull(response.Content?.From);
|
Assert.NotNull(response.Content?.From);
|
||||||
Assert.NotNull(response.Content?.To);
|
Assert.NotNull(response.Content?.To);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetPart_returns_success()
|
public async Task GetPart_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var dateBegin = DateTimeOffset.UtcNow;
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
var take = 2;
|
var take = 2;
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken());
|
var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Empty(response.Content);
|
Assert.Empty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetPart_AfterSave_returns_success()
|
public async Task GetPart_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
var dateBegin = DateTimeOffset.UtcNow;
|
var dateBegin = DateTimeOffset.UtcNow;
|
||||||
var take = 1;
|
var take = 1;
|
||||||
await InsertRange();
|
await InsertRange();
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken());
|
var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.NotEmpty(response.Content);
|
Assert.NotEmpty(response.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<TechMessageDto>> InsertRange()
|
private async Task<IEnumerable<TechMessageDto>> InsertRange()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
memoryCache.Remove(SystemCacheKey);
|
memoryCache.Remove(SystemCacheKey);
|
||||||
dbContext.CleanupDbSet<TechMessage>();
|
dbContext.CleanupDbSet<TechMessage>();
|
||||||
dbContext.CleanupDbSet<DrillingSystem>();
|
dbContext.CleanupDbSet<DrillingSystem>();
|
||||||
|
|
||||||
var dtos = new List<TechMessageDto>()
|
var dtos = new List<TechMessageDto>()
|
||||||
{
|
{
|
||||||
new TechMessageDto()
|
new()
|
||||||
{
|
{
|
||||||
EventId = Guid.NewGuid(),
|
EventId = Guid.NewGuid(),
|
||||||
CategoryId = 1,
|
CategoryId = 1,
|
||||||
Timestamp = DateTimeOffset.UtcNow,
|
Timestamp = DateTimeOffset.UtcNow,
|
||||||
Depth = 1.11,
|
Depth = 1.11,
|
||||||
MessageText = nameof(TechMessageDto.MessageText),
|
MessageText = nameof(TechMessageDto.MessageText),
|
||||||
System = nameof(TechMessageDto.System).ToLower(),
|
System = nameof(TechMessageDto.System).ToLower(),
|
||||||
UserId = Guid.NewGuid()
|
UserId = Guid.NewGuid()
|
||||||
},
|
},
|
||||||
new TechMessageDto()
|
new()
|
||||||
{
|
{
|
||||||
EventId = Guid.NewGuid(),
|
EventId = Guid.NewGuid(),
|
||||||
CategoryId = 2,
|
CategoryId = 2,
|
||||||
Timestamp = DateTimeOffset.UtcNow,
|
Timestamp = DateTimeOffset.UtcNow,
|
||||||
Depth = 2.22,
|
Depth = 2.22,
|
||||||
MessageText = nameof(TechMessageDto.MessageText),
|
MessageText = nameof(TechMessageDto.MessageText),
|
||||||
System = nameof(TechMessageDto.System).ToLower(),
|
System = nameof(TechMessageDto.System).ToLower(),
|
||||||
UserId = Guid.NewGuid()
|
UserId = Guid.NewGuid()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await techMessagesClient.AddRange(dtos, new CancellationToken());
|
var response = await techMessagesClient.AddRange(dtos, new CancellationToken());
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||||
Assert.Equal(dtos.Count, response.Content);
|
Assert.Equal(dtos.Count, response.Content);
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
using System.Net;
|
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Persistence.Client;
|
using Persistence.Client;
|
||||||
using Persistence.Client.Clients;
|
using Persistence.Client.Clients;
|
||||||
using Persistence.Database.Model;
|
using Persistence.Database.Model;
|
||||||
|
using System.Net;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests.Controllers;
|
namespace Persistence.IntegrationTests.Controllers;
|
||||||
|
|
||||||
public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrationTest
|
public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrationTest
|
||||||
where TEntity : class, ITimestampedData, new()
|
where TEntity : class, ITimestampedData, new()
|
||||||
where TDto : class, new()
|
where TDto : class, new()
|
||||||
@ -17,11 +18,11 @@ public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrat
|
|||||||
{
|
{
|
||||||
dbContext.CleanupDbSet<TEntity>();
|
dbContext.CleanupDbSet<TEntity>();
|
||||||
|
|
||||||
var scope = factory.Services.CreateScope();
|
var scope = factory.Services.CreateScope();
|
||||||
var persistenceClientFactory = scope.ServiceProvider
|
var persistenceClientFactory = scope.ServiceProvider
|
||||||
.GetRequiredService<PersistenceClientFactory>();
|
.GetRequiredService<PersistenceClientFactory>();
|
||||||
|
|
||||||
timeSeriesClient = persistenceClientFactory.GetClient<ITimeSeriesClient<TDto>>();
|
timeSeriesClient = persistenceClientFactory.GetClient<ITimeSeriesClient<TDto>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InsertRangeSuccess(TDto dto)
|
public async Task InsertRangeSuccess(TDto dto)
|
||||||
@ -104,7 +105,7 @@ public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrat
|
|||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
|
|
||||||
var ratio = entities.Count() / approxPointsCount;
|
var ratio = entities.Count / approxPointsCount;
|
||||||
if (ratio > 1)
|
if (ratio > 1)
|
||||||
{
|
{
|
||||||
var expectedResampledCount = entities
|
var expectedResampledCount = entities
|
||||||
|
@ -39,7 +39,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
|||||||
Guid idDiscriminator = Guid.NewGuid();
|
Guid idDiscriminator = Guid.NewGuid();
|
||||||
int count = 10;
|
int count = 10;
|
||||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||||
var insertResponse = await client.AddRange(idDiscriminator, testSets);
|
await client.AddRange(idDiscriminator, testSets);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue);
|
var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue);
|
||||||
@ -58,7 +58,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
|||||||
Guid idDiscriminator = Guid.NewGuid();
|
Guid idDiscriminator = Guid.NewGuid();
|
||||||
int count = 10;
|
int count = 10;
|
||||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||||
var insertResponse = await client.AddRange(idDiscriminator, testSets);
|
await client.AddRange(idDiscriminator, testSets);
|
||||||
string[] props = ["A"];
|
string[] props = ["A"];
|
||||||
|
|
||||||
// act
|
// act
|
||||||
@ -69,12 +69,12 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
|||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
var items = response.Content!;
|
var items = response.Content!;
|
||||||
Assert.Equal(count, items.Count());
|
Assert.Equal(count, items.Count());
|
||||||
foreach ( var item in items )
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
Assert.Single(item.Set);
|
Assert.Single(item.Set);
|
||||||
var kv = item.Set.First();
|
var kv = item.Set.First();
|
||||||
Assert.Equal("A", kv.Key);
|
Assert.Equal("A", kv.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -85,7 +85,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
|||||||
int count = 10;
|
int count = 10;
|
||||||
var dateMin = DateTimeOffset.Now;
|
var dateMin = DateTimeOffset.Now;
|
||||||
var dateMax = DateTimeOffset.Now.AddSeconds(count);
|
var dateMax = DateTimeOffset.Now.AddSeconds(count);
|
||||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
||||||
var insertResponse = await client.AddRange(idDiscriminator, testSets);
|
var insertResponse = await client.AddRange(idDiscriminator, testSets);
|
||||||
var tail = testSets.OrderBy(t => t.Timestamp).Skip(count / 2).Take(int.MaxValue);
|
var tail = testSets.OrderBy(t => t.Timestamp).Skip(count / 2).Take(int.MaxValue);
|
||||||
var geDate = tail.First().Timestamp;
|
var geDate = tail.First().Timestamp;
|
||||||
@ -152,7 +152,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
|||||||
Guid idDiscriminator = Guid.NewGuid();
|
Guid idDiscriminator = Guid.NewGuid();
|
||||||
int count = 10;
|
int count = 10;
|
||||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||||
var insertResponse = await client.AddRange(idDiscriminator, testSets);
|
await client.AddRange(idDiscriminator, testSets);
|
||||||
var expectedCount = 8;
|
var expectedCount = 8;
|
||||||
|
|
||||||
// act
|
// act
|
||||||
@ -172,7 +172,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
|
|||||||
Guid idDiscriminator = Guid.NewGuid();
|
Guid idDiscriminator = Guid.NewGuid();
|
||||||
int count = 10;
|
int count = 10;
|
||||||
var dateMin = DateTimeOffset.Now;
|
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)));
|
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
||||||
var insertResponse = await client.AddRange(idDiscriminator, testSets);
|
var insertResponse = await client.AddRange(idDiscriminator, testSets);
|
||||||
var tolerance = TimeSpan.FromSeconds(1);
|
var tolerance = TimeSpan.FromSeconds(1);
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace Persistence.IntegrationTests;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests;
|
|
||||||
public class DbConnection
|
public class DbConnection
|
||||||
{
|
{
|
||||||
public string Host { get; set; } = null!;
|
public string Host { get; set; } = null!;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Persistence.Database.Model;
|
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests;
|
namespace Persistence.IntegrationTests;
|
||||||
public static class EFCoreExtensions
|
public static class EFCoreExtensions
|
||||||
|
@ -4,11 +4,11 @@ namespace Persistence.IntegrationTests.Extensions;
|
|||||||
|
|
||||||
public static class EFCoreExtensions
|
public static class EFCoreExtensions
|
||||||
{
|
{
|
||||||
public static void CleanupDbSet<T>(this PersistenceDbContext dbContext)
|
public static void CleanupDbSet<T>(this PersistenceDbContext dbContext)
|
||||||
where T : class
|
where T : class
|
||||||
{
|
{
|
||||||
var dbset = dbContext.Set<T>();
|
var dbSet = dbContext.Set<T>();
|
||||||
dbset.RemoveRange(dbset);
|
dbSet.RemoveRange(dbSet);
|
||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
namespace Persistence.IntegrationTests
|
namespace Persistence.IntegrationTests
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Фабрика HTTP клиентов для интеграционных тестов
|
/// Фабрика HTTP клиентов для интеграционных тестов
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TestHttpClientFactory : IHttpClientFactory
|
public class TestHttpClientFactory : IHttpClientFactory
|
||||||
{
|
{
|
||||||
private readonly WebAppFactoryFixture factory;
|
private readonly WebAppFactoryFixture factory;
|
||||||
|
|
||||||
public TestHttpClientFactory(WebAppFactoryFixture factory)
|
public TestHttpClientFactory(WebAppFactoryFixture factory)
|
||||||
{
|
{
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
}
|
}
|
||||||
public HttpClient CreateClient(string name)
|
public HttpClient CreateClient(string name)
|
||||||
{
|
{
|
||||||
return factory.CreateClient();
|
return factory.CreateClient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Persistence.API;
|
using Persistence.API;
|
||||||
using Persistence.Database;
|
|
||||||
using Persistence.Client;
|
using Persistence.Client;
|
||||||
using Persistence.Database.Model;
|
using Persistence.Database.Model;
|
||||||
using Persistence.Database.Postgres;
|
using Persistence.Database.Postgres;
|
||||||
@ -17,32 +16,32 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
|||||||
private string connectionString = string.Empty;
|
private string connectionString = string.Empty;
|
||||||
|
|
||||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||||
{
|
{
|
||||||
builder.ConfigureAppConfiguration((hostingContext, config) =>
|
builder.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
{
|
{
|
||||||
config.AddJsonFile("appsettings.Tests.json");
|
config.AddJsonFile("appsettings.Tests.json");
|
||||||
|
|
||||||
var dbConnection = config.Build().GetSection("DbConnection").Get<DbConnection>()!;
|
var dbConnection = config.Build().GetSection("DbConnection").Get<DbConnection>()!;
|
||||||
connectionString = dbConnection.GetConnectionString();
|
connectionString = dbConnection.GetConnectionString();
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.ConfigureServices(services =>
|
builder.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<PersistenceDbContext>));
|
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<PersistenceDbContext>));
|
||||||
if (descriptor != null)
|
if (descriptor != null)
|
||||||
services.Remove(descriptor);
|
services.Remove(descriptor);
|
||||||
services.AddDbContext<PersistenceDbContext>(options =>
|
services.AddDbContext<PersistenceDbContext>(options =>
|
||||||
options.UseNpgsql(connectionString));
|
options.UseNpgsql(connectionString));
|
||||||
|
|
||||||
services.RemoveAll<IHttpClientFactory>();
|
services.RemoveAll<IHttpClientFactory>();
|
||||||
services.AddSingleton<IHttpClientFactory>(provider =>
|
services.AddSingleton<IHttpClientFactory>(provider =>
|
||||||
{
|
{
|
||||||
return new TestHttpClientFactory(this);
|
return new TestHttpClientFactory(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddSingleton<PersistenceClientFactory>();
|
services.AddSingleton<PersistenceClientFactory>();
|
||||||
|
|
||||||
var serviceProvider = services.BuildServiceProvider();
|
var serviceProvider = services.BuildServiceProvider();
|
||||||
|
|
||||||
using var scope = serviceProvider.CreateScope();
|
using var scope = serviceProvider.CreateScope();
|
||||||
var scopedServices = scope.ServiceProvider;
|
var scopedServices = scope.ServiceProvider;
|
||||||
@ -50,7 +49,7 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
|||||||
var dbContext = scopedServices.GetRequiredService<PersistenceDbContext>();
|
var dbContext = scopedServices.GetRequiredService<PersistenceDbContext>();
|
||||||
dbContext.Database.EnsureCreatedAndMigrated();
|
dbContext.Database.EnsureCreatedAndMigrated();
|
||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async ValueTask DisposeAsync()
|
public override async ValueTask DisposeAsync()
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using System.Collections;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.Repository;
|
namespace Persistence.Repository;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -134,20 +129,20 @@ public class CyclicArray<T> : IEnumerable<T>
|
|||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IEnumerator<T> GetEnumerator()
|
public IEnumerator<T> GetEnumerator()
|
||||||
=> new CyclycListEnumerator<T>(array, current, used);
|
=> new CyclicListEnumerator<T>(array, current, used);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
=> GetEnumerator();
|
=> GetEnumerator();
|
||||||
|
|
||||||
class CyclycListEnumerator<Te> : IEnumerator<Te>
|
class CyclicListEnumerator<Te> : IEnumerator<Te>
|
||||||
{
|
{
|
||||||
private readonly Te[] array;
|
private readonly Te[] array;
|
||||||
private readonly int used;
|
private readonly int used;
|
||||||
private readonly int first;
|
private readonly int first;
|
||||||
private int current = -1;
|
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];
|
this.array = new Te[array.Length];
|
||||||
array.CopyTo(this.array, 0);
|
array.CopyTo(this.array, 0);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Persistence.Repository.Data;
|
namespace Persistence.Repository.Data;
|
||||||
public class DataSaubDto : ITimeSeriesAbstractDto
|
public class DataSaubDto : ITimeSeriesAbstractDto
|
||||||
|
@ -19,7 +19,7 @@ public static class DependencyInjection
|
|||||||
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
||||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
||||||
services.AddTransient<ITimestampedSetRepository, TimestampedSetRepository>();
|
services.AddTransient<ITimestampedSetRepository, TimestampedSetRepository>();
|
||||||
services.AddTransient<ITechMessagesRepository, TechMessagesRepository>();
|
services.AddTransient<ITechMessagesRepository, TechMessagesRepository>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ public static class EFExtensionsSortBy
|
|||||||
: orderByAscending;
|
: orderByAscending;
|
||||||
|
|
||||||
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
||||||
.Invoke(genericMethod, new object[] { query, lambdaExpression })!;
|
.Invoke(genericMethod, [ query, lambdaExpression ])!;
|
||||||
return newQuery;
|
return newQuery;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,100 +6,100 @@ using Persistence.Repositories;
|
|||||||
|
|
||||||
namespace Persistence.Repository.Repositories
|
namespace Persistence.Repository.Repositories
|
||||||
{
|
{
|
||||||
public class SetpointRepository : ISetpointRepository
|
public class SetpointRepository : ISetpointRepository
|
||||||
{
|
{
|
||||||
private DbContext db;
|
private readonly DbContext db;
|
||||||
public SetpointRepository(DbContext db)
|
public SetpointRepository(DbContext db)
|
||||||
{
|
{
|
||||||
this.db = 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)
|
public async Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var entities = await query
|
var entities = await query
|
||||||
.Where(e => setpointKeys.Contains(e.Key))
|
.Where(e => setpointKeys.Contains(e.Key))
|
||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
var dtos = entities.Select(e => e.Adapt<SetpointValueDto>());
|
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)
|
public async Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var entities = await query
|
var entities = await query
|
||||||
.Where(e => setpointKeys.Contains(e.Key))
|
.Where(e => setpointKeys.Contains(e.Key))
|
||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
var filteredEntities = entities
|
var filteredEntities = entities
|
||||||
.GroupBy(e => e.Key)
|
.GroupBy(e => e.Key)
|
||||||
.Select(e => e.OrderBy(o => o.Created))
|
.Select(e => e.OrderBy(o => o.Created))
|
||||||
.Select(e => e.Where(e => e.Created <= historyMoment).Last());
|
.Select(e => e.Where(e => e.Created <= historyMoment).Last());
|
||||||
var dtos = filteredEntities
|
var dtos = filteredEntities
|
||||||
.Select(e => e.Adapt<SetpointValueDto>());
|
.Select(e => e.Adapt<SetpointValueDto>());
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
public async Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var entities = await query
|
var entities = await query
|
||||||
.Where(e => e.Created >= dateBegin)
|
.Where(e => e.Created >= dateBegin)
|
||||||
.Take(take)
|
.Take(take)
|
||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
var dtos = entities
|
var dtos = entities
|
||||||
.Select(e => e.Adapt<SetpointLogDto>());
|
.Select(e => e.Adapt<SetpointLogDto>());
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly()
|
var query = GetQueryReadOnly()
|
||||||
.GroupBy(e => 1)
|
.GroupBy(e => 1)
|
||||||
.Select(group => new
|
.Select(group => new
|
||||||
{
|
{
|
||||||
Min = group.Min(e => e.Created),
|
Min = group.Min(e => e.Created),
|
||||||
Max = group.Max(e => e.Created),
|
Max = group.Max(e => e.Created),
|
||||||
});
|
});
|
||||||
var values = await query.FirstOrDefaultAsync(token);
|
var values = await query.FirstOrDefaultAsync(token);
|
||||||
var result = new DatesRangeDto()
|
var result = new DatesRangeDto()
|
||||||
{
|
{
|
||||||
From = values?.Min ?? DateTimeOffset.MinValue,
|
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||||
To = values?.Max ?? DateTimeOffset.MaxValue
|
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||||
};
|
};
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var entities = await query
|
var entities = await query
|
||||||
.Where(e => setpointKeys.Contains(e.Key))
|
.Where(e => setpointKeys.Contains(e.Key))
|
||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
var dtos = entities
|
var dtos = entities
|
||||||
.GroupBy(e => e.Key)
|
.GroupBy(e => e.Key)
|
||||||
.ToDictionary(e => e.Key, v => v.Select(z => z.Adapt<SetpointLogDto>()));
|
.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)
|
public async Task Add(Guid setpointKey, object newValue, Guid idUser, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entity = new Setpoint()
|
var entity = new Setpoint()
|
||||||
{
|
{
|
||||||
Key = setpointKey,
|
Key = setpointKey,
|
||||||
Value = newValue,
|
Value = newValue,
|
||||||
IdUser = idUser,
|
IdUser = idUser,
|
||||||
Created = DateTimeOffset.UtcNow
|
Created = DateTimeOffset.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
await db.Set<Setpoint>().AddAsync(entity, token);
|
await db.Set<Setpoint>().AddAsync(entity, token);
|
||||||
await db.SaveChangesAsync(token);
|
await db.SaveChangesAsync(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,170 +8,170 @@ using Persistence.Repository.Extensions;
|
|||||||
|
|
||||||
namespace Persistence.Repository.Repositories
|
namespace Persistence.Repository.Repositories
|
||||||
{
|
{
|
||||||
public class TechMessagesRepository : ITechMessagesRepository
|
public class TechMessagesRepository : ITechMessagesRepository
|
||||||
{
|
{
|
||||||
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DrillingSystem).FullName}CacheKey";
|
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DrillingSystem).FullName}CacheKey";
|
||||||
private const int CacheExpirationInMinutes = 60;
|
private const int CacheExpirationInMinutes = 60;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
private DbContext db;
|
private DbContext db;
|
||||||
|
|
||||||
public TechMessagesRepository(DbContext db, IMemoryCache memoryCache)
|
public TechMessagesRepository(DbContext db, IMemoryCache memoryCache)
|
||||||
{
|
{
|
||||||
this.memoryCache = memoryCache;
|
this.memoryCache = memoryCache;
|
||||||
this.db = db;
|
this.db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual IQueryable<TechMessage> GetQueryReadOnly() => db.Set<TechMessage>()
|
protected virtual IQueryable<TechMessage> GetQueryReadOnly() => db.Set<TechMessage>()
|
||||||
.Include(e => e.System);
|
.Include(e => e.System);
|
||||||
|
|
||||||
public async Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token)
|
public async Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var count = await query.CountAsync(token);
|
var count = await query.CountAsync(token);
|
||||||
|
|
||||||
var sort = request.SortSettings != string.Empty
|
var sort = request.SortSettings != string.Empty
|
||||||
? request.SortSettings
|
? request.SortSettings
|
||||||
: nameof(TechMessage.Timestamp);
|
: nameof(TechMessage.Timestamp);
|
||||||
var entities = await query
|
var entities = await query
|
||||||
.SortBy(request.SortSettings)
|
.SortBy(request.SortSettings)
|
||||||
.Skip(request.Skip)
|
.Skip(request.Skip)
|
||||||
.Take(request.Take)
|
.Take(request.Take)
|
||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
var dto = new PaginationContainer<TechMessageDto>()
|
var dto = new PaginationContainer<TechMessageDto>()
|
||||||
{
|
{
|
||||||
Skip = request.Skip,
|
Skip = request.Skip,
|
||||||
Take = request.Take,
|
Take = request.Take,
|
||||||
Count = count,
|
Count = count,
|
||||||
Items = entities.Select(e => e.Adapt<TechMessageDto>())
|
Items = entities.Select(e => e.Adapt<TechMessageDto>())
|
||||||
};
|
};
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<string> autoDrillingSystem, IEnumerable<int> categoryIds, CancellationToken token)
|
public async Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<string> autoDrillingSystem, IEnumerable<int> categoryIds, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var systems = autoDrillingSystem.Select(s => s.ToLower().Trim());
|
var systems = autoDrillingSystem.Select(s => s.ToLower().Trim());
|
||||||
var result = await query
|
var result = await query
|
||||||
.Where(e => systems.Count() == 0 || systems.Contains(e.System.Name.ToLower().Trim()))
|
.Where(e => systems.Count() == 0 || systems.Contains(e.System.Name.ToLower().Trim()))
|
||||||
.GroupBy(e => e.System.Name, (key, group) => new
|
.GroupBy(e => e.System.Name, (key, group) => new
|
||||||
{
|
{
|
||||||
System = key,
|
System = key,
|
||||||
Categories = group
|
Categories = group
|
||||||
.Where(g => categoryIds.Count() == 0 || categoryIds.Contains(g.CategoryId))
|
.Where(g => categoryIds.Count() == 0 || categoryIds.Contains(g.CategoryId))
|
||||||
})
|
})
|
||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
var entities = new List<MessagesStatisticDto>();
|
var entities = new List<MessagesStatisticDto>();
|
||||||
foreach (var e in result)
|
foreach (var e in result)
|
||||||
{
|
{
|
||||||
var categories = e.Categories
|
var categories = e.Categories
|
||||||
.GroupBy(g => g.CategoryId)
|
.GroupBy(g => g.CategoryId)
|
||||||
.ToDictionary(c => c.Key, v => v.Count());
|
.ToDictionary(c => c.Key, v => v.Count());
|
||||||
var entity = new MessagesStatisticDto()
|
var entity = new MessagesStatisticDto()
|
||||||
{
|
{
|
||||||
System = e.System,
|
System = e.System,
|
||||||
Categories = categories
|
Categories = categories
|
||||||
};
|
};
|
||||||
entities.Add(entity);
|
entities.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<string>> GetSystems(CancellationToken token)
|
public async Task<IEnumerable<string>> GetSystems(CancellationToken token)
|
||||||
{
|
{
|
||||||
var entities = await GetDrillingSystems(token);
|
var entities = await GetDrillingSystems(token);
|
||||||
var result = entities.Select(e => e.Name);
|
var result = entities.Select(e => e.Name);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> AddRange(IEnumerable<TechMessageDto> dtos, Guid userId, CancellationToken token)
|
public async Task<int> AddRange(IEnumerable<TechMessageDto> dtos, Guid userId, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
|
||||||
var entities = new List<TechMessage>();
|
var entities = new List<TechMessage>();
|
||||||
foreach (var dto in dtos)
|
foreach (var dto in dtos)
|
||||||
{
|
{
|
||||||
var entity = dto.Adapt<TechMessage>();
|
var entity = dto.Adapt<TechMessage>();
|
||||||
var systems = await GetDrillingSystems(token);
|
var systems = await GetDrillingSystems(token);
|
||||||
var systemId = systems.FirstOrDefault(e => e.Name.ToLower().Trim() == dto.System.ToLower().Trim())?.SystemId
|
var systemId = systems.FirstOrDefault(e => e.Name.ToLower().Trim() == dto.System.ToLower().Trim())?.SystemId
|
||||||
?? await CreateDrillingSystem(dto.System, token);
|
?? await CreateDrillingSystem(dto.System, token);
|
||||||
|
|
||||||
entity.SystemId = systemId;
|
entity.SystemId = systemId;
|
||||||
entity.UserId = userId;
|
entity.UserId = userId;
|
||||||
|
|
||||||
entities.Add(entity);
|
entities.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.Set<TechMessage>().AddRangeAsync(entities, token);
|
await db.Set<TechMessage>().AddRangeAsync(entities, token);
|
||||||
var result = await db.SaveChangesAsync(token);
|
var result = await db.SaveChangesAsync(token);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
public async Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly();
|
var query = GetQueryReadOnly();
|
||||||
var entities = await query
|
var entities = await query
|
||||||
.Where(e => e.Timestamp >= dateBegin)
|
.Where(e => e.Timestamp >= dateBegin)
|
||||||
.Take(take)
|
.Take(take)
|
||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
var dtos = entities
|
var dtos = entities
|
||||||
.Select(e => e.Adapt<TechMessageDto>());
|
.Select(e => e.Adapt<TechMessageDto>());
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly()
|
var query = GetQueryReadOnly()
|
||||||
.GroupBy(e => 1)
|
.GroupBy(e => 1)
|
||||||
.Select(group => new
|
.Select(group => new
|
||||||
{
|
{
|
||||||
Min = group.Min(e => e.Timestamp),
|
Min = group.Min(e => e.Timestamp),
|
||||||
Max = group.Max(e => e.Timestamp),
|
Max = group.Max(e => e.Timestamp),
|
||||||
});
|
});
|
||||||
var values = await query.FirstOrDefaultAsync(token);
|
var values = await query.FirstOrDefaultAsync(token);
|
||||||
var result = new DatesRangeDto()
|
var result = new DatesRangeDto()
|
||||||
{
|
{
|
||||||
From = values?.Min ?? DateTimeOffset.MinValue,
|
From = values?.Min ?? DateTimeOffset.MinValue,
|
||||||
To = values?.Max ?? DateTimeOffset.MaxValue
|
To = values?.Max ?? DateTimeOffset.MaxValue
|
||||||
};
|
};
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<Models.DrillingSystemDto>> GetDrillingSystems(CancellationToken token)
|
private async Task<IEnumerable<Models.DrillingSystemDto>> GetDrillingSystems(CancellationToken token)
|
||||||
{
|
{
|
||||||
var systems = await memoryCache.GetOrCreateAsync(SystemCacheKey, async f =>
|
var systems = await memoryCache.GetOrCreateAsync(SystemCacheKey, async f =>
|
||||||
{
|
{
|
||||||
f.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(CacheExpirationInMinutes);
|
f.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(CacheExpirationInMinutes);
|
||||||
|
|
||||||
var query = db.Set<Database.Entity.DrillingSystem>();
|
var query = db.Set<Database.Entity.DrillingSystem>();
|
||||||
var entities = await query.ToListAsync(token);
|
var entities = await query.ToListAsync(token);
|
||||||
var dtos = entities.Select(e => e.Adapt<Models.DrillingSystemDto>());
|
var dtos = entities.Select(e => e.Adapt<Models.DrillingSystemDto>());
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
});
|
});
|
||||||
|
|
||||||
return systems!;
|
return systems!;
|
||||||
}
|
}
|
||||||
private async Task<Guid> CreateDrillingSystem(string name, CancellationToken token)
|
private async Task<Guid> CreateDrillingSystem(string name, CancellationToken token)
|
||||||
{
|
{
|
||||||
memoryCache.Remove(SystemCacheKey);
|
memoryCache.Remove(SystemCacheKey);
|
||||||
|
|
||||||
var entity = new Database.Entity.DrillingSystem()
|
var entity = new Database.Entity.DrillingSystem()
|
||||||
{
|
{
|
||||||
SystemId = default,
|
SystemId = default,
|
||||||
Name = name.ToLower().Trim()
|
Name = name.ToLower().Trim()
|
||||||
};
|
};
|
||||||
|
|
||||||
await db.Set<Database.Entity.DrillingSystem>().AddAsync(entity);
|
await db.Set<Database.Entity.DrillingSystem>().AddAsync(entity);
|
||||||
await db.SaveChangesAsync(token);
|
await db.SaveChangesAsync(token);
|
||||||
|
|
||||||
return entity.SystemId;
|
return entity.SystemId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
using Mapster;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Persistence.Database.Model;
|
using Persistence.Database.Model;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
|
|
||||||
@ -24,12 +22,12 @@ public class TimeSeriesDataCachedRepository<TEntity, TDto> : TimeSeriesDataRepos
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstByDate = firstDateItem;
|
FirstByDate = firstDateItem;
|
||||||
|
|
||||||
var dtos = await base.GetLastAsync(CacheItemsCount, CancellationToken.None);
|
var dtos = await base.GetLastAsync(CacheItemsCount, CancellationToken.None);
|
||||||
dtos = dtos.OrderBy(d => d.Date);
|
dtos = dtos.OrderBy(d => d.Date);
|
||||||
LastData.AddRange(dtos);
|
LastData.AddRange(dtos);
|
||||||
}).Wait();
|
}).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +51,7 @@ public class TimeSeriesDataCachedRepository<TEntity, TDto> : TimeSeriesDataRepos
|
|||||||
var result = await base.AddRange(dtos, token);
|
var result = await base.AddRange(dtos, token);
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
dtos = dtos.OrderBy(x => x.Date);
|
dtos = dtos.OrderBy(x => x.Date);
|
||||||
|
|
||||||
FirstByDate = dtos.First();
|
FirstByDate = dtos.First();
|
||||||
@ -75,12 +73,12 @@ public class TimeSeriesDataCachedRepository<TEntity, TDto> : TimeSeriesDataRepos
|
|||||||
From = FirstByDate.Date,
|
From = FirstByDate.Date,
|
||||||
To = LastData[^1].Date
|
To = LastData[^1].Date
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<IEnumerable<TDto>> GetResampledData(
|
public override async Task<IEnumerable<TDto>> GetResampledData(
|
||||||
DateTimeOffset dateBegin,
|
DateTimeOffset dateBegin,
|
||||||
double intervalSec = 600d,
|
double intervalSec = 600d,
|
||||||
int approxPointsCount = 1024,
|
int approxPointsCount = 1024,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
@ -78,8 +78,8 @@ public class TimeSeriesDataRepository<TEntity, TDto> : ITimeSeriesDataRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async virtual Task<IEnumerable<TDto>> GetResampledData(
|
public async virtual Task<IEnumerable<TDto>> GetResampledData(
|
||||||
DateTimeOffset dateBegin,
|
DateTimeOffset dateBegin,
|
||||||
double intervalSec = 600d,
|
double intervalSec = 600d,
|
||||||
int approxPointsCount = 1024,
|
int approxPointsCount = 1024,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
@ -77,12 +77,12 @@ public class TimestampedSetRepository : ITimestampedSetRepository
|
|||||||
{
|
{
|
||||||
var query = db.Set<TimestampedSet>()
|
var query = db.Set<TimestampedSet>()
|
||||||
.GroupBy(entity => entity.IdDiscriminator)
|
.GroupBy(entity => entity.IdDiscriminator)
|
||||||
.Select(group => new
|
.Select(group => new
|
||||||
{
|
{
|
||||||
Min = group.Min(entity => entity.Timestamp),
|
Min = group.Min(entity => entity.Timestamp),
|
||||||
Max = group.Max(entity => entity.Timestamp),
|
Max = group.Max(entity => entity.Timestamp),
|
||||||
});
|
});
|
||||||
|
|
||||||
var item = await query.FirstOrDefaultAsync(token);
|
var item = await query.FirstOrDefaultAsync(token);
|
||||||
if (item is null)
|
if (item is null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -33,12 +33,12 @@ public interface ISetpointApi : ISyncApi<SetpointLogDto>
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Метод сохранения уставки
|
/// Метод сохранения уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKey">ключ уставки</param>
|
/// <param name="setpointKey">ключ уставки</param>
|
||||||
/// <param name="newValue">значение</param>
|
/// <param name="newValue">значение</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token);
|
Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
@ -16,9 +15,9 @@ public interface ITimeSeriesBaseDataApi<TDto>
|
|||||||
/// <param name="approxPointsCount"></param>
|
/// <param name="approxPointsCount"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> GetResampledData(
|
Task<IActionResult> GetResampledData(
|
||||||
DateTimeOffset dateBegin,
|
DateTimeOffset dateBegin,
|
||||||
double intervalSec = 600d,
|
double intervalSec = 600d,
|
||||||
int approxPointsCount = 1024,
|
int approxPointsCount = 1024,
|
||||||
CancellationToken token = default);
|
CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ namespace Persistence.Models;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Часть записи описывающая изменение
|
/// Часть записи описывающая изменение
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ChangeLogDto<T> where T: class
|
public class ChangeLogDto<T> where T : class
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Запись
|
/// Запись
|
||||||
@ -38,5 +38,5 @@ public class ChangeLogDto<T> where T: class
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id заменяемой записи
|
/// Id заменяемой записи
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? IdPrevious { get; set; }
|
public int? IdPrevious { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AuthUser
|
public class AuthUser
|
||||||
{
|
{
|
||||||
public required string Username { get; set; }
|
public required string Username { get; set; }
|
||||||
public required string Password { get; set; }
|
public required string Password { get; set; }
|
||||||
public required string ClientId { get; set; }
|
public required string ClientId { get; set; }
|
||||||
public required string GrantType { 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
|
namespace Persistence.Models.Configurations
|
||||||
{
|
{
|
||||||
public static class JwtParams
|
public static class JwtParams
|
||||||
{
|
{
|
||||||
private static readonly string KeyValue = "супер секретный ключ для шифрования";
|
private static readonly string KeyValue = "супер секретный ключ для шифрования";
|
||||||
public static SymmetricSecurityKey SecurityKey
|
public static SymmetricSecurityKey SecurityKey
|
||||||
{
|
{
|
||||||
get { return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(KeyValue)); }
|
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
|
namespace Persistence.Models.Configurations
|
||||||
{
|
{
|
||||||
public class JwtToken
|
public class JwtToken
|
||||||
{
|
{
|
||||||
[JsonPropertyName("access_token")]
|
[JsonPropertyName("access_token")]
|
||||||
public required string AccessToken { get; set; }
|
public required string AccessToken { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace Persistence.Models;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Диапазон дат
|
/// Диапазон дат
|
||||||
|
@ -5,18 +5,18 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DrillingSystemDto
|
public class DrillingSystemDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ключ
|
/// Ключ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid SystemId { get; set; }
|
public Guid SystemId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Наименование
|
/// Наименование
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Описание
|
/// Описание
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MessagesStatisticDto
|
public class MessagesStatisticDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Система бурения
|
/// Система бурения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required string System { get; set; }
|
public required string System { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Количество сообщений в соответствии с категориями важности
|
/// Количество сообщений в соответствии с категориями важности
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required Dictionary<int, int> Categories { get; set; }
|
public required Dictionary<int, int> Categories { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ public class SetpointLogDto : SetpointValueDto
|
|||||||
/// Дата сохранения уставки
|
/// Дата сохранения уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ключ пользователя
|
/// Ключ пользователя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -9,7 +9,7 @@ public class SetpointValueDto
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid Key { get; set; }
|
public Guid Key { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Значение уставки
|
/// Значение уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2,51 +2,51 @@
|
|||||||
|
|
||||||
namespace Persistence.Models
|
namespace Persistence.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Модель технологического сообщения
|
/// Модель технологического сообщения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TechMessageDto
|
public class TechMessageDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id события
|
/// Id события
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public Guid EventId { get; set; }
|
public Guid EventId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id Категории важности
|
/// Id Категории важности
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Range(0, int.MaxValue, ErrorMessage = "Id Категории важности не может быть меньше 0")]
|
[Range(0, int.MaxValue, ErrorMessage = "Id Категории важности не может быть меньше 0")]
|
||||||
public int CategoryId { get; set; }
|
public int CategoryId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата возникновения
|
/// Дата возникновения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset Timestamp { get; set; }
|
public DateTimeOffset Timestamp { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Глубина забоя
|
/// Глубина забоя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Range(0, double.MaxValue, ErrorMessage = "Глубина забоя не может быть меньше 0")]
|
[Range(0, double.MaxValue, ErrorMessage = "Глубина забоя не может быть меньше 0")]
|
||||||
public double? Depth { get; set; }
|
public double? Depth { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Текст сообщения
|
/// Текст сообщения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
[StringLength(512, MinimumLength = 1, ErrorMessage = "Допустимая длина текста сообщения от 1 до 512 символов")]
|
[StringLength(512, MinimumLength = 1, ErrorMessage = "Допустимая длина текста сообщения от 1 до 512 символов")]
|
||||||
public required string MessageText { get; set; }
|
public required string MessageText { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Система автобурения, к которой относится сообщение
|
/// Система автобурения, к которой относится сообщение
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
[StringLength(256, MinimumLength = 1, ErrorMessage = "Допустимая длина наименования системы АБ от 1 до 256 символов")]
|
[StringLength(256, MinimumLength = 1, ErrorMessage = "Допустимая длина наименования системы АБ от 1 до 256 символов")]
|
||||||
public required string System { get; set; }
|
public required string System { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id пользователя за пультом бурильщика
|
/// Id пользователя за пультом бурильщика
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid UserId { get; set; }
|
public Guid UserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,165 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Persistence.Models;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
|
||||||
//public abstract class AbstractChangeLogRepository<TEntity, TChangeLogDto, TDto> : IChangeLogRepository<TDto, TChangeLogDto>
|
|
||||||
// where TDto : class, new()
|
|
||||||
// where TEntity : class, IChangeLogAbstract
|
|
||||||
// where TChangeLogDto : ChangeLogDto<TDto>
|
|
||||||
//{
|
|
||||||
// private readonly DbContext dbContext;
|
|
||||||
|
|
||||||
// protected AbstractChangeLogRepository(DbContext dbContext)
|
|
||||||
// {
|
|
||||||
// this.dbContext = dbContext;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public abstract TEntity Convert(TDto entity);
|
|
||||||
// public async Task<int> Clear(int idUser,CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
|
|
||||||
// //var updateTime = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
// ////todo
|
|
||||||
// //var query = BuildQuery(request);
|
|
||||||
// //query = query.Where(e => e.Obsolete == null);
|
|
||||||
|
|
||||||
// //var entitiesToDelete = await query.ToArrayAsync(token);
|
|
||||||
|
|
||||||
// //foreach (var entity in entitiesToDelete)
|
|
||||||
// //{
|
|
||||||
// // entity.IdState = IChangeLogAbstract.IdCleared;
|
|
||||||
// // entity.Obsolete = updateTime;
|
|
||||||
// // entity.IdEditor = idUser;
|
|
||||||
// //}
|
|
||||||
|
|
||||||
// //var result = await SaveChangesWithExceptionHandling(token);
|
|
||||||
// //return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public async Task<int> ClearAndInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// var result = 0;
|
|
||||||
// using var transaction = await dbContext.Database.BeginTransactionAsync(token);
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// result += await Clear(idUser, token);
|
|
||||||
// result += await InsertRangeWithoutTransaction(idUser, dtos, token);
|
|
||||||
|
|
||||||
// await transaction.CommitAsync(token);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
// catch
|
|
||||||
// {
|
|
||||||
// await transaction.RollbackAsync(token);
|
|
||||||
// throw;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Task<IEnumerable<TDto>> GetCurrent(DateTimeOffset moment, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Task<IEnumerable<DateOnly>> GetDatesChange(CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset date, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public async Task<int> AddRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// using var transaction = dbContext.Database.BeginTransaction();
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// var result = await InsertRangeWithoutTransaction(idUser, dtos, token);
|
|
||||||
// await transaction.CommitAsync(token);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
// catch
|
|
||||||
// {
|
|
||||||
// await transaction.RollbackAsync(token);
|
|
||||||
// throw;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// protected abstract DatabaseFacade GetDataBase();
|
|
||||||
|
|
||||||
// public Task<int> MarkAsDeleted(int idUser, IEnumerable<int> ids, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Task<int> UpdateOrInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Task<int> UpdateRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Task<IEnumerable<TChangeLogDto>> GetChangeLogForDate(DateTimeOffset? updateFrom, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private async Task<int> InsertRangeWithoutTransaction(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
// {
|
|
||||||
// var result = 0;
|
|
||||||
// if (dtos.Any())
|
|
||||||
// {
|
|
||||||
// var entities = dtos.Select(Convert);
|
|
||||||
// var creation = DateTimeOffset.UtcNow;
|
|
||||||
// var dbSet = dbContext.Set<TEntity>();
|
|
||||||
// foreach (var entity in entities)
|
|
||||||
// {
|
|
||||||
// entity.Id = default;
|
|
||||||
// entity.IdAuthor = idUser;
|
|
||||||
// entity.Creation = creation;
|
|
||||||
// entity.IdState = IChangeLogAbstract.IdStateActual;
|
|
||||||
// entity.IdEditor = null;
|
|
||||||
// entity.IdPrevious = null;
|
|
||||||
// entity.Obsolete = null;
|
|
||||||
// dbSet.Add(entity);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// result += await SaveChangesWithExceptionHandling(token);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private async Task<int> SaveChangesWithExceptionHandling(CancellationToken token)
|
|
||||||
// {
|
|
||||||
// var result = await dbContext.SaveChangesAsync(token);
|
|
||||||
// return result;
|
|
||||||
// //try
|
|
||||||
// //{
|
|
||||||
// // var result = await dbContext.SaveChangesAsync(token);
|
|
||||||
// // return result;
|
|
||||||
// //}
|
|
||||||
// //catch (DbUpdateException ex)
|
|
||||||
// //{
|
|
||||||
// // if (ex.InnerException is PostgresException pgException)
|
|
||||||
// // TryConvertPostgresExceptionToValidateException(pgException);
|
|
||||||
// // throw;
|
|
||||||
// //}
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// //private static void TryConvertPostgresExceptionToValidateException(PostgresException pgException)
|
|
||||||
// //{
|
|
||||||
// // if (pgException.SqlState == PostgresErrorCodes.ForeignKeyViolation)
|
|
||||||
// // throw new ArgumentInvalidException("dtos", pgException.Message + "\r\n" + pgException.Detail);
|
|
||||||
// //}
|
|
||||||
//}
|
|
@ -1,4 +1,3 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
namespace Persistence.Repositories;
|
||||||
@ -16,14 +15,14 @@ public interface ISetpointRepository
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить значения уставок за определенный момент времени
|
/// Получить значения уставок за определенный момент времени
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKeys"></param>
|
/// <param name="setpointKeys"></param>
|
||||||
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить историю изменений значений уставок
|
/// Получить историю изменений значений уставок
|
||||||
@ -33,31 +32,31 @@ public interface ISetpointRepository
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Метод сохранения уставки
|
/// Метод сохранения уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpointKey">ключ операции</param>
|
/// <param name="setpointKey">ключ операции</param>
|
||||||
/// <param name="idUser">ключ пользователя</param>
|
/// <param name="idUser">ключ пользователя</param>
|
||||||
/// <param name="newValue">значение</param>
|
/// <param name="newValue">значение</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// to do
|
/// to do
|
||||||
/// id User учесть в соответствующем методе репозитория
|
/// id User учесть в соответствующем методе репозитория
|
||||||
Task Add(Guid setpointKey, object newValue, Guid idUser, CancellationToken token);
|
Task Add(Guid setpointKey, object newValue, Guid idUser, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -1,59 +1,58 @@
|
|||||||
using System.Threading.Tasks;
|
using Persistence.Models;
|
||||||
using Persistence.Models;
|
|
||||||
|
|
||||||
namespace Persistence.Repositories
|
namespace Persistence.Repositories
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс по работе с технологическими сообщениями
|
/// Интерфейс по работе с технологическими сообщениями
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITechMessagesRepository
|
public interface ITechMessagesRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить страницу списка объектов
|
/// Получить страницу списка объектов
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token);
|
Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление новых сообщений
|
/// Добавление новых сообщений
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> AddRange(IEnumerable<TechMessageDto> dtos, Guid userId, CancellationToken token);
|
Task<int> AddRange(IEnumerable<TechMessageDto> dtos, Guid userId, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение списка уникальных названий систем АБ
|
/// Получение списка уникальных названий систем АБ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<string>> GetSystems(CancellationToken token);
|
Task<IEnumerable<string>> GetSystems(CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение количества сообщений по категориям и системам автобурения
|
/// Получение количества сообщений по категориям и системам автобурения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="categoryId">Id Категории важности</param>
|
/// <param name="categoryId">Id Категории важности</param>
|
||||||
/// <param name="autoDrillingSystem">Система автобурения</param>
|
/// <param name="autoDrillingSystem">Система автобурения</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<string> autoDrillingSystem, IEnumerable<int> categoryIds, CancellationToken token);
|
Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<string> autoDrillingSystem, IEnumerable<int> categoryIds, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin"></param>
|
/// <param name="dateBegin"></param>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ public interface ITimeSeriesBaseRepository<TDto>
|
|||||||
/// <param name="approxPointsCount"></param>
|
/// <param name="approxPointsCount"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<TDto>> GetResampledData(
|
Task<IEnumerable<TDto>> GetResampledData(
|
||||||
DateTimeOffset dateBegin,
|
DateTimeOffset dateBegin,
|
||||||
double intervalSec = 600d,
|
double intervalSec = 600d,
|
||||||
int approxPointsCount = 1024,
|
int approxPointsCount = 1024,
|
||||||
CancellationToken token = default);
|
CancellationToken token = default);
|
||||||
|
|
||||||
|
77
exclusion.dic
Normal file
77
exclusion.dic
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
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
|
||||||
|
прога
|
||||||
|
Persistance
|
||||||
|
yyyyMMdd_HHmmssfff
|
||||||
|
Serializers
|
||||||
|
keycloak
|
||||||
|
Params
|
Loading…
Reference in New Issue
Block a user