Compare commits
No commits in common. "master" and "PersistenceClient" have entirely different histories.
master
...
Persistenc
273
.editorconfig
273
.editorconfig
@ -1,273 +0,0 @@
|
||||
# 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,38 +0,0 @@
|
||||
name: Unit tests
|
||||
run-name: ${{ gitea.actor }} is testing
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container: node
|
||||
|
||||
# Service containers to run with `runner-job`
|
||||
services:
|
||||
# Label used to access the service container
|
||||
postgres:
|
||||
# Docker Hub image
|
||||
image: postgres
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps tcp port 5432 on service container to the host
|
||||
- 5442:5432
|
||||
|
||||
steps:
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run integration tests
|
||||
run: dotnet test DD.Persistence.IntegrationTests
|
@ -1,178 +0,0 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
{
|
||||
private readonly IChangeLogRepository repository;
|
||||
|
||||
public ChangeLogController(IChangeLogRepository repository)
|
||||
{
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
[HttpPost("{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> Add(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
[FromBody] DataWithWellDepthAndSectionDto dto,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.AddRange(userId, idDiscriminator, [dto], token);
|
||||
|
||||
return CreatedAtAction(nameof(Add), result);
|
||||
}
|
||||
|
||||
[HttpPost("range/{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> AddRange(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
[FromBody] IEnumerable<DataWithWellDepthAndSectionDto> dtos,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.AddRange(userId, idDiscriminator, dtos, token);
|
||||
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> Delete(Guid id, CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.MarkAsDeleted(userId, [id], token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpDelete("range")]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> DeleteRange(IEnumerable<Guid> ids, CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.MarkAsDeleted(userId, ids, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost("replace/{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> ClearAndAddRange(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
[FromBody] IEnumerable<DataWithWellDepthAndSectionDto> dtos,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.ClearAndAddRange(userId, idDiscriminator, dtos, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> Update(
|
||||
DataWithWellDepthAndSectionDto dto,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.UpdateRange(userId, [dto], token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPut("range")]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> UpdateRange(
|
||||
IEnumerable<DataWithWellDepthAndSectionDto> dtos,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.UpdateRange(userId, dtos, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(PaginationContainer<DataWithWellDepthAndSectionDto>), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetCurrent(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
[FromQuery] SectionPartRequest filterRequest,
|
||||
[FromQuery] PaginationRequest paginationRequest,
|
||||
CancellationToken token)
|
||||
{
|
||||
var moment = new DateTimeOffset(3000, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
||||
var result = await repository.GetByDate(idDiscriminator, moment, filterRequest, paginationRequest, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("moment/{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(PaginationContainer<DataWithWellDepthAndSectionDto>), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetByDate(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
DateTimeOffset moment,
|
||||
[FromQuery] SectionPartRequest filterRequest,
|
||||
[FromQuery] PaginationRequest paginationRequest,
|
||||
CancellationToken token)
|
||||
{
|
||||
var result = await repository.GetByDate(idDiscriminator, moment, filterRequest, paginationRequest, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("history/{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ChangeLogDto>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||
public async Task<IActionResult> GetChangeLogForDate(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
DateTimeOffset dateBegin,
|
||||
DateTimeOffset dateEnd,
|
||||
CancellationToken token)
|
||||
{
|
||||
var result = await repository.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("datesChange/{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DateOnly>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||
public async Task<IActionResult> GetDatesChange([FromRoute] Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = await repository.GetDatesChange(idDiscriminator, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("part/{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DataWithWellDepthAndSectionDto>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||
public async Task<ActionResult<IEnumerable<DataWithWellDepthAndSectionDto>>> GetPart([FromRoute] Guid idDiscriminator, DateTimeOffset dateBegin, int take = 86400, CancellationToken token = default)
|
||||
{
|
||||
var result = await repository.GetGtDate(idDiscriminator, dateBegin, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("datesRange/{idDiscriminator}")]
|
||||
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync([FromRoute] Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = await repository.GetDatesRange(idDiscriminator, token);
|
||||
|
||||
if (result is null)
|
||||
return NoContent();
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Работа с системами
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class DataSourceSystemController : ControllerBase
|
||||
{
|
||||
private readonly IDataSourceSystemRepository dataSourceSystemRepository;
|
||||
|
||||
public DataSourceSystemController(IDataSourceSystemRepository dataSourceSystemRepository)
|
||||
{
|
||||
this.dataSourceSystemRepository = dataSourceSystemRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить системы
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<DataSourceSystemDto>> Get(CancellationToken token)
|
||||
{
|
||||
var result = await dataSourceSystemRepository.Get(token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить систему
|
||||
/// </summary>
|
||||
/// <param name="dataSourceSystemDto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> Add(DataSourceSystemDto dataSourceSystemDto, CancellationToken token)
|
||||
{
|
||||
await dataSourceSystemRepository.Add(dataSourceSystemDto, token);
|
||||
|
||||
return CreatedAtAction(nameof(Add), true);
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Работа с уставками
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class SetpointController : ControllerBase, ISetpointApi
|
||||
{
|
||||
private readonly ISetpointRepository setpointRepository;
|
||||
|
||||
public SetpointController(ISetpointRepository setpointRepository)
|
||||
{
|
||||
this.setpointRepository = setpointRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить актуальные значения уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("current")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetCurrent(setpointKeys, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="historyMoment"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("history")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory([FromQuery] IEnumerable<Guid> setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить историю изменений значений уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("log")]
|
||||
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetLog(setpointKeys, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("range")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetDatesRangeAsync(token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("part")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetPart(dateBegin, take, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить уставку
|
||||
/// </summary>
|
||||
/// <param name="setpointKey"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> Add(Guid setpointKey, object newValue, CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
await setpointRepository.Add(setpointKey, newValue, userId, token);
|
||||
|
||||
return CreatedAtAction(nameof(Add), true);
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Работа с технологическими сообщениями систем автобурения (АБ)
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class TechMessagesController : ControllerBase
|
||||
{
|
||||
private readonly ITechMessagesRepository techMessagesRepository;
|
||||
private static readonly Dictionary<int, string> categories = new()
|
||||
{
|
||||
{ 0, "System" },
|
||||
{ 1, "Авария" },
|
||||
{ 2, "Предупреждение" },
|
||||
{ 3, "Инфо" },
|
||||
{ 4, "Прочее" }
|
||||
};
|
||||
|
||||
public TechMessagesController(ITechMessagesRepository techMessagesRepository)
|
||||
{
|
||||
this.techMessagesRepository = techMessagesRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список технологических сообщений в виде страницы
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<PaginationContainer<TechMessageDto>>> GetPage([FromQuery] PaginationRequest request, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetPage(request, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить статистику по системам
|
||||
/// </summary>
|
||||
/// <param name="autoDrillingSystem"></param>
|
||||
/// <param name="categoryIds"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("statistics")]
|
||||
public async Task<ActionResult<IEnumerable<MessagesStatisticDto>>> GetStatistics([FromQuery] IEnumerable<Guid> autoDrillingSystem, [FromQuery] IEnumerable<int> categoryIds, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetStatistics(autoDrillingSystem, categoryIds, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список всех систем
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("systems")]
|
||||
public async Task<ActionResult<Dictionary<string, int>>> GetSystems(CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetSystems(token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("range")]
|
||||
public async Task<ActionResult<DatesRangeDto?>> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetDatesRangeAsync(token);
|
||||
|
||||
return result == null ? NoContent() : Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("part")]
|
||||
public async Task<ActionResult<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetPart(dateBegin, take, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить новые технологические сообщения
|
||||
/// </summary>
|
||||
/// <param name="systemId"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{systemId}")]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> AddRange([FromRoute] Guid systemId, [FromBody] IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
|
||||
var result = await techMessagesRepository.AddRange(systemId, dtos, userId, token);
|
||||
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить словарь категорий
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("categories")]
|
||||
public ActionResult<Dictionary<int, string>> GetImportantCategories()
|
||||
{
|
||||
return Ok(categories);
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDto>
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
{
|
||||
private readonly ITimeSeriesDataRepository<TDto> timeSeriesDataRepository;
|
||||
|
||||
public TimeSeriesController(ITimeSeriesDataRepository<TDto> timeSeriesDataRepository)
|
||||
{
|
||||
this.timeSeriesDataRepository = timeSeriesDataRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список объектов, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Get(DateTimeOffset dateBegin, CancellationToken token)
|
||||
{
|
||||
var result = await timeSeriesDataRepository.GetGtDate(dateBegin, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("datesRange")]
|
||||
public async Task<IActionResult> GetDatesRange(CancellationToken token)
|
||||
{
|
||||
var result = await timeSeriesDataRepository.GetDatesRange(token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="intervalSec"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("resampled")]
|
||||
public async Task<IActionResult> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
|
||||
{
|
||||
var result = await timeSeriesDataRepository.GetResampledData(dateBegin, intervalSec, approxPointsCount, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить записи
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await timeSeriesDataRepository.AddRange(dtos, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Хранение наборов данных с отметкой времени.
|
||||
/// Не оптимизировано под большие данные.
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]/{idDiscriminator}")]
|
||||
public class TimestampedSetController : ControllerBase
|
||||
{
|
||||
private readonly ITimestampedSetRepository repository;
|
||||
|
||||
public TimestampedSetController(ITimestampedSetRepository repository)
|
||||
{
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Записать новые данные
|
||||
/// Предполагается что данные с одним дискриминатором имеют одинаковую структуру
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||
/// <param name="sets"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>кол-во затронутых записей</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> AddRange([FromRoute] Guid idDiscriminator, [FromBody] IEnumerable<TimestampedSetDto> sets, CancellationToken token)
|
||||
{
|
||||
var result = await repository.AddRange(idDiscriminator, sets, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
||||
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||
/// <param name="skip"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, [FromQuery] IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||
{
|
||||
var result = await repository.Get(idDiscriminator, geTimestamp, columnNames, skip, take, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить последние данные
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||
[HttpGet("last")]
|
||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetLast(Guid idDiscriminator, [FromQuery] IEnumerable<string>? columnNames, int take, CancellationToken token)
|
||||
{
|
||||
var result = await repository.GetLast(idDiscriminator, columnNames, take, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Диапазон дат за которые есть данные
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>Дата первой и последней записи</returns>
|
||||
[HttpGet("datesRange")]
|
||||
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||
public async Task<IActionResult> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = await repository.GetDatesRange(idDiscriminator, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Количество записей по указанному набору в БД. Для пагинации.
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("count")]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||
public async Task<IActionResult> Count(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = await repository.Count(idDiscriminator, token);
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Services.Interfaces;
|
||||
using System.Net;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Работа с параметрами Wits
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class WitsDataController : ControllerBase, IWitsDataApi
|
||||
{
|
||||
private readonly IWitsDataService witsDataService;
|
||||
|
||||
public WitsDataController(IWitsDataService witsDataService)
|
||||
{
|
||||
this.witsDataService = witsDataService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/datesRange")]
|
||||
public async Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync([FromRoute] Guid discriminatorId, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetDatesRangeAsync(discriminatorId, token);
|
||||
|
||||
return result == null ? NoContent() : Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/part")]
|
||||
public async Task<ActionResult<IEnumerable<WitsDataDto>>> GetPart([FromRoute] Guid discriminatorId, [FromQuery] DateTimeOffset dateBegin, [FromQuery] int take, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetPart(discriminatorId, dateBegin, take, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId">Дискриминатор системы</param>
|
||||
/// <param name="dateFrom">Начало временного интервала</param>
|
||||
/// <param name="dateTo">Конец временного интервала</param>
|
||||
/// <param name="approxPointsCount">Количество точек</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{discriminatorId}/graph")]
|
||||
public async Task<ActionResult<IEnumerable<WitsDataDto>>> GetValuesForGraph([FromRoute] Guid discriminatorId,
|
||||
[FromQuery] DateTimeOffset dateFrom, [FromQuery] DateTimeOffset dateTo, [FromQuery] int approxPointsCount, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointsCount, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
|
||||
public async Task<IActionResult> AddRange([FromBody] IEnumerable<WitsDataDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await witsDataService.AddRange(dtos, token);
|
||||
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
|
||||
<AssemblyVersion>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.3.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DD.Persistence.Database.Postgres\DD.Persistence.Database.Postgres.csproj" />
|
||||
<ProjectReference Include="..\DD.Persistence.Database\DD.Persistence.Database.csproj" />
|
||||
<ProjectReference Include="..\DD.Persistence.Repository\DD.Persistence.Repository.csproj" />
|
||||
<ProjectReference Include="..\DD.Persistence\DD.Persistence.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,207 +0,0 @@
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Configurations;
|
||||
using DD.Persistence.Services;
|
||||
using DD.Persistence.Services.Interfaces;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Nodes;
|
||||
using DD.Persistence.Database.Entity;
|
||||
|
||||
namespace DD.Persistence.API;
|
||||
|
||||
public static class DependencyInjection
|
||||
{
|
||||
public static void AddSwagger(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.MapType<TimeSpan>(() => new OpenApiSchema { Type = "string", Example = new OpenApiString("0.00:00:00") });
|
||||
c.MapType<DateOnly>(() => new OpenApiSchema { Type = "string", Format = "date" });
|
||||
c.MapType<JsonValue>(() => new OpenApiSchema
|
||||
{
|
||||
AnyOf = [
|
||||
new OpenApiSchema {Type = "string", Format = "string" },
|
||||
new OpenApiSchema {Type = "number", Format = "int32" },
|
||||
new OpenApiSchema {Type = "number", Format = "float" }
|
||||
]
|
||||
});
|
||||
|
||||
c.CustomOperationIds(e =>
|
||||
{
|
||||
return $"{e.ActionDescriptor.RouteValues["action"]}";
|
||||
});
|
||||
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Persistence web api", Version = "v1" });
|
||||
|
||||
var needUseKeyCloak = configuration.GetSection("NeedUseKeyCloak").Get<bool>();
|
||||
if (needUseKeyCloak)
|
||||
c.AddKeycloakSecurity(configuration);
|
||||
else c.AddDefaultSecurity();
|
||||
|
||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
var includeControllerXmlComment = true;
|
||||
c.IncludeXmlComments(xmlPath, includeControllerXmlComment);
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IWitsDataService, WitsDataService>();
|
||||
}
|
||||
|
||||
#region Authentication
|
||||
public static void AddJWTAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var needUseKeyCloak = configuration
|
||||
.GetSection("NeedUseKeyCloak")
|
||||
.Get<bool>();
|
||||
if (needUseKeyCloak)
|
||||
services.AddKeyCloakAuthentication(configuration);
|
||||
else services.AddDefaultAuthentication(configuration);
|
||||
}
|
||||
|
||||
private static void AddKeyCloakAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var keyCloakHost = configuration["KeyCloakAuthentication:Host"];
|
||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.Audience = configuration["KeyCloakAuthentication:Audience"];
|
||||
options.MetadataAddress = $"{keyCloakHost}/.well-known/openid-configuration";
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidIssuer = keyCloakHost
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private static void AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = JwtParams.Issuer,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = JwtParams.Audience,
|
||||
ValidateLifetime = true,
|
||||
IssuerSigningKey = JwtParams.SecurityKey,
|
||||
ValidateIssuerSigningKey = false,
|
||||
};
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
var accessToken = context.Request.Headers.Authorization
|
||||
.ToString()
|
||||
.Replace(JwtBearerDefaults.AuthenticationScheme, string.Empty)
|
||||
.Trim();
|
||||
|
||||
context.Token = accessToken;
|
||||
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
var username = context.Principal?.Claims
|
||||
.FirstOrDefault(e => e.Type == "username")?.Value;
|
||||
|
||||
var password = context.Principal?.Claims
|
||||
.FirstOrDefault(e => e.Type == "password")?.Value;
|
||||
|
||||
var keyCloakUser = configuration
|
||||
.GetSection(nameof(AuthUser))
|
||||
.Get<AuthUser>()!;
|
||||
|
||||
if (username != keyCloakUser.Username || password != keyCloakUser.Password)
|
||||
{
|
||||
context.Fail("username or password did not match");
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Keycloak
|
||||
private static void AddKeycloakSecurity(this SwaggerGenOptions options, IConfiguration configuration)
|
||||
{
|
||||
var keyCloakHost = configuration["KeyCloakAuthentication:Host"];
|
||||
|
||||
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 12345token'",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.OAuth2,
|
||||
Flows = new OpenApiOAuthFlows
|
||||
{
|
||||
Implicit = new OpenApiOAuthFlow
|
||||
{
|
||||
AuthorizationUrl = new Uri($"{keyCloakHost}/protocol/openid-connect/auth"),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Keycloak"
|
||||
},
|
||||
Scheme = "Bearer",
|
||||
Name = "Bearer",
|
||||
In = ParameterLocation.Header,
|
||||
},
|
||||
new List<string>()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void AddDefaultSecurity(this SwaggerGenOptions options)
|
||||
{
|
||||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345token'",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Scheme = "Bearer",
|
||||
});
|
||||
|
||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
},
|
||||
Scheme = "oauth2",
|
||||
Name = "Bearer",
|
||||
In = ParameterLocation.Header,
|
||||
},
|
||||
new List<string>()
|
||||
}
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>8dcdcfed-c959-4eef-9891-ae60b1b136ea</UserSecretsId>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\LinuxRelease.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\WindowsRelease.pubxml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DD.Persistence.API\DD.Persistence.API.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<DeleteExistingFiles>true</DeleteExistingFiles>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<PublishProvider>FileSystem</PublishProvider>
|
||||
<PublishUrl>bin\Release\net8.0\publish\</PublishUrl>
|
||||
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<ProjectGuid>063238bf-e982-43fa-9ddb-7d7d279086d8</ProjectGuid>
|
||||
<SelfContained>true</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<DeleteExistingFiles>true</DeleteExistingFiles>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<PublishProvider>FileSystem</PublishProvider>
|
||||
<PublishUrl>bin\Release\net8.0\publish\</PublishUrl>
|
||||
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<ProjectGuid>063238bf-e982-43fa-9ddb-7d7d279086d8</ProjectGuid>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -1,52 +0,0 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:5266"
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:7154;http://localhost:5266"
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_HTTPS_PORTS": "8081",
|
||||
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||
},
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:54958",
|
||||
"sslPort": 44352
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
# DD.Persistence.App Readme
|
||||
## Краткое описание DD.Persistence.App сервиса
|
||||
DD.Persistence.App - проект исполняемого файла микросервиса
|
||||
|
||||
## Настройка DD.Persistence.App (файл appsettings.json)
|
||||
- `appsettings.json` - файл с настройками проекта.
|
||||
|
||||
### Подключение к БД
|
||||
- Настройки подключения к базе хранятся в свойстве `DefaultConnection` секции `ConnectionStrings`
|
||||
файла `appsettings.json`, где:
|
||||
- Host - название или ip хоста;
|
||||
- Database - название базы данных;
|
||||
- Username - пользователь базы данных;
|
||||
- Password - пароль базы данных;
|
||||
- Больше информации о настройке подключения к postgreSQL можно прочесть по [ссылке](https://www.npgsql.org/doc/connection-string-parameters.html)
|
||||
|
||||
### Авторизация
|
||||
1. В проекте предусмотрены 2 типа авторизации:
|
||||
- Авторизация через KeyCloak. Используется в продакшен версии.
|
||||
- Авторизация через Jwt-токен. Используется для разработки и тестирования.
|
||||
2. Для включения авторизации через KeyCloak необходимо:
|
||||
- Установить секцию `NeedUseKeyCloak` файла `appsettings.json` в `true`
|
||||
- По необходимости настроить свойства секции `Authentication` файла `appsettings.json`
|
||||
|
||||
### defaultsettings.json
|
||||
Копия файла `appsettings.json` хранится в файле `defaultsettings.json`
|
||||
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"DbConnection": {
|
||||
"Host": "postgres",
|
||||
"Port": 5432,
|
||||
"Database": "persistence",
|
||||
"Username": "postgres",
|
||||
"Password": "postgres"
|
||||
},
|
||||
"NeedUseKeyCloak": false,
|
||||
"AuthUser": {
|
||||
"username": "myuser",
|
||||
"password": 12345,
|
||||
"clientId": "webapi",
|
||||
"grantType": "password"
|
||||
},
|
||||
"KeycloakGetTokenUrl": "http://192.168.0.10:8321/realms/Persistence/protocol/openid-connect/token"
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Host=localhost;Database=persistence;Username=postgres;Password=postgres;Persist Security Info=True"
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"NeedUseKeyCloak": false,
|
||||
"KeyCloakAuthentication": {
|
||||
"Audience": "account",
|
||||
"Host": "http://192.168.0.10:8321/realms/Persistence"
|
||||
},
|
||||
"AuthUser": {
|
||||
"username": "myuser",
|
||||
"password": 12345,
|
||||
"clientId": "webapi",
|
||||
"grantType": "password",
|
||||
"http://schemas.xmlsoap.org/ws/2005/05/identity /claims/nameidentifier": "7d9f3574-6574-4ca3-845a-0276eb4aa8f6"
|
||||
},
|
||||
"ClientUrl": "http://localhost:5000/"
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"NeedUseKeyCloak": false
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Host=localhost;Port=5432;Database=persistence;Username=postgres;Password=q;Persist Security Info=True"
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"NeedUseKeyCloak": false,
|
||||
"KeyCloakAuthentication": {
|
||||
"Audience": "account",
|
||||
"Host": "http://192.168.0.10:8321/realms/Persistence"
|
||||
},
|
||||
"AuthUser": {
|
||||
"username": "myuser",
|
||||
"password": 12345,
|
||||
"clientId": "webapi",
|
||||
"grantType": "password",
|
||||
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "7d9f3574-6574-4ca3-845a-0276eb4aa8f6"
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
using DD.Persistence.Client.Helpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Base;
|
||||
public abstract class BaseClient
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
|
||||
public BaseClient(ILogger<BaseClient> logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public async Task<T?> ExecuteGetResponse<T>(Func<Task<IApiResponse<T>>> getMethod, CancellationToken token)
|
||||
{
|
||||
var response = await getMethod.Invoke().WaitAsync(token);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return response.Content;
|
||||
}
|
||||
|
||||
var exception = response.GetPersistenceException();
|
||||
|
||||
logger.LogError(exception.Message);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
|
||||
public async Task ExecutePostResponse(Func<Task<IApiResponse>> postMethod, CancellationToken token)
|
||||
{
|
||||
var response = await postMethod.Invoke().WaitAsync(token);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var exception = response.GetPersistenceException();
|
||||
|
||||
logger.LogError(exception.Message);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
|
||||
public async Task<int> ExecutePostResponse(Func<Task<IApiResponse<int>>> postMethod, CancellationToken token)
|
||||
{
|
||||
var response = await postMethod.Invoke().WaitAsync(token);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return response.Content;
|
||||
}
|
||||
|
||||
var exception = response.GetPersistenceException();
|
||||
|
||||
logger.LogError(exception.Message);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class ChangeLogClient : BaseClient, IChangeLogClient
|
||||
{
|
||||
private readonly IRefitChangeLogClient refitChangeLogClient;
|
||||
|
||||
public ChangeLogClient(IRefitClientFactory<IRefitChangeLogClient> refitClientFactory, ILogger<ChangeLogClient> logger) : base(logger)
|
||||
{
|
||||
this.refitChangeLogClient = refitClientFactory.Create();
|
||||
}
|
||||
|
||||
public async Task<int> ClearAndAddRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitChangeLogClient.ClearAndAddRange(idDiscriminator, dtos, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<PaginationContainer<DataWithWellDepthAndSectionDto>> GetByDate(Guid idDiscriminator, DateTimeOffset moment,
|
||||
SectionPartRequest filterRequest, PaginationRequest paginationRequest, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitChangeLogClient.GetByDate(idDiscriminator, moment, filterRequest, paginationRequest, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ChangeLogDto>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitChangeLogClient.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<int> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitChangeLogClient.Add(idDiscriminator, dto, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitChangeLogClient.AddRange(idDiscriminator, dtos, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> Update(DataWithWellDepthAndSectionDto dto, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitChangeLogClient.Update(dto, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> UpdateRange(IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitChangeLogClient.UpdateRange(dtos, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> Delete(Guid id, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitChangeLogClient.Delete(id, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> DeleteRange(IEnumerable<Guid> ids, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitChangeLogClient.DeleteRange(ids, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitChangeLogClient.GetDatesRange(idDiscriminator, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
refitChangeLogClient.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class DataSourceSystemClient : BaseClient, IDataSourceSystemClient
|
||||
{
|
||||
private readonly IRefitDataSourceSystemClient dataSourceSystemClient;
|
||||
|
||||
public DataSourceSystemClient(IRefitClientFactory<IRefitDataSourceSystemClient> dataSourceSystemClientFactory, ILogger<DataSourceSystemClient> logger) : base(logger)
|
||||
{
|
||||
this.dataSourceSystemClient = dataSourceSystemClientFactory.Create();
|
||||
}
|
||||
|
||||
public async Task Add(DataSourceSystemDto dataSourceSystemDto, CancellationToken token)
|
||||
{
|
||||
await ExecutePostResponse(
|
||||
async () => await dataSourceSystemClient.Add(dataSourceSystemDto, token), token);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DataSourceSystemDto>> Get(CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await dataSourceSystemClient.Get(token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
dataSourceSystemClient.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Клиент для работы с записями ChangeLog
|
||||
/// </summary>
|
||||
public interface IChangeLogClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавить одну запись
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавить несколько записей
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Импорт с заменой: удаление старых строк и добавление новых
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> ClearAndAddRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить одну запись
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Delete(Guid id, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить несколько записей
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeleteRange(IEnumerable<Guid> ids, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение актуальных данных на определенную дату (с пагинацией)
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="moment"></param>
|
||||
/// <param name="filterRequest"></param>
|
||||
/// <param name="paginationRequest"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<PaginationContainer<DataWithWellDepthAndSectionDto>> GetByDate(Guid idDiscriminator, DateTimeOffset moment, SectionPartRequest filterRequest, PaginationRequest paginationRequest, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение исторических данных за определенный период времени
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="dateEnd"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ChangeLogDto>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени)
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить одну запись
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Update(DataWithWellDepthAndSectionDto dto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить несколько записей
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateRange(IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Клиент для работы с системами
|
||||
/// </summary>
|
||||
public interface IDataSourceSystemClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить системы
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<DataSourceSystemDto>> Get(CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавить систему
|
||||
/// </summary>
|
||||
/// <param name="dataSourceSystemDto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task Add(DataSourceSystemDto dataSourceSystemDto, CancellationToken token);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Клиент для работы с уставками
|
||||
/// </summary>
|
||||
public interface ISetpointClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавить уставку
|
||||
/// </summary>
|
||||
/// <param name="setpointKey"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task Add(Guid setpointKey, object newValue, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить актуальные значения уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="historyMoment"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить историю изменений значений уставок
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Клиент для работы с технологическими сообщениями
|
||||
/// </summary>
|
||||
public interface ITechMessagesClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавить новые технологические сообщения
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(Guid systemId, IEnumerable<TechMessageDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto?> GetDatesRangeAsync(CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить список технологических сообщений в виде страницы
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<PaginationContainer<TechMessageDto>> GetPage(PaginationRequest request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить статистику по системам
|
||||
/// </summary>
|
||||
/// <param name="systemIds"></param>
|
||||
/// <param name="categoryIds"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<Guid> systemIds, IEnumerable<int> categoryIds, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить список всех систем
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<DataSourceSystemDto>> GetSystems(CancellationToken token);
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Клиент для работы с временными данными
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto"></typeparam>
|
||||
public interface ITimeSeriesClient<TDto> : IDisposable where TDto : class, ITimeSeriesAbstractDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавление записей
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(IEnumerable<TDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить список объектов, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="dateEnd"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TDto>> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto?> GetDatesRange(CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
|
||||
/// </summary>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="intervalSec"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TDto>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Клиент для работы с репозиторием для хранения разных наборов данных рядов.
|
||||
/// idDiscriminator - идентифицирует конкретный набор данных, прим.: циклы измерения АСИБР, или отчет о DrillTest.
|
||||
/// idDiscriminator формируют клиенты и только им известно что они обозначают.
|
||||
/// Так как данные приходят редко, то их прореживания для построения графиков не предусмотрено.
|
||||
/// </summary>
|
||||
public interface ITimestampedSetClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Записать новые данные
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="sets"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(Guid idDiscriminator, IEnumerable<TimestampedSetDto> sets, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Количество записей по указанному набору в БД. Для пагинации
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Count(Guid idDiscriminator, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="geTimestamp"></param>
|
||||
/// <param name="columnNames"></param>
|
||||
/// <param name="skip"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TimestampedSetDto>> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Диапазон дат за которые есть данные
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="columnNames"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TimestampedSetDto>> GetLast(Guid idDiscriminator, IEnumerable<string>? columnNames, int take, CancellationToken token);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Клиент для работы с параметрами Wits
|
||||
/// </summary>
|
||||
public interface IWitsDataClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить набор параметров (Wits) для построения графика
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateFrom"></param>
|
||||
/// <param name="dateTo"></param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WitsDataDto>> GetValuesForGraph(Guid discriminatorId, [Query] DateTimeOffset dateFrom, [Query] DateTimeOffset dateTo, [Query] int approxPointsCount, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранить набор параметров (Wits)
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить порцию записей, начиная с заданной даты
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="dateBegin"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WitsDataDto>> GetPart(Guid discriminatorId, [Query] DateTimeOffset dateBegin, [Query] int take = 24 * 60 * 60, CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||
/// </summary>
|
||||
/// <param name="discriminatorId"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DatesRangeDto> GetDatesRangeAsync(Guid discriminatorId, CancellationToken token);
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
||||
public interface IRefitChangeLogClient : IRefitClient, IDisposable
|
||||
{
|
||||
private const string BaseRoute = "/api/ChangeLog";
|
||||
|
||||
[Post($"{BaseRoute}/replace/{{idDiscriminator}}")]
|
||||
Task<IApiResponse<int>> ClearAndAddRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/moment/{{idDiscriminator}}")]
|
||||
Task<IApiResponse<PaginationContainer<DataWithWellDepthAndSectionDto>>> GetByDate(
|
||||
Guid idDiscriminator,
|
||||
DateTimeOffset moment,
|
||||
[Query] SectionPartRequest filterRequest,
|
||||
[Query] PaginationRequest paginationRequest,
|
||||
CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/history/{{idDiscriminator}}")]
|
||||
Task<IApiResponse<IEnumerable<ChangeLogDto>>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
||||
|
||||
[Post($"{BaseRoute}/{{idDiscriminator}}")]
|
||||
Task<IApiResponse<int>> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token);
|
||||
|
||||
[Post($"{BaseRoute}/range/{{idDiscriminator}}")]
|
||||
Task<IApiResponse<int>> AddRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
||||
|
||||
[Put($"{BaseRoute}")]
|
||||
Task<IApiResponse<int>> Update(DataWithWellDepthAndSectionDto dto, CancellationToken token);
|
||||
|
||||
[Put($"{BaseRoute}/range")]
|
||||
Task<IApiResponse<int>> UpdateRange(IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
||||
|
||||
[Delete($"{BaseRoute}")]
|
||||
Task<IApiResponse<int>> Delete(Guid id, CancellationToken token);
|
||||
|
||||
[Delete($"{BaseRoute}/range")]
|
||||
Task<IApiResponse<int>> DeleteRange([Body] IEnumerable<Guid> ids, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/datesRange/{{idDiscriminator}}")]
|
||||
Task<IApiResponse<DatesRangeDto?>> GetDatesRange(Guid idDiscriminator, CancellationToken token);
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
public interface IRefitClient
|
||||
{
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
public interface IRefitDataSourceSystemClient : IRefitClient, IDisposable
|
||||
{
|
||||
private const string BaseRoute = "/api/dataSourceSystem";
|
||||
|
||||
[Get($"{BaseRoute}")]
|
||||
Task<IApiResponse<IEnumerable<DataSourceSystemDto>>> Get(CancellationToken token);
|
||||
|
||||
[Post($"{BaseRoute}")]
|
||||
Task<IApiResponse> Add(DataSourceSystemDto dataSourceSystemDto, CancellationToken token);
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
||||
public interface IRefitSetpointClient : IRefitClient, IDisposable
|
||||
{
|
||||
private const string BaseRoute = "/api/setpoint";
|
||||
|
||||
[Get($"{BaseRoute}/current")]
|
||||
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetCurrent([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/history")]
|
||||
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetHistory([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys, [Query] DateTimeOffset historyMoment, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/log")]
|
||||
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/range")]
|
||||
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/part")]
|
||||
Task<IApiResponse<IEnumerable<SetpointLogDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
|
||||
[Post($"{BaseRoute}/")]
|
||||
Task<IApiResponse> Add(Guid setpointKey, object newValue, CancellationToken token);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit
|
||||
{
|
||||
public interface IRefitTechMessagesClient : IRefitClient, IDisposable
|
||||
{
|
||||
private const string BaseRoute = "/api/techMessages";
|
||||
|
||||
[Get($"{BaseRoute}")]
|
||||
Task<IApiResponse<PaginationContainer<TechMessageDto>>> GetPage([Query] PaginationRequest request, CancellationToken token);
|
||||
|
||||
[Post($"{BaseRoute}/{{systemId}}")]
|
||||
Task<IApiResponse<int>> AddRange(Guid systemId, [Body] IEnumerable<TechMessageDto> dtos, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/systems")]
|
||||
Task<IApiResponse<IEnumerable<DataSourceSystemDto>>> GetSystems(CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/range")]
|
||||
Task<IApiResponse<DatesRangeDto?>> GetDatesRangeAsync(CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/part")]
|
||||
Task<IApiResponse<IEnumerable<TechMessageDto>>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/statistics")]
|
||||
Task<IApiResponse<IEnumerable<MessagesStatisticDto>>> GetStatistics([Query(CollectionFormat.Multi)] IEnumerable<Guid> systemIds, [Query(CollectionFormat.Multi)] IEnumerable<int> categoryIds, CancellationToken token);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
public interface IRefitTimeSeriesClient<TDto> : IRefitClient, IDisposable
|
||||
where TDto : class, ITimeSeriesAbstractDto
|
||||
{
|
||||
private const string BaseRoute = "/api/dataSaub";
|
||||
|
||||
[Post($"{BaseRoute}")]
|
||||
Task<IApiResponse<int>> AddRange(IEnumerable<TDto> dtos, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}")]
|
||||
Task<IApiResponse<IEnumerable<TDto>>> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/resampled")]
|
||||
Task<IApiResponse<IEnumerable<TDto>>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default);
|
||||
|
||||
[Get($"{BaseRoute}/datesRange")]
|
||||
Task<IApiResponse<DatesRangeDto?>> GetDatesRange(CancellationToken token);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
||||
public interface IRefitTimestampedSetClient : IRefitClient, IDisposable
|
||||
{
|
||||
private const string baseUrl = "/api/TimestampedSet/{idDiscriminator}";
|
||||
|
||||
[Post(baseUrl)]
|
||||
Task<IApiResponse<int>> AddRange(Guid idDiscriminator, IEnumerable<TimestampedSetDto> sets, CancellationToken token);
|
||||
|
||||
[Get(baseUrl)]
|
||||
Task<IApiResponse<IEnumerable<TimestampedSetDto>>> Get(Guid idDiscriminator, [Query] DateTimeOffset? geTimestamp, [Query] IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
||||
|
||||
[Get($"{baseUrl}/last")]
|
||||
Task<IApiResponse<IEnumerable<TimestampedSetDto>>> GetLast(Guid idDiscriminator, [Query] IEnumerable<string>? columnNames, int take, CancellationToken token);
|
||||
|
||||
[Get($"{baseUrl}/count")]
|
||||
Task<IApiResponse<int>> Count(Guid idDiscriminator, CancellationToken token);
|
||||
|
||||
[Get($"{baseUrl}/datesRange")]
|
||||
Task<IApiResponse<DatesRangeDto?>> GetDatesRange(Guid idDiscriminator, CancellationToken token);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
public interface IRefitWitsDataClient : IRefitClient, IDisposable
|
||||
{
|
||||
private const string BaseRoute = "/api/witsData";
|
||||
|
||||
[Get($"{BaseRoute}/{{discriminatorId}}/graph")]
|
||||
Task<IApiResponse<IEnumerable<WitsDataDto>>> GetValuesForGraph(Guid discriminatorId, [Query] DateTimeOffset dateFrom, [Query] DateTimeOffset dateTo, [Query] int approxPointsCount, CancellationToken token);
|
||||
|
||||
[Post($"{BaseRoute}/")]
|
||||
Task<IApiResponse<int>> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token);
|
||||
|
||||
[Get($"{BaseRoute}/{{discriminatorId}}/part")]
|
||||
Task<IApiResponse<IEnumerable<WitsDataDto>>> GetPart(Guid discriminatorId, [Query] DateTimeOffset dateBegin, [Query] int take = 24 * 60 * 60, CancellationToken token = default);
|
||||
|
||||
[Get($"{BaseRoute}/{{discriminatorId}}/datesRange")]
|
||||
Task<IApiResponse<DatesRangeDto>> GetDatesRangeAsync(Guid discriminatorId, CancellationToken token);
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
|
||||
public class SetpointClient : BaseClient, ISetpointClient
|
||||
{
|
||||
private readonly IRefitSetpointClient refitSetpointClient;
|
||||
|
||||
public SetpointClient(IRefitClientFactory<IRefitSetpointClient> refitSetpointClientFactory, ILogger<SetpointClient> logger) : base(logger)
|
||||
{
|
||||
this.refitSetpointClient = refitSetpointClientFactory.Create();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitSetpointClient.GetCurrent(setpointKeys, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitSetpointClient.GetHistory(setpointKeys, historyMoment, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitSetpointClient.GetLog(setpointKeys, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitSetpointClient.GetDatesRangeAsync(token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointLogDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitSetpointClient.GetPart(dateBegin, take, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task Add(Guid setpointKey, object newValue, CancellationToken token)
|
||||
{
|
||||
await ExecutePostResponse(
|
||||
async () => await refitSetpointClient.Add(setpointKey, newValue, token), token);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
refitSetpointClient.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
|
||||
public class TechMessagesClient : BaseClient, ITechMessagesClient
|
||||
{
|
||||
private readonly IRefitTechMessagesClient refitTechMessagesClient;
|
||||
|
||||
public TechMessagesClient(IRefitClientFactory<IRefitTechMessagesClient> refitTechMessagesClientFactory, ILogger<TechMessagesClient> logger) : base(logger)
|
||||
{
|
||||
this.refitTechMessagesClient = refitTechMessagesClientFactory.Create();
|
||||
}
|
||||
|
||||
public async Task<PaginationContainer<TechMessageDto>> GetPage(PaginationRequest request, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTechMessagesClient.GetPage(request, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(Guid systemId, IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitTechMessagesClient.AddRange(systemId, dtos, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DataSourceSystemDto>> GetSystems(CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTechMessagesClient.GetSystems(token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto?> GetDatesRangeAsync(CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTechMessagesClient.GetDatesRangeAsync(token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TechMessageDto>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTechMessagesClient.GetPart(dateBegin, take, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MessagesStatisticDto>> GetStatistics(IEnumerable<Guid> systemIds, IEnumerable<int> categoryIds, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTechMessagesClient.GetStatistics(systemIds, categoryIds, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
refitTechMessagesClient.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class TimeSeriesClient<TDto> : BaseClient, ITimeSeriesClient<TDto> where TDto : class, ITimeSeriesAbstractDto
|
||||
{
|
||||
private readonly IRefitTimeSeriesClient<TDto> timeSeriesClient;
|
||||
|
||||
public TimeSeriesClient(IRefitClientFactory<IRefitTimeSeriesClient<TDto>> refitTechMessagesClientFactory, ILogger<TimeSeriesClient<TDto>> logger) : base(logger)
|
||||
{
|
||||
this.timeSeriesClient = refitTechMessagesClientFactory.Create();
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await timeSeriesClient.AddRange(dtos, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TDto>> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await timeSeriesClient.Get(dateBegin, dateEnd, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TDto>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await timeSeriesClient.GetResampledData(dateBegin, intervalSec, approxPointsCount, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto?> GetDatesRange(CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await timeSeriesClient.GetDatesRange(token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
timeSeriesClient.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class TimestampedSetClient : BaseClient, ITimestampedSetClient
|
||||
{
|
||||
private readonly IRefitTimestampedSetClient refitTimestampedSetClient;
|
||||
|
||||
public TimestampedSetClient(IRefitClientFactory<IRefitTimestampedSetClient> refitTimestampedSetClientFactory, ILogger<TimestampedSetClient> logger) : base(logger)
|
||||
{
|
||||
this.refitTimestampedSetClient = refitTimestampedSetClientFactory.Create();
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(Guid idDiscriminator, IEnumerable<TimestampedSetDto> sets, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitTimestampedSetClient.AddRange(idDiscriminator, sets, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TimestampedSetDto>> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTimestampedSetClient.Get(idDiscriminator, geTimestamp, columnNames, skip, take, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TimestampedSetDto>> GetLast(Guid idDiscriminator, IEnumerable<string>? columnNames, int take, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTimestampedSetClient.GetLast(idDiscriminator, columnNames, take, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<int> Count(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTimestampedSetClient.Count(idDiscriminator, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitTimestampedSetClient.GetDatesRange(idDiscriminator, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
refitTimestampedSetClient.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class WitsDataClient : BaseClient, IWitsDataClient
|
||||
{
|
||||
private readonly IRefitWitsDataClient refitWitsDataClient;
|
||||
|
||||
public WitsDataClient(IRefitClientFactory<IRefitWitsDataClient> refitWitsDataClientFactory, ILogger<WitsDataClient> logger) : base(logger)
|
||||
{
|
||||
this.refitWitsDataClient = refitWitsDataClientFactory.Create();
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(IEnumerable<WitsDataDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await ExecutePostResponse(
|
||||
async () => await refitWitsDataClient.AddRange(dtos, token), token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<DatesRangeDto> GetDatesRangeAsync(Guid discriminatorId, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitWitsDataClient.GetDatesRangeAsync(discriminatorId, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WitsDataDto>> GetPart(Guid discriminatorId, DateTimeOffset dateBegin, int take = 86400, CancellationToken token = default)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitWitsDataClient.GetPart(discriminatorId, dateBegin, take, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WitsDataDto>> GetValuesForGraph(Guid discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo, int approxPointsCount, CancellationToken token)
|
||||
{
|
||||
var result = await ExecuteGetResponse(
|
||||
async () => await refitWitsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointsCount, token), token);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
refitWitsDataClient.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace DD.Persistence.Client.CustomExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Not Acceptable (406)
|
||||
/// </summary>
|
||||
public class AcceptableException : Exception
|
||||
{
|
||||
public AcceptableException(string message)
|
||||
: base(message) { }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace DD.Persistence.Client.CustomExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Bad gateway (502)
|
||||
/// </summary>
|
||||
public class BadGatewayException : Exception
|
||||
{
|
||||
public BadGatewayException(string message)
|
||||
: base(message) { }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace DD.Persistence.Client.CustomExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Forbidden (403)
|
||||
/// </summary>
|
||||
public class ForbiddenException : Exception
|
||||
{
|
||||
public ForbiddenException(string message)
|
||||
: base(message) { }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace DD.Persistence.Client.CustomExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Internal Server Error (500)
|
||||
/// </summary>
|
||||
public class InternalServerException : Exception
|
||||
{
|
||||
public InternalServerException(string message)
|
||||
: base(message) { }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace DD.Persistence.Client.CustomExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Locked (423)
|
||||
/// </summary>
|
||||
public class LockedException : Exception
|
||||
{
|
||||
public LockedException(string message)
|
||||
: base(message) { }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace DD.Persistence.Client.CustomExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Service Unavailable Error (503)
|
||||
/// </summary>
|
||||
public class ServiceUnavailableException : Exception
|
||||
{
|
||||
public ServiceUnavailableException(string message)
|
||||
: base(message) { }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace DD.Persistence.Client.CustomExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Too Many Requests (429)
|
||||
/// </summary>
|
||||
public class TooManyRequestsException : Exception
|
||||
{
|
||||
public TooManyRequestsException(string message)
|
||||
: base(message) { }
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
<!--Генерация NuGet пакета при сборке-->
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<!--Наименование-->
|
||||
<Title>DD.Persistence.Client</Title>
|
||||
<!--Версия пакета-->
|
||||
<VersionPrefix>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
|
||||
<!--Версия сборки-->
|
||||
<AssemblyVersion>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
|
||||
<!--Id пакета-->
|
||||
<PackageId>DD.Persistence.Client</PackageId>
|
||||
|
||||
<!--Автор-->
|
||||
<Authors>Digital Drilling</Authors>
|
||||
<!--Компания-->
|
||||
<Company>Digital Drilling</Company>
|
||||
<!--Описание-->
|
||||
<Description>Пакет для получения клиентов для работы с Persistence сервисом</Description>
|
||||
|
||||
<!--Url репозитория-->
|
||||
<RepositoryUrl>https://git.ddrilling.ru/on.nemtina/persistence.git</RepositoryUrl>
|
||||
<!--тип репозитория-->
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<!--Символы отладки-->
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<!--Формат пакета с символами-->
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<!--Путь к пакету-->
|
||||
<PackageOutputPath>C:\Projects\Nuget\Persistence\Client</PackageOutputPath>
|
||||
|
||||
<!--Readme-->
|
||||
<PackageReadmeFile>Readme.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
|
||||
<AssemblyVersion>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Readme.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.3.0" />
|
||||
<PackageReference Include="Refit" Version="8.0.0" />
|
||||
<PackageReference Include="Refit.HttpClientFactory" Version="8.0.0" />
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DD.Persistence.Models\DD.Persistence.Models.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,30 +0,0 @@
|
||||
using DD.Persistence.Client.Clients;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace DD.Persistence.Client;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddPersistenceClients(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient(typeof(IRefitClientFactory<>), typeof(RefitClientFactory<>));
|
||||
services.AddTransient<IChangeLogClient, ChangeLogClient>();
|
||||
services.AddTransient<IDataSourceSystemClient, DataSourceSystemClient>();
|
||||
services.AddTransient<ISetpointClient, SetpointClient>();
|
||||
services.AddTransient<ITechMessagesClient, TechMessagesClient>();
|
||||
services.AddTransient<ITimeSeriesClient<DataSaubDto>, TimeSeriesClient<DataSaubDto>>();
|
||||
services.AddTransient<ITimestampedSetClient, TimestampedSetClient>();
|
||||
services.AddTransient<IWitsDataClient, WitsDataClient>();
|
||||
return services;
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using DD.Persistence.Models.Configurations;
|
||||
using RestSharp;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DD.Persistence.Client.Helpers;
|
||||
public static class ApiTokenHelper
|
||||
{
|
||||
public static void Authorize(this HttpClient httpClient, IConfiguration configuration)
|
||||
{
|
||||
var authUser = configuration
|
||||
.GetSection(nameof(AuthUser))
|
||||
.Get<AuthUser>()!;
|
||||
var needUseKeyCloak = configuration
|
||||
.GetSection("NeedUseKeyCloak")
|
||||
.Get<bool>()!;
|
||||
var keycloakGetTokenUrl = configuration.GetSection("KeycloakGetTokenUrl").Get<string>() ?? string.Empty;
|
||||
|
||||
var jwtToken = needUseKeyCloak
|
||||
? authUser.CreateKeyCloakJwtToken(keycloakGetTokenUrl)
|
||||
: authUser.CreateDefaultJwtToken();
|
||||
|
||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
|
||||
}
|
||||
|
||||
public static void Authorize(this HttpClient httpClient, string jwtToken)
|
||||
{
|
||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
|
||||
}
|
||||
|
||||
private static string CreateDefaultJwtToken(this AuthUser authUser)
|
||||
{
|
||||
var nameIdetifier = Guid.NewGuid().ToString();
|
||||
var claims = new List<Claim>()
|
||||
{
|
||||
new(ClaimTypes.NameIdentifier, nameIdetifier),
|
||||
new("client_id", authUser.ClientId),
|
||||
new("username", authUser.Username),
|
||||
new("password", authUser.Password),
|
||||
new("grant_type", authUser.GrantType),
|
||||
new(ClaimTypes.NameIdentifier.ToString(), Guid.NewGuid().ToString())
|
||||
};
|
||||
|
||||
var tokenDescriptor = new SecurityTokenDescriptor
|
||||
{
|
||||
Issuer = JwtParams.Issuer,
|
||||
Audience = JwtParams.Audience,
|
||||
Subject = new ClaimsIdentity(claims),
|
||||
Expires = DateTime.UtcNow.AddHours(1),
|
||||
SigningCredentials = new SigningCredentials(JwtParams.SecurityKey, SecurityAlgorithms.HmacSha256Signature)
|
||||
};
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
private static string CreateKeyCloakJwtToken(this AuthUser authUser, string keycloakGetTokenUrl)
|
||||
{
|
||||
var restClient = new RestClient();
|
||||
|
||||
var request = new RestRequest(keycloakGetTokenUrl, Method.Post);
|
||||
request.AddParameter("username", authUser.Username);
|
||||
request.AddParameter("password", authUser.Password);
|
||||
request.AddParameter("client_id", authUser.ClientId);
|
||||
request.AddParameter("grant_type", authUser.GrantType);
|
||||
|
||||
var keycloakResponse = restClient.Post(request);
|
||||
if (keycloakResponse.IsSuccessful && !String.IsNullOrEmpty(keycloakResponse.Content))
|
||||
{
|
||||
var token = JsonSerializer.Deserialize<JwtToken>(keycloakResponse.Content)!;
|
||||
return token.AccessToken;
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
using DD.Persistence.Client.CustomExceptions;
|
||||
using Refit;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace DD.Persistence.Client.Helpers;
|
||||
public static class ExceptionsHelper
|
||||
{
|
||||
private static readonly Dictionary<System.Net.HttpStatusCode, Exception> ExceptionsDictionary = new Dictionary<System.Net.HttpStatusCode, Exception>()
|
||||
{
|
||||
{ System.Net.HttpStatusCode.BadRequest, new ValidationException("Ошибка валидации, формата или маршрутизации запроса") },
|
||||
{ System.Net.HttpStatusCode.Unauthorized, new UnauthorizedAccessException("Ошибка авторизации, клиент должен аутентифицировать себя, чтобы получить запрошенный ответ") },
|
||||
{ System.Net.HttpStatusCode.Forbidden, new ForbiddenException("Клиент известен серверу, но он неавторизован") },
|
||||
{ System.Net.HttpStatusCode.NotFound, new EntryPointNotFoundException("Сервер не может найти запрошенный ресурс") },
|
||||
{ System.Net.HttpStatusCode.MethodNotAllowed, new MethodAccessException("Обращение запрещено") },
|
||||
{ System.Net.HttpStatusCode.NotAcceptable, new AcceptableException("После выполнения согласования контента не найдено содержимого, соответствующего заданным критериям") },
|
||||
{ System.Net.HttpStatusCode.RequestTimeout, new TimeoutException("Время ожидания истекло") },
|
||||
{ System.Net.HttpStatusCode.Locked, new LockedException("Запрашиваемый ресурс заблокирован") },
|
||||
{ System.Net.HttpStatusCode.TooManyRequests, new TooManyRequestsException("Пользователь отправил слишком много запросов в определённый промежуток времени") },
|
||||
{ System.Net.HttpStatusCode.InternalServerError, new InternalServerException("На сервере произошла ошибка, в результате которой он не может успешно обработать запрос") },
|
||||
{ System.Net.HttpStatusCode.NotImplemented, new NotImplementedException("Метод запроса не поддерживается сервером") },
|
||||
{ System.Net.HttpStatusCode.BadGateway, new BadGatewayException("В процессе обработки запроса полуен недопустимый ответ от целевого сервера") },
|
||||
{ System.Net.HttpStatusCode.ServiceUnavailable, new ServiceUnavailableException("В процессе обработки запроса полуен недопустимый ответ от целевого сервера") },
|
||||
{ System.Net.HttpStatusCode.GatewayTimeout, new TimeoutException("Время ожидания целевого сервера истекло") }
|
||||
};
|
||||
|
||||
public static Exception GetPersistenceException(this IApiResponse response)
|
||||
{
|
||||
ExceptionsDictionary
|
||||
.TryGetValue(response.StatusCode, out var exception);
|
||||
|
||||
var result = exception ?? new Exception("Неопознанная ошибка");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
||||
namespace DD.Persistence.Client;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для фабрики, которая создает refit-клиентов
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface IRefitClientFactory<T> where T : IRefitClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Создание refit-клиента
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T Create();
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
# Persistence Client Nuget Readme
|
||||
## Краткое описание Persistence сервиса
|
||||
Persistence сервис отвечает за работу с хранимыми данными
|
||||
в рамках совокупности различных систем.
|
||||
|
||||
## Описание пакета
|
||||
Данный пакет предоставляет возможность взаимодействия с
|
||||
Persistence сервисом посредством обращения к конкретному
|
||||
клиенту, ответственному за работу с одной из областей сервиса.
|
||||
|
||||
## Список предоставляемых клиентов
|
||||
- `ISetpointClient` - Клиент для работы с уставками
|
||||
- `ITechMessagesClient` - Клиент для работы с технологическими сообщениями
|
||||
- `ITimeSeriesClient` - Клиент для работы с временными данными
|
||||
- `ITimestampedSetClient` - Клиент для работы с данными с отметкой времени
|
||||
- `IChangeLogClient` - Клиент для работы с записями ChangeLog
|
||||
- `IWitsDataClient` - Клиент для работы с параметрами Wits
|
||||
- `IDataSourceSystemClient` - Клиент для работы с системами
|
||||
|
||||
## Использование
|
||||
Для получения того или иного Persistence - клиента нужно
|
||||
обращаться к фабрике Persistence клиентов - `PersistenceClientFactory`. Для этого требуется:
|
||||
1. Добавить в проект фабрику HTTP - клиентов `IHttpClientFactory`.
|
||||
<br>Она должна предоставлять HTTP - клиента через метод `GetClient()`.
|
||||
>В том случае, если фабрика клиентов предоставляет не авторизованного клиента -
|
||||
необходимо добавить в проект фабрику токенов аутентификации `IAuthTokenFactory` с методом `GetToken()`,
|
||||
возвращающем токен в виде строки (без префикса `Bearer`).
|
||||
|
||||
2. Добавить логирование `ILoger`
|
||||
3. Внедрить зависимость в проект `services.AddSingleton<PersistenceClientFactory>();` - пример.
|
||||
4. Обратиться к фабрике Persistence - клиентов и получить требуемого клиента.
|
||||
|
||||
## xunit тестирование
|
||||
При написании интеграционных тестов с использованием Persistence - клиентов
|
||||
Http - клиент не обязан быть авторизован через передачу токена в `PersistenceClientFactory`.
|
||||
Для осуществления тестовой авторизации достаточно добавить в `appsettings.Tests.json` :
|
||||
```json
|
||||
"NeedUseKeyCloak": false,
|
||||
"AuthUser": {
|
||||
"username": "myuser",
|
||||
"password": 12345,
|
||||
"clientId": "webapi",
|
||||
"grantType": "password"
|
||||
},
|
||||
"KeycloakGetTokenUrl": "http://192.168.0.10:8321/realms/Persistence/protocol/openid-connect/token"
|
||||
```
|
||||
При этом возможна авторизация через `KeyCloak`.
|
||||
|
@ -1,52 +0,0 @@
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Client.Helpers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Refit;
|
||||
using System.Configuration;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DD.Persistence.Client;
|
||||
|
||||
/// <summary>
|
||||
/// Фабрика, которая создает refit-клиентов
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class RefitClientFactory<T> : IRefitClientFactory<T> where T : IRefitClient
|
||||
{
|
||||
private HttpClient client;
|
||||
private RefitSettings refitSettings;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RefitClientFactory(IConfiguration configuration, ILogger<IRefitClientFactory<T>> logger, HttpClient client)
|
||||
{
|
||||
//this.client = factory.CreateClient();
|
||||
this.client = client;
|
||||
|
||||
var baseUrl = configuration.GetSection("ClientUrl").Get<string>();
|
||||
if (String.IsNullOrEmpty(baseUrl))
|
||||
{
|
||||
var exception = new SettingsPropertyNotFoundException("В настройках конфигурации не указан адрес Persistence сервиса.");
|
||||
|
||||
logger.LogError(exception.Message);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
client.BaseAddress = new Uri(baseUrl);
|
||||
|
||||
JsonSerializerOptions JsonSerializerOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
refitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions));
|
||||
}
|
||||
/// <summary>
|
||||
/// создание клиента
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T Create()
|
||||
{
|
||||
return RestService.For<T>(client, refitSettings);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Npgsql;
|
||||
using DD.Persistence.Database.Model;
|
||||
|
||||
namespace DD.Persistence.Database.Postgres;
|
||||
|
||||
/// <summary>
|
||||
/// Фабрика контекста для dotnet ef миграций
|
||||
/// </summary>
|
||||
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<PersistencePostgresContext>
|
||||
{
|
||||
public PersistencePostgresContext CreateDbContext(string[] args)
|
||||
{
|
||||
var connectionStringBuilder = new NpgsqlConnectionStringBuilder
|
||||
{
|
||||
Host = "localhost",
|
||||
Database = "persistence",
|
||||
Username = "postgres",
|
||||
Password = "q",
|
||||
PersistSecurityInfo = true
|
||||
};
|
||||
var connectionString = connectionStringBuilder.ToString();
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<PersistencePostgresContext>();
|
||||
optionsBuilder.UseNpgsql(connectionString);
|
||||
var context = new PersistencePostgresContext(optionsBuilder.Options);
|
||||
return context;
|
||||
}
|
||||
}
|
@ -1,304 +0,0 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using DD.Persistence.Database.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DD.Persistence.Database.Postgres.Migrations
|
||||
{
|
||||
[DbContext(typeof(PersistencePostgresContext))]
|
||||
[Migration("20241220062251_Init")]
|
||||
partial class Init
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.DataSourceSystem", b =>
|
||||
{
|
||||
b.Property<Guid>("SystemId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id системы - источника данных");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text")
|
||||
.HasComment("Описание системы - источника данных");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(256)")
|
||||
.HasComment("Наименование системы - источника данных");
|
||||
|
||||
b.HasKey("SystemId");
|
||||
|
||||
b.ToTable("DataSourceSystem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ParameterData", b =>
|
||||
{
|
||||
b.Property<Guid>("DiscriminatorId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор системы");
|
||||
|
||||
b.Property<int>("ParameterId")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Id параметра");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Временная отметка");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(256)")
|
||||
.HasComment("Значение параметра в виде строки");
|
||||
|
||||
b.HasKey("DiscriminatorId", "ParameterId", "Timestamp");
|
||||
|
||||
b.ToTable("ParameterData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.Property<Guid>("EventId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id события");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Id Категории важности");
|
||||
|
||||
b.Property<int>("EventState")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Статус события");
|
||||
|
||||
b.Property<Guid>("SystemId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id системы, к которой относится сообщение");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(512)")
|
||||
.HasComment("Текст сообщения");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата возникновения");
|
||||
|
||||
b.HasKey("EventId");
|
||||
|
||||
b.HasIndex("SystemId");
|
||||
|
||||
b.ToTable("TechMessage");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TimestampedSet", b =>
|
||||
{
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор ссылка на тип сохраняемых данных");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Отметка времени, строго в UTC");
|
||||
|
||||
b.Property<string>("Set")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasComment("Набор сохраняемых данных");
|
||||
|
||||
b.HasKey("IdDiscriminator", "Timestamp");
|
||||
|
||||
b.ToTable("TimestampedSets", t =>
|
||||
{
|
||||
t.HasComment("Общая таблица данных временных рядов");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Model.ChangeLog", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Ключ записи");
|
||||
|
||||
b.Property<DateTimeOffset>("Creation")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания записи");
|
||||
|
||||
b.Property<double>("DepthEnd")
|
||||
.HasColumnType("double precision")
|
||||
.HasComment("Глубина забоя на дату окончания интервала");
|
||||
|
||||
b.Property<double>("DepthStart")
|
||||
.HasColumnType("double precision")
|
||||
.HasComment("Глубина забоя на дату начала интервала");
|
||||
|
||||
b.Property<Guid>("IdAuthor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Автор изменения");
|
||||
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid?>("IdEditor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Редактор");
|
||||
|
||||
b.Property<Guid?>("IdNext")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id заменяющей записи");
|
||||
|
||||
b.Property<Guid>("IdSection")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Ключ секции");
|
||||
|
||||
b.Property<DateTimeOffset?>("Obsolete")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата устаревания (например при удалении)");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasComment("Значение");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ChangeLog");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Model.DataSaub", b =>
|
||||
{
|
||||
b.Property<DateTimeOffset>("Date")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date");
|
||||
|
||||
b.Property<double?>("AxialLoad")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("axialLoad");
|
||||
|
||||
b.Property<double?>("BitDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("bitDepth");
|
||||
|
||||
b.Property<double?>("BlockPosition")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("blockPosition");
|
||||
|
||||
b.Property<double?>("BlockSpeed")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("blockSpeed");
|
||||
|
||||
b.Property<double?>("Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("flow");
|
||||
|
||||
b.Property<double?>("HookWeight")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("hookWeight");
|
||||
|
||||
b.Property<int>("IdFeedRegulator")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("idFeedRegulator");
|
||||
|
||||
b.Property<int?>("Mode")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("mode");
|
||||
|
||||
b.Property<double?>("Mse")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("mse");
|
||||
|
||||
b.Property<short>("MseState")
|
||||
.HasColumnType("smallint")
|
||||
.HasColumnName("mseState");
|
||||
|
||||
b.Property<double?>("Pressure")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pressure");
|
||||
|
||||
b.Property<double?>("Pump0Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump0Flow");
|
||||
|
||||
b.Property<double?>("Pump1Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump1Flow");
|
||||
|
||||
b.Property<double?>("Pump2Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump2Flow");
|
||||
|
||||
b.Property<double?>("RotorSpeed")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("rotorSpeed");
|
||||
|
||||
b.Property<double?>("RotorTorque")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("rotorTorque");
|
||||
|
||||
b.Property<string>("User")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("user");
|
||||
|
||||
b.Property<double?>("WellDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("wellDepth");
|
||||
|
||||
b.HasKey("Date");
|
||||
|
||||
b.ToTable("DataSaub");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Model.Setpoint", b =>
|
||||
{
|
||||
b.Property<Guid>("Key")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Ключ");
|
||||
|
||||
b.Property<DateTimeOffset>("Created")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания уставки");
|
||||
|
||||
b.Property<Guid>("IdUser")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id автора последнего изменения");
|
||||
|
||||
b.Property<object>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasComment("Значение уставки");
|
||||
|
||||
b.HasKey("Key", "Created");
|
||||
|
||||
b.ToTable("Setpoint");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.HasOne("DD.Persistence.Database.Entity.DataSourceSystem", "System")
|
||||
.WithMany()
|
||||
.HasForeignKey("SystemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("System");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DD.Persistence.Database.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Init : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChangeLog",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ записи"),
|
||||
IdDiscriminator = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор таблицы"),
|
||||
IdAuthor = table.Column<Guid>(type: "uuid", nullable: false, comment: "Автор изменения"),
|
||||
IdEditor = table.Column<Guid>(type: "uuid", nullable: true, comment: "Редактор"),
|
||||
Creation = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата создания записи"),
|
||||
Obsolete = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true, comment: "Дата устаревания (например при удалении)"),
|
||||
IdNext = table.Column<Guid>(type: "uuid", nullable: true, comment: "Id заменяющей записи"),
|
||||
DepthStart = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина забоя на дату начала интервала"),
|
||||
DepthEnd = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина забоя на дату окончания интервала"),
|
||||
IdSection = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ секции"),
|
||||
Value = table.Column<string>(type: "jsonb", nullable: false, comment: "Значение")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChangeLog", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DataSaub",
|
||||
columns: table => new
|
||||
{
|
||||
date = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
|
||||
mode = table.Column<int>(type: "integer", nullable: true),
|
||||
user = table.Column<string>(type: "text", nullable: true),
|
||||
wellDepth = table.Column<double>(type: "double precision", nullable: true),
|
||||
bitDepth = table.Column<double>(type: "double precision", nullable: true),
|
||||
blockPosition = table.Column<double>(type: "double precision", nullable: true),
|
||||
blockSpeed = table.Column<double>(type: "double precision", nullable: true),
|
||||
pressure = table.Column<double>(type: "double precision", nullable: true),
|
||||
axialLoad = table.Column<double>(type: "double precision", nullable: true),
|
||||
hookWeight = table.Column<double>(type: "double precision", nullable: true),
|
||||
rotorTorque = table.Column<double>(type: "double precision", nullable: true),
|
||||
rotorSpeed = table.Column<double>(type: "double precision", nullable: true),
|
||||
flow = table.Column<double>(type: "double precision", nullable: true),
|
||||
mseState = table.Column<short>(type: "smallint", nullable: false),
|
||||
idFeedRegulator = table.Column<int>(type: "integer", nullable: false),
|
||||
mse = table.Column<double>(type: "double precision", nullable: true),
|
||||
pump0Flow = table.Column<double>(type: "double precision", nullable: true),
|
||||
pump1Flow = table.Column<double>(type: "double precision", nullable: true),
|
||||
pump2Flow = table.Column<double>(type: "double precision", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DataSaub", x => x.date);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DataSourceSystem",
|
||||
columns: table => new
|
||||
{
|
||||
SystemId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id системы - источника данных"),
|
||||
Name = table.Column<string>(type: "varchar(256)", nullable: false, comment: "Наименование системы - источника данных"),
|
||||
Description = table.Column<string>(type: "text", nullable: true, comment: "Описание системы - источника данных")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DataSourceSystem", x => x.SystemId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ParameterData",
|
||||
columns: table => new
|
||||
{
|
||||
DiscriminatorId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор системы"),
|
||||
ParameterId = table.Column<int>(type: "integer", nullable: false, comment: "Id параметра"),
|
||||
Timestamp = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Временная отметка"),
|
||||
Value = table.Column<string>(type: "varchar(256)", nullable: false, comment: "Значение параметра в виде строки")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ParameterData", x => new { x.DiscriminatorId, x.ParameterId, x.Timestamp });
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Setpoint",
|
||||
columns: table => new
|
||||
{
|
||||
Key = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ"),
|
||||
Created = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата создания уставки"),
|
||||
Value = table.Column<object>(type: "jsonb", nullable: false, comment: "Значение уставки"),
|
||||
IdUser = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id автора последнего изменения")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Setpoint", x => new { x.Key, x.Created });
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TimestampedSets",
|
||||
columns: table => new
|
||||
{
|
||||
IdDiscriminator = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор ссылка на тип сохраняемых данных"),
|
||||
Timestamp = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Отметка времени, строго в UTC"),
|
||||
Set = table.Column<string>(type: "jsonb", nullable: false, comment: "Набор сохраняемых данных")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TimestampedSets", x => new { x.IdDiscriminator, x.Timestamp });
|
||||
},
|
||||
comment: "Общая таблица данных временных рядов");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TechMessage",
|
||||
columns: table => new
|
||||
{
|
||||
EventId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id события"),
|
||||
CategoryId = table.Column<int>(type: "integer", nullable: false, comment: "Id Категории важности"),
|
||||
Timestamp = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата возникновения"),
|
||||
Text = table.Column<string>(type: "varchar(512)", nullable: false, comment: "Текст сообщения"),
|
||||
SystemId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id системы, к которой относится сообщение"),
|
||||
EventState = table.Column<int>(type: "integer", nullable: false, comment: "Статус события")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TechMessage", x => x.EventId);
|
||||
table.ForeignKey(
|
||||
name: "FK_TechMessage_DataSourceSystem_SystemId",
|
||||
column: x => x.SystemId,
|
||||
principalTable: "DataSourceSystem",
|
||||
principalColumn: "SystemId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TechMessage_SystemId",
|
||||
table: "TechMessage",
|
||||
column: "SystemId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ChangeLog");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DataSaub");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ParameterData");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Setpoint");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TechMessage");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TimestampedSets");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DataSourceSystem");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,301 +0,0 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using DD.Persistence.Database.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DD.Persistence.Database.Postgres.Migrations
|
||||
{
|
||||
[DbContext(typeof(PersistencePostgresContext))]
|
||||
partial class PersistencePostgresContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.DataSourceSystem", b =>
|
||||
{
|
||||
b.Property<Guid>("SystemId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id системы - источника данных");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text")
|
||||
.HasComment("Описание системы - источника данных");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(256)")
|
||||
.HasComment("Наименование системы - источника данных");
|
||||
|
||||
b.HasKey("SystemId");
|
||||
|
||||
b.ToTable("DataSourceSystem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ParameterData", b =>
|
||||
{
|
||||
b.Property<Guid>("DiscriminatorId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор системы");
|
||||
|
||||
b.Property<int>("ParameterId")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Id параметра");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Временная отметка");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(256)")
|
||||
.HasComment("Значение параметра в виде строки");
|
||||
|
||||
b.HasKey("DiscriminatorId", "ParameterId", "Timestamp");
|
||||
|
||||
b.ToTable("ParameterData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.Property<Guid>("EventId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id события");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Id Категории важности");
|
||||
|
||||
b.Property<int>("EventState")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Статус события");
|
||||
|
||||
b.Property<Guid>("SystemId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id системы, к которой относится сообщение");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(512)")
|
||||
.HasComment("Текст сообщения");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата возникновения");
|
||||
|
||||
b.HasKey("EventId");
|
||||
|
||||
b.HasIndex("SystemId");
|
||||
|
||||
b.ToTable("TechMessage");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TimestampedSet", b =>
|
||||
{
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор ссылка на тип сохраняемых данных");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Отметка времени, строго в UTC");
|
||||
|
||||
b.Property<string>("Set")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasComment("Набор сохраняемых данных");
|
||||
|
||||
b.HasKey("IdDiscriminator", "Timestamp");
|
||||
|
||||
b.ToTable("TimestampedSets", t =>
|
||||
{
|
||||
t.HasComment("Общая таблица данных временных рядов");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Model.ChangeLog", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Ключ записи");
|
||||
|
||||
b.Property<DateTimeOffset>("Creation")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания записи");
|
||||
|
||||
b.Property<double>("DepthEnd")
|
||||
.HasColumnType("double precision")
|
||||
.HasComment("Глубина забоя на дату окончания интервала");
|
||||
|
||||
b.Property<double>("DepthStart")
|
||||
.HasColumnType("double precision")
|
||||
.HasComment("Глубина забоя на дату начала интервала");
|
||||
|
||||
b.Property<Guid>("IdAuthor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Автор изменения");
|
||||
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid?>("IdEditor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Редактор");
|
||||
|
||||
b.Property<Guid?>("IdNext")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id заменяющей записи");
|
||||
|
||||
b.Property<Guid>("IdSection")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Ключ секции");
|
||||
|
||||
b.Property<DateTimeOffset?>("Obsolete")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата устаревания (например при удалении)");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasComment("Значение");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ChangeLog");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Model.DataSaub", b =>
|
||||
{
|
||||
b.Property<DateTimeOffset>("Date")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date");
|
||||
|
||||
b.Property<double?>("AxialLoad")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("axialLoad");
|
||||
|
||||
b.Property<double?>("BitDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("bitDepth");
|
||||
|
||||
b.Property<double?>("BlockPosition")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("blockPosition");
|
||||
|
||||
b.Property<double?>("BlockSpeed")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("blockSpeed");
|
||||
|
||||
b.Property<double?>("Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("flow");
|
||||
|
||||
b.Property<double?>("HookWeight")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("hookWeight");
|
||||
|
||||
b.Property<int>("IdFeedRegulator")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("idFeedRegulator");
|
||||
|
||||
b.Property<int?>("Mode")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("mode");
|
||||
|
||||
b.Property<double?>("Mse")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("mse");
|
||||
|
||||
b.Property<short>("MseState")
|
||||
.HasColumnType("smallint")
|
||||
.HasColumnName("mseState");
|
||||
|
||||
b.Property<double?>("Pressure")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pressure");
|
||||
|
||||
b.Property<double?>("Pump0Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump0Flow");
|
||||
|
||||
b.Property<double?>("Pump1Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump1Flow");
|
||||
|
||||
b.Property<double?>("Pump2Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump2Flow");
|
||||
|
||||
b.Property<double?>("RotorSpeed")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("rotorSpeed");
|
||||
|
||||
b.Property<double?>("RotorTorque")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("rotorTorque");
|
||||
|
||||
b.Property<string>("User")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("user");
|
||||
|
||||
b.Property<double?>("WellDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("wellDepth");
|
||||
|
||||
b.HasKey("Date");
|
||||
|
||||
b.ToTable("DataSaub");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Model.Setpoint", b =>
|
||||
{
|
||||
b.Property<Guid>("Key")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Ключ");
|
||||
|
||||
b.Property<DateTimeOffset>("Created")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания уставки");
|
||||
|
||||
b.Property<Guid>("IdUser")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id автора последнего изменения");
|
||||
|
||||
b.Property<object>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasComment("Значение уставки");
|
||||
|
||||
b.HasKey("Key", "Created");
|
||||
|
||||
b.ToTable("Setpoint");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.HasOne("DD.Persistence.Database.Entity.DataSourceSystem", "System")
|
||||
.WithMany()
|
||||
.HasForeignKey("SystemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("System");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DD.Persistence.Database.Model;
|
||||
|
||||
/// <summary>
|
||||
/// EF êîíòåêñò äëÿ ÁÄ Postgres
|
||||
/// </summary>
|
||||
public partial class PersistencePostgresContext : PersistenceDbContext
|
||||
{
|
||||
public PersistencePostgresContext(DbContextOptions options)
|
||||
: base(options)
|
||||
{ }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
## Создать миграцию
|
||||
```
|
||||
dotnet ef migrations add <MigrationName> --project DD.Persistence.Database.Postgres
|
||||
|
||||
```
|
||||
|
||||
## Откатить миграцию
|
||||
```
|
||||
dotnet ef migrations remove --project DD.Persistence.Database.Postgres
|
||||
```
|
||||
Удаляется последняя созданная миграция.
|
@ -1,41 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DD.Persistence.Database;
|
||||
|
||||
public static class EFExtensions
|
||||
{
|
||||
private static readonly JsonSerializerOptions jsonSerializerOptions = new()
|
||||
{
|
||||
AllowTrailingCommas = true,
|
||||
WriteIndented = true,
|
||||
NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.AllowNamedFloatingPointLiterals,
|
||||
};
|
||||
|
||||
public static Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder<TProperty> HasJsonConversion<TProperty>(
|
||||
this Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder<TProperty> builder)
|
||||
=> HasJsonConversion(builder, jsonSerializerOptions);
|
||||
|
||||
public static Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder<TProperty> HasJsonConversion<TProperty>(
|
||||
this Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder<TProperty> builder,
|
||||
JsonSerializerOptions jsonSerializerOptions)
|
||||
{
|
||||
builder.HasConversion(
|
||||
s => JsonSerializer.Serialize(s, jsonSerializerOptions),
|
||||
s => JsonSerializer.Deserialize<TProperty>(s, jsonSerializerOptions)!);
|
||||
|
||||
ValueComparer<TProperty> valueComparer = new(
|
||||
(a, b) =>
|
||||
(a != null) && (b != null)
|
||||
? a.GetHashCode() == b.GetHashCode()
|
||||
: (a == null) && (b == null),
|
||||
i => (i == null) ? -1 : i.GetHashCode(),
|
||||
i => i);
|
||||
|
||||
builder.Metadata.SetValueComparer(valueComparer);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,46 +0,0 @@
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Model;
|
||||
|
||||
/// <summary>
|
||||
/// Часть записи, описывающая изменение
|
||||
/// </summary>
|
||||
public class ChangeLog : IChangeLog, IWithSectionPart
|
||||
{
|
||||
[Key, Comment("Ключ записи")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Comment("Дискриминатор таблицы")]
|
||||
public Guid IdDiscriminator { get; set; }
|
||||
|
||||
[Comment("Автор изменения")]
|
||||
public Guid IdAuthor { get; set; }
|
||||
|
||||
[Comment("Редактор")]
|
||||
public Guid? IdEditor { get; set; }
|
||||
|
||||
[Comment("Дата создания записи")]
|
||||
public DateTimeOffset Creation { get; set; }
|
||||
|
||||
[Comment("Дата устаревания (например при удалении)")]
|
||||
public DateTimeOffset? Obsolete { get; set; }
|
||||
|
||||
[Comment("Id заменяющей записи")]
|
||||
public Guid? IdNext { get; set; }
|
||||
|
||||
[Comment("Глубина забоя на дату начала интервала")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
[Comment("Глубина забоя на дату окончания интервала")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
[Comment("Ключ секции")]
|
||||
public Guid IdSection { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb"), Comment("Значение")]
|
||||
public required IDictionary<string, object> Value { get; set; }
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity;
|
||||
public class DataSourceSystem
|
||||
{
|
||||
[Key, Comment("Id системы - источника данных")]
|
||||
public Guid SystemId { get; set; }
|
||||
|
||||
[Required, Column(TypeName = "varchar(256)"), Comment("Наименование системы - источника данных")]
|
||||
public required string Name { get; set; }
|
||||
|
||||
[Comment("Описание системы - источника данных")]
|
||||
public string? Description { get; set; }
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
|
||||
namespace DD.Persistence.Database.Model;
|
||||
|
||||
/// <summary>
|
||||
/// Часть записи, описывающая изменение
|
||||
/// </summary>
|
||||
public interface IChangeLog
|
||||
{
|
||||
/// <summary>
|
||||
/// Ключ записи
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Автор изменения
|
||||
/// </summary>
|
||||
public Guid IdAuthor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Редактор
|
||||
/// </summary>
|
||||
public Guid? IdEditor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата создания записи
|
||||
/// </summary>
|
||||
public DateTimeOffset Creation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата устаревания (например при удалении)
|
||||
/// </summary>
|
||||
public DateTimeOffset? Obsolete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id заменяющей записи
|
||||
/// </summary>
|
||||
public Guid? IdNext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дискриминатор таблицы
|
||||
/// </summary>
|
||||
public Guid IdDiscriminator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Значение
|
||||
/// </summary>
|
||||
public IDictionary<string, object> Value { get; set; }
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity;
|
||||
|
||||
[PrimaryKey(nameof(DiscriminatorId), nameof(ParameterId), nameof(Timestamp))]
|
||||
public class ParameterData
|
||||
{
|
||||
[Required, Comment("Дискриминатор системы")]
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
|
||||
[Comment("Id параметра")]
|
||||
public int ParameterId { get; set; }
|
||||
|
||||
[Column(TypeName = "varchar(256)"), Comment("Значение параметра в виде строки")]
|
||||
public required string Value { get; set; }
|
||||
|
||||
[Comment("Временная отметка")]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Model
|
||||
{
|
||||
[PrimaryKey(nameof(Key), nameof(Created))]
|
||||
public class Setpoint
|
||||
{
|
||||
[Comment("Ключ")]
|
||||
public Guid Key { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
|
||||
public required object Value { get; set; }
|
||||
|
||||
[Comment("Дата создания уставки")]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
|
||||
[Comment("Id автора последнего изменения")]
|
||||
public Guid IdUser { get; set; }
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity
|
||||
{
|
||||
public class TechMessage
|
||||
{
|
||||
[Key, Comment("Id события")]
|
||||
public Guid EventId { get; set; }
|
||||
|
||||
[Comment("Id Категории важности")]
|
||||
public int CategoryId { get; set; }
|
||||
|
||||
[Comment("Дата возникновения")]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
|
||||
public required string Text { get; set; }
|
||||
|
||||
[Required, Comment("Id системы, к которой относится сообщение")]
|
||||
public required Guid SystemId { get; set; }
|
||||
|
||||
[Required, ForeignKey(nameof(SystemId)), Comment("Система, к которой относится сообщение")]
|
||||
public virtual required DataSourceSystem System { get; set; }
|
||||
|
||||
[Comment("Статус события")]
|
||||
public int EventState { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity;
|
||||
|
||||
[Comment("Общая таблица данных временных рядов")]
|
||||
[PrimaryKey(nameof(IdDiscriminator), nameof(Timestamp))]
|
||||
public record TimestampedSet(
|
||||
[property: Comment("Дискриминатор ссылка на тип сохраняемых данных")] Guid IdDiscriminator,
|
||||
[property: Comment("Отметка времени, строго в UTC")] DateTimeOffset Timestamp,
|
||||
[property: Column(TypeName = "jsonb"), Comment("Набор сохраняемых данных")] IDictionary<string, object> Set);
|
@ -1,42 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using DD.Persistence.Database.Model;
|
||||
|
||||
namespace DD.Persistence.Database;
|
||||
|
||||
/// <summary>
|
||||
/// EF контекст для любых БД поддерживаемых в EF
|
||||
/// </summary>
|
||||
public class PersistenceDbContext : DbContext
|
||||
{
|
||||
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
||||
|
||||
public DbSet<Setpoint> Setpoint => Set<Setpoint>();
|
||||
|
||||
public DbSet<TimestampedSet> TimestampedSets => Set<TimestampedSet>();
|
||||
|
||||
public DbSet<ChangeLog> ChangeLog => Set<ChangeLog>();
|
||||
|
||||
public DbSet<TechMessage> TechMessage => Set<TechMessage>();
|
||||
|
||||
public DbSet<ParameterData> ParameterData => Set<ParameterData>();
|
||||
|
||||
public DbSet<DataSourceSystem> DataSourceSystem => Set<DataSourceSystem>();
|
||||
|
||||
public PersistenceDbContext(DbContextOptions options)
|
||||
: base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<TimestampedSet>()
|
||||
.Property(e => e.Set)
|
||||
.HasJsonConversion();
|
||||
|
||||
modelBuilder.Entity<ChangeLog>()
|
||||
.Property(e => e.Value)
|
||||
.HasJsonConversion();
|
||||
}
|
||||
}
|
@ -1,350 +0,0 @@
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using Xunit;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Client.Clients;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Refit;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests.Controllers;
|
||||
public class ChangeLogControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private readonly IChangeLogClient client;
|
||||
private static readonly Random generatorRandomDigits = new();
|
||||
|
||||
public ChangeLogControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var refitClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<IRefitClientFactory<IRefitChangeLogClient>>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<ChangeLogClient>>();
|
||||
|
||||
client = scope.ServiceProvider
|
||||
.GetRequiredService<IChangeLogClient>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ClearAndInsertRange_InEmptyDb()
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(2);
|
||||
|
||||
// act
|
||||
var result = await client.ClearAndAddRange(idDiscriminator, dtos, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(2, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ClearAndInsertRange_InNotEmptyDb()
|
||||
{
|
||||
// arrange
|
||||
var insertedCount = 10;
|
||||
var createdResult = CreateChangeLogItems(insertedCount, (-15, 15));
|
||||
var idDiscriminator = createdResult.Item1;
|
||||
var dtos = createdResult.Item2.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>());
|
||||
|
||||
// act
|
||||
var result = await client.ClearAndAddRange(idDiscriminator, dtos, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(insertedCount * 2, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Add_returns_success()
|
||||
{
|
||||
// arrange
|
||||
var count = 1;
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(count);
|
||||
var dto = dtos.FirstOrDefault()!;
|
||||
|
||||
// act
|
||||
var result = await client.Add(idDiscriminator, dto, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(count, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddRange_returns_success()
|
||||
{
|
||||
// arrange
|
||||
var count = 3;
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(count);
|
||||
|
||||
// act
|
||||
var result = await client.AddRange(idDiscriminator, dtos, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(count, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Update_returns_success()
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
var idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(1);
|
||||
var dto = dtos.FirstOrDefault()!;
|
||||
var result = await client.Add(idDiscriminator, dto, new CancellationToken());
|
||||
|
||||
var entity = dbContext.ChangeLog
|
||||
.Where(x => x.IdDiscriminator == idDiscriminator)
|
||||
.FirstOrDefault();
|
||||
dto = entity.Adapt<DataWithWellDepthAndSectionDto>();
|
||||
dto.DepthEnd += 10;
|
||||
|
||||
// act
|
||||
result = await client.Update(dto, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(2, result);
|
||||
|
||||
var dateBegin = DateTimeOffset.UtcNow.AddDays(-1);
|
||||
var dateEnd = DateTimeOffset.UtcNow.AddDays(1);
|
||||
|
||||
var changeLogResult = await client.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, new CancellationToken());
|
||||
Assert.NotNull(changeLogResult);
|
||||
|
||||
var obsoleteDto = changeLogResult
|
||||
.Where(e => e.Obsolete.HasValue)
|
||||
.FirstOrDefault();
|
||||
|
||||
var activeDto = changeLogResult
|
||||
.Where(e => !e.Obsolete.HasValue)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (obsoleteDto == null || activeDto == null)
|
||||
{
|
||||
Assert.Fail();
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Equal(activeDto.Id, obsoleteDto.IdNext);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateRange_returns_success()
|
||||
{
|
||||
// arrange
|
||||
var count = 2;
|
||||
var dtos = Generate(count);
|
||||
var entities = dtos.Select(d => d.Adapt<ChangeLog>()).ToArray();
|
||||
dbContext.ChangeLog.AddRange(entities);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
dtos = entities.Select(c => new DataWithWellDepthAndSectionDto()
|
||||
{
|
||||
DepthEnd = c.DepthEnd + 10,
|
||||
DepthStart = c.DepthStart + 10,
|
||||
Id = c.Id,
|
||||
IdSection = c.IdSection,
|
||||
Value = c.Value
|
||||
}).ToArray();
|
||||
|
||||
// act
|
||||
var result = await client.UpdateRange(dtos, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(count * 2, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Delete_returns_success()
|
||||
{
|
||||
// arrange
|
||||
var dtos = Generate(1);
|
||||
var dto = dtos.FirstOrDefault()!;
|
||||
var entity = dto.Adapt<ChangeLog>();
|
||||
dbContext.ChangeLog.Add(entity);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
// act
|
||||
var result = await client.Delete(entity.Id, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(1, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteRange_returns_success()
|
||||
{
|
||||
// arrange
|
||||
var count = 10;
|
||||
var dtos = Generate(count);
|
||||
var entities = dtos.Select(d => d.Adapt<ChangeLog>()).ToArray();
|
||||
dbContext.ChangeLog.AddRange(entities);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
// act
|
||||
var ids = entities.Select(e => e.Id);
|
||||
var result = await client.DeleteRange(ids, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(count, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange_returns_success()
|
||||
{
|
||||
// arrange
|
||||
var changeLogItems = CreateChangeLogItems(3, (-15, 15));
|
||||
var idDiscriminator = changeLogItems.Item1;
|
||||
var entities = changeLogItems.Item2.OrderBy(e => e.Creation);
|
||||
|
||||
// act
|
||||
var result = await client.GetDatesRange(idDiscriminator, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.NotNull(result);
|
||||
|
||||
var minDate = entities.First().Creation;
|
||||
var maxDate = entities.Last().Creation;
|
||||
|
||||
var expectedMinDate = minDate.ToUniversalTime().ToString();
|
||||
var actualMinDate = result.From.ToUniversalTime().ToString();
|
||||
Assert.Equal(expectedMinDate, actualMinDate);
|
||||
|
||||
var expectedMaxDate = maxDate.ToUniversalTime().ToString();
|
||||
var actualMaxDate = result.To.ToUniversalTime().ToString();
|
||||
Assert.Equal(expectedMaxDate, actualMaxDate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetByDate_returns_success()
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
//создаем записи
|
||||
var count = 5;
|
||||
var changeLogItems = CreateChangeLogItems(count, (-15, 15));
|
||||
var idDiscriminator = changeLogItems.Item1;
|
||||
var entities = changeLogItems.Item2;
|
||||
|
||||
//удаляем все созданные записи за исключением первой и второй
|
||||
//даты 2-х оставшихся записей должны вернуться в методе GetByDate
|
||||
var ids = entities.Select(e => e.Id);
|
||||
var idsToDelete = ids.Skip(2);
|
||||
|
||||
var deletedCount = await client.DeleteRange(idsToDelete, new CancellationToken());
|
||||
|
||||
var filterRequest = new SectionPartRequest()
|
||||
{
|
||||
DepthStart = 0,
|
||||
DepthEnd = 1000,
|
||||
};
|
||||
|
||||
var paginationRequest = new PaginationRequest()
|
||||
{
|
||||
Skip = 0,
|
||||
Take = 10,
|
||||
SortSettings = String.Empty,
|
||||
};
|
||||
|
||||
var moment = DateTimeOffset.UtcNow.AddDays(16);
|
||||
var result = await client.GetByDate(idDiscriminator, moment, filterRequest, paginationRequest, new CancellationToken());
|
||||
|
||||
Assert.NotNull(result);
|
||||
|
||||
var restEntities = entities.Where(e => !idsToDelete.Contains(e.Id));
|
||||
Assert.Equal(restEntities.Count(), result.Count);
|
||||
|
||||
var actualIds = restEntities.Select(e => e.Id);
|
||||
var expectedIds = result.Items.Select(e => e.Id);
|
||||
Assert.Equivalent(expectedIds, actualIds);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(5, -15, 15, -20, 20, 10)]
|
||||
[InlineData(5, -15, -10, -16, -9, 5)]
|
||||
public async Task GetChangeLogForInterval_returns_success(
|
||||
int insertedCount,
|
||||
int daysBeforeNowChangeLog,
|
||||
int daysAfterNowChangeLog,
|
||||
int daysBeforeNowFilter,
|
||||
int daysAfterNowFilter,
|
||||
int changeLogCount)
|
||||
{
|
||||
// arrange
|
||||
dbContext.CleanupDbSet<ChangeLog>();
|
||||
|
||||
//создаем записи
|
||||
var count = insertedCount;
|
||||
var daysRange = (daysBeforeNowChangeLog, daysAfterNowChangeLog);
|
||||
var changeLogItems = CreateChangeLogItems(count, daysRange);
|
||||
var idDiscriminator = changeLogItems.Item1;
|
||||
var entities = changeLogItems.Item2;
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
entity.DepthEnd += 10;
|
||||
}
|
||||
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>()).ToArray();
|
||||
await client.UpdateRange(dtos, new CancellationToken());
|
||||
|
||||
//act
|
||||
var dateBegin = DateTimeOffset.UtcNow.AddDays(daysBeforeNowFilter);
|
||||
var dateEnd = DateTimeOffset.UtcNow.AddDays(daysAfterNowFilter);
|
||||
var result = await client.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, new CancellationToken());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(changeLogCount, result.Count());
|
||||
}
|
||||
|
||||
|
||||
private static IEnumerable<DataWithWellDepthAndSectionDto> Generate(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
yield return new DataWithWellDepthAndSectionDto()
|
||||
{
|
||||
Value = new Dictionary<string, object>()
|
||||
{
|
||||
{ "Key", 1 }
|
||||
},
|
||||
DepthStart = generatorRandomDigits.Next(1, 5),
|
||||
DepthEnd = generatorRandomDigits.Next(5, 15),
|
||||
Id = Guid.NewGuid(),
|
||||
IdSection = Guid.NewGuid()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private (Guid, ChangeLog[]) CreateChangeLogItems(int count, (int, int) daysRange)
|
||||
{
|
||||
var minDayCount = daysRange.Item1;
|
||||
var maxDayCount = daysRange.Item2;
|
||||
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
var dtos = Generate(count);
|
||||
var entities = dtos.Select(d =>
|
||||
{
|
||||
var entity = d.Adapt<ChangeLog>();
|
||||
entity.IdDiscriminator = idDiscriminator;
|
||||
entity.Creation = DateTimeOffset.UtcNow.AddDays(generatorRandomDigits.Next(minDayCount, maxDayCount));
|
||||
|
||||
return entity;
|
||||
}).ToArray();
|
||||
dbContext.ChangeLog.AddRange(entities);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
return (idDiscriminator, entities);
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using DD.Persistence.Client;
|
||||
using DD.Persistence.Client.Clients;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using DD.Persistence.Models;
|
||||
using Xunit;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests.Controllers
|
||||
{
|
||||
public class DataSourceSystemControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DataSourceSystem).FullName}CacheKey";
|
||||
private readonly IDataSourceSystemClient dataSourceSystemClient;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
public DataSourceSystemControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var refitClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<IRefitClientFactory<IRefitDataSourceSystemClient>>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<DataSourceSystemClient>>();
|
||||
|
||||
dataSourceSystemClient = scope.ServiceProvider
|
||||
.GetRequiredService<IDataSourceSystemClient>();
|
||||
memoryCache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_returns_success()
|
||||
{
|
||||
//arrange
|
||||
memoryCache.Remove(SystemCacheKey);
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
//act
|
||||
var response = await dataSourceSystemClient.Get(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
await Add();
|
||||
|
||||
//act
|
||||
var response = await dataSourceSystemClient.Get(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
|
||||
var expectedSystemCount = 1;
|
||||
var actualSystemCount = response!.Count();
|
||||
Assert.Equal(expectedSystemCount, actualSystemCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Add_returns_success()
|
||||
{
|
||||
await Add();
|
||||
}
|
||||
|
||||
private async Task Add()
|
||||
{
|
||||
//arrange
|
||||
memoryCache.Remove(SystemCacheKey);
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
var dto = new DataSourceSystemDto()
|
||||
{
|
||||
SystemId = Guid.NewGuid(),
|
||||
Name = "Test",
|
||||
Description = "Test"
|
||||
};
|
||||
|
||||
//act
|
||||
await dataSourceSystemClient.Add(dto, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,231 +0,0 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using DD.Persistence.Client;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Database.Model;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Client.Clients;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests.Controllers
|
||||
{
|
||||
public class SetpointControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private readonly ISetpointClient setpointClient;
|
||||
private class TestObject
|
||||
{
|
||||
public string? Value1 { get; set; }
|
||||
public int? Value2 { get; set; }
|
||||
}
|
||||
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var refitClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<IRefitClientFactory<IRefitSetpointClient>>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<SetpointClient>>();
|
||||
|
||||
setpointClient = scope.ServiceProvider
|
||||
.GetRequiredService<ISetpointClient>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetCurrent_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetCurrent(setpointKeys, new CancellationToken());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetCurrent_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetCurrent([setpointKey], new CancellationToken());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotEmpty(response);
|
||||
Assert.Equal(setpointKey, response.FirstOrDefault()?.Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetHistory_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
var historyMoment = DateTimeOffset.UtcNow;
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetHistory(setpointKeys, historyMoment, new CancellationToken());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetHistory_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
var historyMoment = DateTimeOffset.UtcNow;
|
||||
historyMoment = historyMoment.AddDays(1);
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetHistory([setpointKey], historyMoment, new CancellationToken());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotEmpty(response);
|
||||
Assert.Equal(setpointKey, response.FirstOrDefault()?.Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetLog_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetLog(setpointKeys, new CancellationToken());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetLog_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = await Add();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetLog([setpointKey], new CancellationToken());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotEmpty(response);
|
||||
Assert.Equal(setpointKey, response.FirstOrDefault().Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<Setpoint>();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetDatesRangeAsync(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(DateTimeOffset.MinValue, response!.From);
|
||||
Assert.Equal(DateTimeOffset.MaxValue, response!.To);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<Setpoint>();
|
||||
|
||||
await Add();
|
||||
|
||||
var dateBegin = DateTimeOffset.MinValue;
|
||||
var take = 1;
|
||||
var part = await setpointClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetDatesRangeAsync(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
|
||||
var expectedValue = part!
|
||||
.FirstOrDefault()!.Created
|
||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||
var actualValueFrom = response.From
|
||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||
Assert.Equal(expectedValue, actualValueFrom);
|
||||
|
||||
var actualValueTo = response.To
|
||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||
Assert.Equal(expectedValue, actualValueTo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 2;
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 1;
|
||||
await Add();
|
||||
|
||||
//act
|
||||
var response = await setpointClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotEmpty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Save_returns_success()
|
||||
{
|
||||
await Add();
|
||||
}
|
||||
|
||||
private async Task<Guid> Add()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = Guid.NewGuid();
|
||||
var setpointValue = new TestObject()
|
||||
{
|
||||
Value1 = "1",
|
||||
Value2 = 2
|
||||
};
|
||||
|
||||
//act
|
||||
await setpointClient.Add(setpointKey, setpointValue, new CancellationToken());
|
||||
|
||||
return setpointKey;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,283 +0,0 @@
|
||||
using DD.Persistence.Client;
|
||||
using DD.Persistence.Client.Clients;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Enumerations;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests.Controllers
|
||||
{
|
||||
public class TechMessagesControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DataSourceSystem).FullName}CacheKey";
|
||||
private readonly ITechMessagesClient techMessagesClient;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
public TechMessagesControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var refitClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<IRefitClientFactory<IRefitTechMessagesClient>>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TechMessagesClient>>();
|
||||
|
||||
techMessagesClient = scope.ServiceProvider
|
||||
.GetRequiredService<ITechMessagesClient>();
|
||||
memoryCache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPage_returns_success()
|
||||
{
|
||||
//arrange
|
||||
memoryCache.Remove(SystemCacheKey);
|
||||
dbContext.CleanupDbSet<TechMessage>();
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
var requestDto = new PaginationRequest()
|
||||
{
|
||||
Skip = 1,
|
||||
Take = 2,
|
||||
SortSettings = nameof(TechMessage.CategoryId)
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetPage(requestDto, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response.Items);
|
||||
Assert.Equal(requestDto.Skip, response.Skip);
|
||||
Assert.Equal(requestDto.Take, response.Take);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPage_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dtos = await InsertRange(Guid.NewGuid());
|
||||
var dtosCount = dtos.Count();
|
||||
var requestDto = new PaginationRequest()
|
||||
{
|
||||
Skip = 0,
|
||||
Take = 2,
|
||||
SortSettings = nameof(TechMessage.CategoryId)
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetPage(requestDto, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(dtosCount, response.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_success()
|
||||
{
|
||||
await InsertRange(Guid.NewGuid());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_BadRequest()
|
||||
{
|
||||
//arrange
|
||||
const string exceptionMessage = "Ошибка валидации, формата или маршрутизации запроса";
|
||||
var systemId = Guid.NewGuid();
|
||||
var dtos = new List<TechMessageDto>()
|
||||
{
|
||||
new TechMessageDto()
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
CategoryId = -1, // < 0
|
||||
Timestamp = DateTimeOffset.UtcNow,
|
||||
Text = string.Empty, // length < 0
|
||||
EventState = EventState.Triggered
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
//act
|
||||
var response = await techMessagesClient.AddRange(systemId, dtos, CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//assert
|
||||
Assert.Equal(exceptionMessage, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSystems_returns_success()
|
||||
{
|
||||
//arrange
|
||||
memoryCache.Remove(SystemCacheKey);
|
||||
dbContext.CleanupDbSet<TechMessage>();
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetSystems(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSystems_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
await InsertRange(Guid.NewGuid());
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetSystems(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
var expectedSystemCount = 1;
|
||||
Assert.Equal(expectedSystemCount, response!.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetStatistics_returns_success()
|
||||
{
|
||||
//arrange
|
||||
memoryCache.Remove(SystemCacheKey);
|
||||
dbContext.CleanupDbSet<TechMessage>();
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
var categoryIds = new[] { 1, 2 };
|
||||
var systemIds = new[] { Guid.NewGuid() };
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetStatistics(systemIds, categoryIds, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetStatistics_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var categoryIds = new[] { 1 };
|
||||
var systemId = Guid.NewGuid();
|
||||
var dtos = await InsertRange(systemId);
|
||||
var filteredDtos = dtos.Where(e => categoryIds.Contains(e.CategoryId));
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetStatistics([systemId], categoryIds, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotEmpty(response);
|
||||
var categories = response
|
||||
.FirstOrDefault()!.Categories
|
||||
.Count();
|
||||
Assert.Equal(filteredDtos.Count(), categories);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange_returns_NoContent()
|
||||
{
|
||||
//arrange
|
||||
memoryCache.Remove(SystemCacheKey);
|
||||
dbContext.CleanupDbSet<TechMessage>();
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetDatesRangeAsync(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Null(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
await InsertRange(Guid.NewGuid());
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetDatesRangeAsync(CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotNull(response?.From);
|
||||
Assert.NotNull(response?.To);
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
// public async Task GetPart_returns_success()
|
||||
// {
|
||||
// //arrange
|
||||
// var dateBegin = DateTimeOffset.UtcNow;
|
||||
// var take = 2;
|
||||
|
||||
// //act
|
||||
// var response = await techMessagesClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
|
||||
// //assert
|
||||
// Assert.NotNull(response);
|
||||
// Assert.Empty(response);
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 1;
|
||||
await InsertRange(Guid.NewGuid());
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.GetPart(dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotEmpty(response);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<TechMessageDto>> InsertRange(Guid systemId)
|
||||
{
|
||||
//arrange
|
||||
memoryCache.Remove(SystemCacheKey);
|
||||
dbContext.CleanupDbSet<TechMessage>();
|
||||
dbContext.CleanupDbSet<DataSourceSystem>();
|
||||
|
||||
var dtos = new List<TechMessageDto>()
|
||||
{
|
||||
new TechMessageDto()
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
CategoryId = 1,
|
||||
Timestamp = DateTimeOffset.UtcNow,
|
||||
Text = nameof(TechMessageDto.Text),
|
||||
EventState = Models.Enumerations.EventState.Triggered
|
||||
},
|
||||
new TechMessageDto()
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
CategoryId = 2,
|
||||
Timestamp = DateTimeOffset.UtcNow,
|
||||
Text = nameof(TechMessageDto.Text),
|
||||
EventState = Models.Enumerations.EventState.Triggered
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//act
|
||||
var response = await techMessagesClient.AddRange(systemId, dtos, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(dtos.Count, response);
|
||||
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using DD.Persistence.Client;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Models;
|
||||
using Xunit;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Client.Clients;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests.Controllers;
|
||||
public class TimestampedSetControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private readonly ITimestampedSetClient client;
|
||||
|
||||
public TimestampedSetControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var refitClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<IRefitClientFactory<IRefitTimestampedSetClient>>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TimestampedSetClient>>();
|
||||
|
||||
client = scope.ServiceProvider
|
||||
.GetRequiredService<ITimestampedSetClient>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(10, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
|
||||
// act
|
||||
var response = await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.Equal(testSets.Count(), response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_without_filter()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(count, response.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_with_filter_props()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
string[] props = ["A"];
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, null, props, 0, int.MaxValue, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(count, response.Count());
|
||||
foreach (var item in response)
|
||||
{
|
||||
Assert.Single(item.Set);
|
||||
var kv = item.Set.First();
|
||||
Assert.Equal("A", kv.Key);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_geDate()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
var dateMin = DateTimeOffset.Now;
|
||||
var dateMax = DateTimeOffset.Now.AddSeconds(count);
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
||||
var insertResponse = await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var tail = testSets.OrderBy(t => t.Timestamp).Skip(count / 2).Take(int.MaxValue);
|
||||
var geDate = tail.First().Timestamp;
|
||||
var tolerance = TimeSpan.FromSeconds(1);
|
||||
var expectedCount = tail.Count();
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, geDate, null, 0, int.MaxValue, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(expectedCount, response.Count());
|
||||
var minDate = response.Min(t => t.Timestamp);
|
||||
Assert.Equal(geDate, geDate, tolerance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_with_skip_take()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var expectedCount = count / 2;
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, null, null, 2, expectedCount, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(expectedCount, response.Count());
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task Get_with_big_skip_take()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
var expectedCount = 1;
|
||||
int count = 10 + expectedCount;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// act
|
||||
var response = await client.Get(idDiscriminator, null, null, count - expectedCount, count, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(expectedCount, response.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetLast()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var expectedCount = 8;
|
||||
|
||||
// act
|
||||
var response = await client.GetLast(idDiscriminator, null, expectedCount, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(expectedCount, response.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRange()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 10;
|
||||
var dateMin = DateTimeOffset.Now;
|
||||
var dateMax = DateTimeOffset.Now.AddSeconds(count - 1);
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
var tolerance = TimeSpan.FromSeconds(1);
|
||||
|
||||
// act
|
||||
var response = await client.GetDatesRange(idDiscriminator, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(dateMin, response.From, tolerance);
|
||||
Assert.Equal(dateMax, response.To, tolerance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Count()
|
||||
{
|
||||
// arrange
|
||||
Guid idDiscriminator = Guid.NewGuid();
|
||||
int count = 144;
|
||||
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
|
||||
await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
|
||||
|
||||
// act
|
||||
var response = await client.Count(idDiscriminator, new CancellationToken());
|
||||
|
||||
// assert
|
||||
Assert.Equal(count, response);
|
||||
}
|
||||
|
||||
private static IEnumerable<TimestampedSetDto> Generate(int n, DateTimeOffset from)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
yield return new TimestampedSetDto
|
||||
(
|
||||
from.AddSeconds(i),
|
||||
new Dictionary<string, object>{
|
||||
{"A", i },
|
||||
{"B", i * 1.1 },
|
||||
{"C", $"Any{i}" },
|
||||
{"D", DateTimeOffset.Now},
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,237 +0,0 @@
|
||||
using DD.Persistence.Client;
|
||||
using DD.Persistence.Client.Clients;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using DD.Persistence.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests.Controllers;
|
||||
public class WitsDataControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private IWitsDataClient witsDataClient;
|
||||
|
||||
public WitsDataControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
var refitClientFactory = scope.ServiceProvider
|
||||
.GetRequiredService<IRefitClientFactory<IRefitWitsDataClient>>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<WitsDataClient>>();
|
||||
|
||||
witsDataClient = scope.ServiceProvider
|
||||
.GetRequiredService<IWitsDataClient>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRangeAsync_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var dateBegin = DateTimeOffset.UtcNow;
|
||||
var take = 1;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
//act
|
||||
await AddRange();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetValuesForGraph_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var dateFrom = DateTimeOffset.UtcNow;
|
||||
var dateTo = DateTimeOffset.UtcNow;
|
||||
var approxPointCount = 12;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Empty(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDatesRangeAsync_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var dtos = await AddRange();
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
|
||||
var expectedDateFrom = dtos
|
||||
.Select(e => e.Timestamped)
|
||||
.Min()
|
||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||
var actualDateFrom = response.From.DateTime
|
||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||
Assert.Equal(expectedDateFrom, actualDateFrom);
|
||||
|
||||
var expectedDateTo = dtos
|
||||
.Select(e => e.Timestamped)
|
||||
.Max()
|
||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||
var actualDateTo = response.To.DateTime
|
||||
.ToString("dd.MM.yyyy-HH:mm:ss");
|
||||
Assert.Equal(expectedDateTo, actualDateTo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetPart_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var dtos = await AddRange();
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
var dateBegin = dtos.FirstOrDefault()!.Timestamped;
|
||||
var take = 1;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.NotEmpty(response);
|
||||
Assert.Equal(take, response.Count());
|
||||
|
||||
var expectedDto = dtos.FirstOrDefault();
|
||||
var actualDto = response.FirstOrDefault();
|
||||
Assert.Equal(expectedDto?.DiscriminatorId, actualDto?.DiscriminatorId);
|
||||
|
||||
var expectedValueDto = expectedDto?.Values.FirstOrDefault();
|
||||
var actualValueDto = actualDto?.Values.FirstOrDefault();
|
||||
Assert.Equal(expectedValueDto?.ItemId, actualValueDto?.ItemId);
|
||||
Assert.Equal(expectedValueDto?.RecordId, actualValueDto?.RecordId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetValuesForGraph_AfterSave_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ParameterData>();
|
||||
|
||||
var dtos = await AddRange(37);
|
||||
var discriminatorId = dtos.FirstOrDefault()!.DiscriminatorId;
|
||||
var dateFrom = dtos.Select(e => e.Timestamped).Min();
|
||||
var dateTo = dtos.Select(e => e.Timestamped).Max();
|
||||
var approxPointCount = 12;
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(approxPointCount, response.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddRange_returns_BadRequest()
|
||||
{
|
||||
//arrange
|
||||
const string exceptionMessage = "Ошибка валидации, формата или маршрутизации запроса";
|
||||
var dtos = new List<WitsDataDto>()
|
||||
{
|
||||
new WitsDataDto()
|
||||
{
|
||||
DiscriminatorId = Guid.NewGuid(),
|
||||
Timestamped = DateTimeOffset.UtcNow,
|
||||
Values = new List<WitsValueDto>()
|
||||
{
|
||||
new WitsValueDto()
|
||||
{
|
||||
RecordId = -1, // < 0
|
||||
ItemId = 101, // > 100
|
||||
Value = string.Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
//act
|
||||
var response = await witsDataClient.AddRange(dtos, CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//assert
|
||||
Assert.Equal(exceptionMessage, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<WitsDataDto>> AddRange(int countToCreate = 10)
|
||||
{
|
||||
var dtos = new List<WitsDataDto>();
|
||||
var discriminatorId = Guid.NewGuid();
|
||||
var timestamped = DateTimeOffset.UtcNow;
|
||||
for (var i = 0; i < countToCreate; i++)
|
||||
{
|
||||
var random = new Random();
|
||||
dtos.Add(new WitsDataDto()
|
||||
{
|
||||
DiscriminatorId = discriminatorId,
|
||||
Timestamped = timestamped.AddSeconds(i),
|
||||
Values = new List<WitsValueDto>()
|
||||
{
|
||||
new WitsValueDto()
|
||||
{
|
||||
RecordId = i + 1,
|
||||
ItemId = i + 1,
|
||||
Value = random.Next(1, 100)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//act
|
||||
var response = await witsDataClient.AddRange(dtos, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
var count = dtos.SelectMany(e => e.Values).Count();
|
||||
Assert.Equal(count, response);
|
||||
|
||||
return dtos;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
using DD.Persistence.Client.Helpers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Фабрика HTTP клиентов для интеграционных тестов
|
||||
/// </summary>
|
||||
public class TestHttpClientFactory : IHttpClientFactory
|
||||
{
|
||||
private readonly WebAppFactoryFixture factory;
|
||||
private readonly IConfiguration configuration;
|
||||
|
||||
public TestHttpClientFactory(WebAppFactoryFixture factory, IConfiguration configuration)
|
||||
{
|
||||
this.factory = factory;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
public HttpClient CreateClient(string name)
|
||||
{
|
||||
var client = factory.CreateClient();
|
||||
client.Authorize(configuration);
|
||||
|
||||
return client;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DD.Persistence.API;
|
||||
using DD.Persistence.Client;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Database.Postgres;
|
||||
using RestSharp;
|
||||
using DD.Persistence.App;
|
||||
using DD.Persistence.Client.Helpers;
|
||||
using DD.Persistence.Factories;
|
||||
using System.Net;
|
||||
|
||||
namespace DD.Persistence.IntegrationTests;
|
||||
public class WebAppFactoryFixture : WebApplicationFactory<Program>
|
||||
{
|
||||
private string connectionString = string.Empty;
|
||||
|
||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||
{
|
||||
builder.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config.AddJsonFile("appsettings.Tests.json");
|
||||
|
||||
var dbConnection = config.Build().GetSection("DbConnection").Get<DbConnection>()!;
|
||||
connectionString = dbConnection.GetConnectionString();
|
||||
//connectionString = "Host=postgres;Port=5442;Username=postgres;Password=postgres;Database=persistence";
|
||||
});
|
||||
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<PersistencePostgresContext>));
|
||||
if (descriptor != null)
|
||||
services.Remove(descriptor);
|
||||
|
||||
services.AddDbContext<PersistencePostgresContext>(options =>
|
||||
options.UseNpgsql(connectionString));
|
||||
|
||||
services.AddLogging(builder => builder.AddConsole());
|
||||
|
||||
services.RemoveAll<IHttpClientFactory>();
|
||||
services.AddSingleton<IHttpClientFactory>((provider) =>
|
||||
{
|
||||
return new TestHttpClientFactory(this, provider.GetRequiredService<IConfiguration>());
|
||||
});
|
||||
services.AddHttpClient();
|
||||
services.AddPersistenceClients();
|
||||
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
var scopedServices = scope.ServiceProvider;
|
||||
|
||||
var dbContext = scopedServices.GetRequiredService<PersistencePostgresContext>();
|
||||
dbContext.Database.EnsureCreatedAndMigrated();
|
||||
dbContext.SaveChanges();
|
||||
});
|
||||
}
|
||||
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
var dbContext = new PersistencePostgresContext(
|
||||
new DbContextOptionsBuilder<PersistencePostgresContext>()
|
||||
.UseNpgsql(connectionString)
|
||||
.Options);
|
||||
|
||||
await dbContext.Database.EnsureDeletedAsync();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Часть записи описывающая изменение
|
||||
/// </summary>
|
||||
public class ChangeLogDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Ключ записи
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Создатель записи
|
||||
/// </summary>
|
||||
public Guid IdAuthor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Пользователь, изменивший запись
|
||||
/// </summary>
|
||||
public Guid? IdEditor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата создания
|
||||
/// </summary>
|
||||
public DateTimeOffset Creation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата устаревания
|
||||
/// </summary>
|
||||
public DateTimeOffset? Obsolete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ключ заменившей записи
|
||||
/// </summary>
|
||||
public Guid? IdNext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Объект записи
|
||||
/// </summary>
|
||||
public DataWithWellDepthAndSectionDto Value { get; set; } = default!;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace DD.Persistence.Models.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Настройки credentials для авторизации
|
||||
/// </summary>
|
||||
public class AuthUser
|
||||
{
|
||||
public required string Username { get; set; }
|
||||
public required string Password { get; set; }
|
||||
public required string ClientId { get; set; }
|
||||
public required string GrantType { get; set; }
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Text;
|
||||
|
||||
namespace DD.Persistence.Models.Configurations
|
||||
{
|
||||
public static class JwtParams
|
||||
{
|
||||
private static readonly string KeyValue = "супер секретный ключ для шифрования";
|
||||
public static SymmetricSecurityKey SecurityKey
|
||||
{
|
||||
get { return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(KeyValue)); }
|
||||
}
|
||||
|
||||
public static readonly string Issuer = "a";
|
||||
|
||||
public static readonly string Audience = "a";
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DD.Persistence.Models.Configurations
|
||||
{
|
||||
public class JwtToken
|
||||
{
|
||||
[JsonPropertyName("access_token")]
|
||||
public required string AccessToken { get; set; }
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
using DD.Persistence.Models.Enumerations;
|
||||
|
||||
namespace DD.Persistence.Models.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Протокол Wits
|
||||
/// </summary>
|
||||
public class WitsInfo
|
||||
{
|
||||
public int RecordId { get; set; }
|
||||
|
||||
public int ItemId { get; set; }
|
||||
|
||||
public WitsType ValueType { get; set; }
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
<!--Генерация NuGet пакета при сборке-->
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<!--Наименование-->
|
||||
<Title>DD.Persistence.Models</Title>
|
||||
<!--Версия пакета-->
|
||||
<VersionPrefix>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
|
||||
<!--Версия сборки-->
|
||||
<AssemblyVersion>1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
|
||||
<!--Id пакета-->
|
||||
<PackageId>DD.Persistence.Models</PackageId>
|
||||
|
||||
<!--Автор-->
|
||||
<Authors>Digital Drilling</Authors>
|
||||
<!--Компания-->
|
||||
<Company>Digital Drilling</Company>
|
||||
<!--Описание-->
|
||||
<Description>Пакет для получения dtos для работы с Persistence сервисом</Description>
|
||||
|
||||
<!--Url репозитория-->
|
||||
<RepositoryUrl>https://git.ddrilling.ru/on.nemtina/persistence.git</RepositoryUrl>
|
||||
<!--тип репозитория-->
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<!--Символы отладки-->
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<!--Формат пакета с символами-->
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<!--Путь к пакету-->
|
||||
<PackageOutputPath>C:\Projects\Nuget\Persistence\Models</PackageOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,22 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Модель системы - источника данных
|
||||
/// </summary>
|
||||
public class DataSourceSystemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Ключ
|
||||
/// </summary>
|
||||
public Guid SystemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Наименование
|
||||
/// </summary>
|
||||
public required string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Описание
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Dto для хранения записей, содержащих начальную и конечную глубину забоя, а также секцию
|
||||
/// </summary>
|
||||
public class DataWithWellDepthAndSectionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Ключ записи
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя на дату начала интервала
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя на дату окончания интервала
|
||||
/// </summary>
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ключ секции
|
||||
/// </summary>
|
||||
public Guid IdSection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Объект записи
|
||||
/// </summary>
|
||||
public required IDictionary<string, object> Value { get; set; }
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace DD.Persistence.Models.Enumerations;
|
||||
public enum EventState
|
||||
{
|
||||
NotTriggered = 0,
|
||||
Triggered = 1,
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
namespace DD.Persistence.Models.Enumerations;
|
||||
|
||||
/// <summary>
|
||||
/// WITS Data Type Codes
|
||||
/// </summary>
|
||||
public enum WitsType
|
||||
{
|
||||
/// <summary>
|
||||
/// Alphanumeric, Rep Code = 65
|
||||
/// </summary>
|
||||
A,
|
||||
/// <summary>
|
||||
/// 32 bit 2's complement signed integer, Rep Code = 73
|
||||
/// </summary>
|
||||
L,
|
||||
/// <summary>
|
||||
/// 16 bit 2's complement signed integer, Rep Code = 79
|
||||
/// </summary>
|
||||
S,
|
||||
/// <summary>
|
||||
/// 32 bit IEEE single precision floating point, Rep Code = 128
|
||||
/// </summary>
|
||||
F,
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
public interface IWithSectionPart
|
||||
{
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
public Guid IdSection { get; set; }
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Статистика сообщений по системам бурения
|
||||
/// </summary>
|
||||
public class MessagesStatisticDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Система бурения
|
||||
/// </summary>
|
||||
public required string System { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Количество сообщений в соответствии с категориями важности
|
||||
/// </summary>
|
||||
public required Dictionary<int, int> Categories { get; set; }
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Модель параметра
|
||||
/// </summary>
|
||||
public class ParameterDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Дискриминатор системы
|
||||
/// </summary>
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id параметра
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue, ErrorMessage = "Id параметра не может быть меньше 0")]
|
||||
public int ParameterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Значение параметра в виде строки
|
||||
/// </summary>
|
||||
[StringLength(256, MinimumLength = 1, ErrorMessage = "Допустимая длина значения параметра от 1 до 256 символов")]
|
||||
public required string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Временная отметка
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
namespace DD.Persistence.Models.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Запрос для фильтрации данных по секции и глубине
|
||||
/// </summary>
|
||||
public class SectionPartRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Глубина забоя на дату начала интервала
|
||||
/// </summary>
|
||||
public double? DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя на дату окончания интервала
|
||||
/// </summary>
|
||||
public double? DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ключ секции
|
||||
/// </summary>
|
||||
public Guid? IdSection { get; set; }
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DD.Persistence.Models.Enumerations;
|
||||
|
||||
namespace DD.Persistence.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель технологического сообщения
|
||||
/// </summary>
|
||||
public class TechMessageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id события
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid EventId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id Категории важности
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue, ErrorMessage = "Id Категории важности не может быть меньше 0")]
|
||||
public int CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата возникновения
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Текст сообщения
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(512, MinimumLength = 1, ErrorMessage = "Допустимая длина текста сообщения от 1 до 512 символов")]
|
||||
public required string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Статус события
|
||||
/// </summary>
|
||||
public EventState EventState { get; set; }
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// набор данных с отметкой времени
|
||||
/// </summary>
|
||||
/// <param name="Timestamp">отметка времени</param>
|
||||
/// <param name="Set">набор данных</param>
|
||||
public record TimestampedSetDto(DateTimeOffset Timestamp, IDictionary<string, object> Set);
|
@ -1,22 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Группа параметров Wits
|
||||
/// </summary>
|
||||
public class WitsDataDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Временная отметка
|
||||
/// </summary>
|
||||
public required DateTimeOffset Timestamped { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дискриминатор системы
|
||||
/// </summary>
|
||||
public required Guid DiscriminatorId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Параметры
|
||||
/// </summary>
|
||||
public IEnumerable<WitsValueDto> Values { get; set; } = [];
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Параметр Wits
|
||||
/// </summary>
|
||||
public class WitsValueDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Wits - Record Number
|
||||
/// </summary>
|
||||
[Range(1, 100, ErrorMessage = "Значение \"Record Number\" обязано находиться в диапозоне от 1 до 100")]
|
||||
public int RecordId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Wits - Record Item
|
||||
/// </summary>
|
||||
[Range(1, 100, ErrorMessage = "Значение \"Wits Record Item\" обязано находиться в диапозоне от 1 до 100")]
|
||||
public int ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Значение параметра
|
||||
/// </summary>
|
||||
public required object Value { get; set; }
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
using Mapster;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using DD.Persistence.Repository.Repositories;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DD.Persistence.Repository;
|
||||
public static class DependencyInjection
|
||||
{
|
||||
public static void MapsterSetup()
|
||||
{
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<TechMessageDto, TechMessage>()
|
||||
.Ignore(dest => dest.System, dest => dest.SystemId);
|
||||
|
||||
TypeAdapterConfig<ChangeLog, ChangeLogDto>.NewConfig()
|
||||
.Map(dest => dest.Value, src => new DataWithWellDepthAndSectionDto()
|
||||
{
|
||||
DepthEnd = src.DepthEnd,
|
||||
DepthStart = src.DepthStart,
|
||||
IdSection = src.IdSection,
|
||||
Value = src.Value,
|
||||
Id = src.Id
|
||||
});
|
||||
}
|
||||
|
||||
public static IServiceCollection AddInfrastructure(this IServiceCollection services)
|
||||
{
|
||||
var typeAdapterConfig = TypeAdapterConfig.GlobalSettings;
|
||||
typeAdapterConfig.RuleMap.Clear();
|
||||
typeAdapterConfig.Scan(Assembly.GetExecutingAssembly());
|
||||
|
||||
MapsterSetup();
|
||||
|
||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataRepository<DataSaub, DataSaubDto>>();
|
||||
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
||||
services.AddTransient<IChangeLogRepository, ChangeLogRepository>();
|
||||
services.AddTransient<ITimestampedSetRepository, TimestampedSetRepository>();
|
||||
services.AddTransient<ITechMessagesRepository, TechMessagesRepository>();
|
||||
services.AddTransient<IParameterRepository, ParameterRepository>();
|
||||
services.AddTransient<IDataSourceSystemRepository, DataSourceSystemCachedRepository>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user